发表于: 2017-06-30 21:59:46

1 1185


今日完成:

项目添加memcache

压测JSP


明日计划:

  • 部署两台WEB,使用Nginx的Upstream来做负载。重新压测。
  • 将Memcache替换成Redis,重复以步骤。最后生成一份压测报告,同样的发布到自媒体里。


收获:

添加memcache步骤:

1.检查memcache客户端是否开启

在终端输入:lsof -i :11211  可以看到memcache进程。

如果没有进程在终端输入启动memcache命令:

memcached -d -p 11211 -u nobody -c 1024 -m 64

2.检查配置文件是否加载,缺少。

memcache需要的配置文件:

①memcache.properties、

#设置服务器地址
memcached.server=127.0.0.1:11211
#设置初始连接数
memcached.initConn=20
#设置最小连接数
memcached.minConn=10
#设置最大连接数
memcached.maxConn=50
#设置连接池维护线程的睡眠时间
memcached.maintSleep=3000
#设置是否使用Nagle算法(Socket的参数),如果是true在写数据时
memcached.nagle=false
#设置socket的读取等待超时时间
memcached.socketTO=100

②spring-mvc.xml下添加如下配置

<!--7.配置memcache-->
<bean id="memcachedPool" class="com.whalin.MemCached.SockIOPool"
     factory-method="getInstance" init-method="initialize" destroy-method="shutDown">
   <constructor-arg>
       <value>memCachedPool</value>
   </constructor-arg>

   <property name="servers">
       <list>
           <value>${memcached.server}</value>
       </list>
   </property>

   <property name="initConn">
       <value>${memcached.initConn}</value>
   </property>

   <property name="minConn">
       <value>${memcached.minConn}</value>
   </property>

   <property name="maxConn">
       <value>${memcached.maxConn}</value>
   </property>

   <property name="maintSleep">
       <value>${memcached.maintSleep}</value>
   </property>

   <property name="nagle">
       <value>${memcached.nagle}</value>
   </property>

   <property name="socketTO">
       <value>${memcached.socketTO}</value>
   </property>
</bean>
<bean id="memCachedClient" class="com.whalin.MemCached.MemCachedClient">
   <constructor-arg>
       <value>memCachedPool</value>
   </constructor-arg>
</bean>

然后引入memcache.properties文件

<context:property-placeholder location="classpath:properties/*"/>

上面是加载properties文件夹下所有配置文件

③添加jar包、com.danga的依赖总是加载失败,这里我用的是com.whalin依赖、

<dependency>
 <groupId>com.whalin</groupId>
 <artifactId>memcached-Java-Client</artifactId>
 <version>3.0.2</version>
</dependency>

④web.xml、加载spring-mvc.xml配置文件。

⑤创建MemcachedUtils工具

package com.ptteng.login.util;

import com.whalin.MemCached.MemCachedClient;

import java.util.Date;

/**
* Created by shun on 2017/6/30.
*/
public class MemcachedUtils {
private static MemCachedClient cachedClient;

   static {
if (cachedClient == null) {
cachedClient new MemCachedClient("memCachedPool");
       }
}

private MemcachedUtils() {
}

public static boolean set(String keyObject value) {
return setExp(keyvalue, null);
   }

public static boolean set(String keyObject valueDate expire) {
return setExp(keyvalueexpire);
   }

public static boolean setExp(String keyObject valueDate expire) {
boolean flag = false;
       try {
flag = cachedClient.set(keyvalueexpire);
       catch (Exception e) {

}
return flag;
   }

public static boolean add(String keyObject value) {
return addExp(keyvalue, null);
   }

public static boolean add(String keyObject valueDate expire) {

return addExp(keyvalueexpire);
   }

public static boolean addExp(String keyObject valueDate expire) {
boolean flag = false;
       try {
flag = cachedClient.add(keyvalueexpire);
       catch (Exception e) {

}
return flag;
   }

public static boolean replace(String keyObject value) {
return replaceExp(keyvalue, null);
   }

/**
    * 仅当键已经存在时,replace命令才会替换缓存中的键
    *
    * @param key
    @param value
    @param expire 过期时间 New Date(1000*10):十秒过期
    * @return
    */
   public static boolean replace(String keyObject valueDate expire) {
return replaceExp(keyvalueexpire);
   }

/**
    * 仅当键已经存在时,replace命令才会替换缓存中的键
    *
    * @param key
    @param value
    @param expire 过期时间 New Date(1000*10):十秒过期
    * @return
    */
   public static boolean replaceExp(String keyObject valueDate expire) {
boolean flag = false;
       try {
flag = cachedClient.replace(keyvalueexpire);
       catch (Exception e) {

}
return flag;
   }

/**
    * get 命令用于检索与之前添加的键值对相关的值
    *
    * @param key
    @return
    */
   public static Object get(String key) {
Object obj = null;
       try {
obj = cachedClient.get(key);
       catch (Exception e) {

}
return obj;
   }

/**
    * 删除 memcached中的任何现有值。
    *
    * @param key
    @param expire
    @return
    */
   public static boolean delete(String keyDate expire) {
return deleteExp(keyexpire);
   }

/**
    * 删除memcached中的任何现有值
    *
    * @param key
    @param expire
    @return
    */
   private static boolean deleteExp(String keyDate expire) {
boolean flag = false;
       try {
flag = cachedClient.delete(keyexpire);
       catch (Exception e) {

}
return flag;
   }

/**
    * 清理缓存中的所有键-值对
    *
    * @return
    */
   public static boolean flushAll() {
boolean flag = false;
       try {
flag = cachedClient.flushAll();
       catch (Exception e) {

}
return flag;
   }
}

在service实现类中添加方法

@Service
public class excellence_stuServiceImpl implements excellence_stuService {
@Autowired
   private excellence_stuDao excellence_stuDao;
   public List<excellence_stu> getAll() {
List<excellence_stu>list;
       if (MemcachedUtils.get("list") != null) {
list = (List<excellence_stu>) MemcachedUtils.get("list");
           System.err.println("本次操作是从缓存中查询数据!");
           return list;
       }
list = excellence_stuDao.getAll();
       boolean flag = MemcachedUtils.add("list"list);
       System.err.println("本次操作是从数据库中查询数据,并向缓存中添加数据,添加结果为:"+flag);
       return list;
   }
}

⑥最关键的地方序列化实体类,没有这个,数据不能添加到缓存。在实体类方法名实现Serializable类

public class excellence_stu implements Serializable {

下面是操作成功示例


什么是序列化?

序列化:就是把一个对象用二进制的表示出来,这样才能把对象写入到输出流中,用来存储或传输类似说我第一个字节表示什么属性名词,第二个字节表示什么属性值,第几个字段表示有几个属性等的意思;

对应到项目中就是说,user这个bean实现了序列化之后,才能保存在memcached缓存中,

拓展:什么是反序列化?

反序列化:就是通过序列化后的字段还原成这个对象本身。但标识不被序列化的字段是不会被还原的。

如一般人员的密码信息等属性需要标识不被序列化。防止网络传输被窃取,特别是web程序


junit测试

在spring中添加测试方法需要在类名上加上这个两个

@RunWith(SpringJUnit4ClassRunner.class)  //使用junit4进行测试
@ContextConfiguration({"classpath:spring/spring-mvc.xml"}) //加载配置文件


压测JSP

未添加缓存:直接卡在这不动了

添加缓存后:效果非常明显,但是cpu率占用特别高



问题:

一.clean

在IDEA里修改配置文件路径后,有时候不会自动加载,比如jdbc.properties这些。这时需要先clean一下,路径就加载成功了。最近经常用到这个操作,删除类后也需要clean一遍。

二.序列化

一下午就解决这个bug了,配置文件,jar包,添加缓存方法等都没问题,但是数据就是存不到缓存里,经志荣大佬指点,发现是没有实体类没有序列化的原因。

三、无法访问页面

发现一个奇怪的问题 经过多次尝试发现,启动memcaceh缓存后,只能访问一个controller类里的页面,访问第二个controller类会报错。关掉memcaceh进程后两个都可以正常访问。

重启memcache进程,访问list页面后再访问home页面就会出错

HTTP ERROR 500

Problem accessing /home. Reason:

    Server Error


Caused by:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.apache.tiles.request.render.CannotRenderException: ServletException including path '/WEB-INF/layout/template.jsp'.

at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:982)

at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)


重启memcache进程,访问home页面后再访问list页面就会出错

HTTP ERROR 500

Problem accessing /list. Reason:

    Server Error


Caused by:

org.apache.jasper.JasperException: An exception occurred processing JSP page /WEB-INF/Student/list.jsp at line 68


65:     <c:forEach items="${list}" var="l">

66:         <tr>

67:             <td>${l.id }</td>

68:             <td>${l.stu_name }</td>

69:             <td>${l.sign}</td>

70:             <td>${l.stu_school}</td>

71:             <td>${l.stu_introducer}</td>



Stacktrace:

at org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:568)

at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:470)

at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:403)

at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:347)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)

at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:751)

at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:566)

at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)

at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:596)





返回列表 返回列表
评论

    分享到