发表于: 2017-10-24 16:02:13

3 836


今日完成:


  学习Memcache缓存的概念.

简单一点讲,实际执行效果就是当我们需要去操作数据库时,


  if(在缓存空间中找不到该数据,那么就去数据库中找){

        if(在数据库中也找不到){

           直接返回并提示没有该值

        }else{

           在数据中找到了数据!;

           在返回结果时,一并把数据放入缓存

        }

  }else{

    直接在缓存中找到数据,直接返回.避免了对数据的操作从而缩短响应时间!

  }



但是关于具体操作流程,需要安装软件引进jar包都是一头雾水,一步步来先!

安装memcached for Windows

操作流程如下

http://blog.csdn.net/zhaotengfei36520/article/details/41315329

http://blog.csdn.net/l1028386804/article/details/61417166

启动成功

参数介绍

     -p 监听的端口 

    -l 连接的IP地址, 默认是本机 

   -d start 启动memcached服务 

   -d restart 重起memcached服务 

   -d stop|shutdown 关闭正在运行的memcached服务 

   -d install 安装memcached服务 

   -d uninstall 卸载memcached服务 

   -u 以的身份运行 (仅在以root运行的时候有效) 

   -m 最大内存使用,单位MB。默认64MB 

   -M 内存耗尽时返回错误,而不是删除项 

   -c 最大同时连接数,默认是1024 

   -f 块大小增长因子,默认是1.25 

   -n 最小分配空间,key+value+flags默认是48 

   -h 显示帮助



这里就改了一下端口,重启服务


使用Telnet可以很直观的使用Memcache,本地启动telnet方法.

https://jingyan.baidu.com/article/ae97a646b22fb6bbfd461d19.html


这边在启动telnet时可能报错,打开telnet属性的依赖关系页面,看看哪些服务没开手动开一下


启动后使用在CMD界面输入Telnet "你本地的IP地址,当然也可以输入远程的IP地址" 11210(memcached端口号,上面我手动设置成了11210)

回车后进入空白页面按下ctrl+],再按一次回车,就可以看见memcached缓存的内容了,当然我这里是空的...


使用命令对缓存空间进行操作

https://jingyan.baidu.com/article/f79b7cb310b6079144023e8f.html

做了个简单的测试!


在这里我们可以把memcached当作当初学习数据库一样,数据库的存储内容是在我们的硬盘内,而memcached存储的内容就在我们当前的内存中!

在cmd命令进入程序使用telnet操作之后,就好比当初使用mysql指令进入数据库操作一样,但当时怎么通过JAVA程序去操作数据库的呢?JDBC? 

OK!没错!那么相似的使用JAVA程序操作memcahed就得使用类似于JDBC的工具了!

JAVA使用MemcacheUtil工具 !    像当初一样memcached要依赖jar包,手动下载后手动添加maven库,教程如下

http://www.cnblogs.com/mycifeng/p/5882509.html


创建核心工具类,现成的轮子,操作核心对象MemCachedClient,配置核心对象SockIOPool!

package cn.ssm.test;

import com.danga.MemCached.MemCachedClient;
import com.danga.MemCached.SockIOPool;

public class MemcachedUtil {

/**
    * memcached客户端单例
    */
   private static MemCachedClient cachedClient = new MemCachedClient();

/**
    * 初始化连接池
    */
   static {
//获取连接池的实例
       SockIOPool pool = SockIOPool.getInstance();

//服务器列表及其权重
       String[] servers = {"127.0.0.1:11210"};
Integer[] weights = {3};

//设置服务器信息
       pool.setServers(servers);
pool.setWeights(weights);

//设置初始连接数、最小连接数、最大连接数、最大处理时间
       pool.setInitConn(10);
pool.setMinConn(10);
pool.setMaxConn(1000);
pool.setMaxIdle(1000*60*60);

//设置连接池守护线程的睡眠时间
       pool.setMaintSleep(60);

//设置TCP参数,连接超时
       pool.setNagle(false);
pool.setSocketTO(60);
pool.setSocketConnectTO(0);

//初始化并启动连接池
       pool.initialize();

//压缩设置,超过指定大小的都压缩
//      cachedClient.setCompressEnable(true);
//      cachedClient.setCompressThreshold(1024*1024);
   }

private MemcachedUtil(){
}

public static boolean add(String key, Object value) {
return cachedClient.add(key, value);
}

public static boolean add(String key, Object value, Integer expire) {
return cachedClient.add(key, value, expire);
}

public static boolean put(String key, Object value) {
return cachedClient.set(key, value);
}

public static boolean put(String key, Object value, Integer expire) {
return cachedClient.set(key, value, expire);
}

public static boolean replace(String key, Object value) {
return cachedClient.replace(key, value);
}

public static boolean replace(String key, Object value, Integer expire) {
return cachedClient.replace(key, value, expire);
}

public static Object get(String key) {
return cachedClient.get(key);
}

}

一个简单测试!

再用telnet测试


OK,但是这里仅仅能存放普通对象类型,而我需要的对student类进行存取,且我们还有令人愉快的春天框架,怎么把工具和spring整合呢?


首先!想要将实体类对象进行存放进缓存或拿取,就得对我们的实体类进行序列化!

测试


但是什么是序列化,为什么一般要在实现序列化的同时重写 hashcode、equals 方法.

http://blog.csdn.net/tengdazhang770960436/article/details/53436334  纯干货文章!


1.序列化是干什么的?

简单的来说就是为了保存各个对象在内存中的状态(也就是实例的变量,不是方法),并且可以把保存的对象状态读出来。虽然你可以用你自己的各种各样的方法来保存 object states,但是java给你提供一种应该比你自己好的保存对象状态的机制,那就是序列化。


2.什么情况下需要序列化

 1. 当你想把内存中的对象状态保存到一个文件或者是数据中的时候;

 2. 当你想用 socket 在网络中传输对象的时候;

 3. 当你想通过 RMI 传输对象的时候;



3.为什么序列化对象通常要重写 hashCode 和 equals方法

2个内容完全一样的对象,在我们“人”看来就是一样的对象,但是计算机不这么认为,为了保证对象在进行比较时候符合人们的思维习惯,所以我们需要重写这2个方法。

在向 set 这种集合中添加对象的时候,set 要求对象都是不重复的,这个检查重复的过程,首先是检查对象的 hashCode() 值,如果这个值一致的话再去通过 equals 方法进行比较,如果 equals方法返回true,那么这个对象就不会被加入到 set 当中。



Spring 大法好!  将我们的memcached注入!

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans  
  5.            http://www.springframework.org/schema/beans/spring-beans.xsd">  
  6.   
  7.     <bean id="memcachedPool" class="com.danga.MemCached.SockIOPool"   
  8.         factory-method="getInstance" init-method="initialize">  
  9.         <constructor-arg>  
  10.             <value>neeaMemcachedPool</value>  
  11.         </constructor-arg>  
  12.         <property name="servers">  
  13.             <list>  
  14.                 <value>127.0.0.1:11210</value>  
  15.             </list>  
  16.         </property>  
  17.         <property name="initConn">  
  18.             <value>20</value>  
  19.         </property>  
  20.         <property name="minConn">  
  21.             <value>10</value>  
  22.         </property>  
  23.         <property name="maxConn">  
  24.             <value>50</value>  
  25.         </property>  
  26.         <property name="nagle">  
  27.             <value>false</value>  
  28.         </property>  
  29.         <property name="socketTO">  
  30.             <value>3000</value>  
  31.         </property>  
  32.     </bean>  
  33.     <bean id="memcachedClient" class="com.danga.MemCached.MemCachedClient">  
  34.         <constructor-arg>  
  35.             <value>neeaMemcachedPool</value>  
  36.         </constructor-arg>  
  37.     </bean>  
  38. </beans>  


测试


OK基本已经可以操作了!


可以开始步骤2,这里因为我们在压测的时候使用jmeter访问的请求方式和数据是固定的,不是动态的.那么第一访问后,后续的请求方式全部一样就会导致后续拿值全是从缓存空间里去拿,并不能实现更加真实有效的使用memcacahe的效果

为了实现这种效果,采用志荣师兄给的测试方式!我们在service层 手动去定义一个计数值count,每访问一次自增1,每当该值达到能被3整除的时候,手动对缓存空间进行清空,这样来达到一个模拟的效果!


service层代码修改如下



手动测试结果

符合之前定下的逻辑标准,删除控制台打印开始压测!   线程属性如下:并发量40,手动测试1分钟访问效果!



报告如下: 使用memcached缓存,压测JSP!





报告如下: 使用memcached缓存,压测JSP!


在service层添加大量判断的情况下使用缓存  90%line 比不使用缓存还快了近100毫秒!!!


开始压测JSNO接口,这里就要涉及到通过spring mvc返回json数据的知识点了!

这里使用简单的注解方式!

①将返回的值使用 @ResponseBody  注解标识

②引入相关jar依赖

  <dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.0</version>
</dependency>


③在spring mvc配置中开启<mvc:annotation-driven /> 会自动注册

DefaultAnnotationHandlerMapping

AnnotationMethodHandlerAdapter 

两个bean,这两个bean是spring MVC为@Controllers分发请求所必须的。并提供了数据绑定支持,@NumberFormatannotation支持,@DateTimeFormat支持,@Valid支持,读写XML的支持(JAXB),读写JSON的支持(Jackson)。

 


测试结果


开始压测,线程属性如下:并发量40,手动测试1分钟访问效果!


报告如下: 使用memcached缓存,压测JSON!


报告如下: 使用memcached缓存,压测JSON!


这里的说下权重这个概念,这里memcached和接下来的nginx都有这个属性weights,看过前面的师兄日报,谈到配置多个memcached服务器时如分配{4,6}表示40%缓存放第一台,60%缓存放第二台.


这里我持保留态度,我认为memcached权重和nginx的权重概念基本一致,即在访问memcached服务器时优先选择权重较高的服务器,从里面查询如查询不到结果,在访问数据后把内容放到该服务器.随着时间增加,权重较高memcached服务器因访问优先,其缓存里的内容肯定多于权重较低的memcached服务器,根据被访问的次数来看,两者缓存内容大小的比例会无限接近于两者所分配的权重比例!


这里开始用nginx.因为之前在Linux已经使用过了,这里一个是因为待会儿要压测服务器估计扛不住,二是也试下在win7里配置nginx使用多个服务器实现负载均衡!


..................实在搞不动了....休息了


明日计划: 瞄了眼验收标准,要理解的概念还很多.


问题:很多,坑踩了不少了今天


收获: 对memcache有了初步的了解..



返回列表 返回列表
评论

    分享到