发表于: 2018-01-27 11:38:09

3 579


今天完成的事情:

1.搞昨天没弄好的telnet

  总是无法连接11211端口,让人非常的崩溃,直到碰到了一篇博客:

https://www.cnblogs.com/love540376/p/6473530.html

被这篇博客点醒了,应该是我的Memcached安装的不对,于是重新安装了Memcached,教程上面都有,按照教程一步步走下来终于能够访问11211端口了:

到了这个界面就ctrl+】

来到这个界面,再回车,来到这里:

好了。。。。可以使用这个东西了。。。真的是麻烦。

http://www.runoob.com/memcached/memcached-set-data.html

上面这个是使用教程,是memcached的常用命令,大家可以去搞一搞。

https://www.cnblogs.com/jeffwongishandsome/archive/2011/11/06/2238265.html

这篇的命令也说得非常好

至此这个东西已经安装好了。

2.接下来就是使用这个东西了:在命令行界面使用当然非常尴尬,于是我找到了这篇教程:

http://blog.csdn.net/ycyk_168/article/details/11214175

按照这个教程一步步搞下来,结果遭遇了情况:我的测试类运行全部通过,但是没有任何数据打印到控制台,这可把我急坏了,怎么搞都不行。。

然后搞了好久突然意识到一个问题,就是我没有设置任何值它怎么会输出呢?

于是我加了个值。就成功了。。。传一下代码:

项目结构,省的后面的人再彷徨浪费时间

接下来是userbean:

package com.ceshi.model;

import java.io.Serializable;

public class UserBean implements Serializable {

private static final long serialVersionUID = 9174194101246733501L;

   private String username;

   private String password;

   public UserBean(String username, String password) {
this.username = username;
       this.password = password;
   }

public String getUsername() {
return username;
   }

public void setUsername(String username) {
this.username = username;
   }

public String getPassword() {
return password;
   }

public void setPassword(String password) {
this.password = password;
   }

@Override
   public int hashCode() {
final int prime = 31;
       int result = 1;
       result = prime * result
+ ((password == null) ? 0 : password.hashCode());
       result = prime * result
+ ((username == null) ? 0 : username.hashCode());
       return result;
   }

@Override
   public boolean equals(Object obj) {
if (this == obj)
return true;
       if (obj == null)
return false;
       if (getClass() != obj.getClass())
return false;
       UserBean other = (UserBean) obj;
       if (password == null) {
if (other.password != null)
return false;
       } else if (!password.equals(other.password))
return false;
       if (username == null) {
if (other.username != null)
return false;
       } else if (!username.equals(other.username))
return false;
       return true;
   }

@Override
   public String toString() {
return "username:" + username + ",password:" + password;
   }
}

然后是工具类:

package com.ceshi;

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:11211"};
       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);
   }

}

然后是测试类:

package com.ceshi;

import com.ceshi.model.UserBean;
import org.junit.Assert;
import org.junit.Test;

public class MemcachedUtilTest {

@Test
   public void testMemcached() {
MemcachedUtil.put("hello", "world", 60);
       String hello = (String) MemcachedUtil.get("hello");
       System.out.println(hello);
       Assert.assertEquals("world", hello);

       for(int i = 0; i < 100; ++i) {
UserBean userBean = new UserBean("Jason" + i, "123456-" + i);
           MemcachedUtil.put("user" + i, userBean, 60);
           Object obj = MemcachedUtil.get("user" + i);
           System.out.println(obj);
           Assert.assertEquals(userBean, obj);
       }
}
}

  我加上了两个输出语句。

接着是pom文件:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>

 <groupId>com.ceshi</groupId>
 <artifactId>memcached</artifactId>
 <version>1.0-SNAPSHOT</version>
 <packaging>jar</packaging>

 <name>memcached</name>
 <url>http://maven.apache.org</url>

 <properties>
   <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 </properties>

 <dependencies>
   <dependency>
     <groupId>junit</groupId>
     <artifactId>junit</artifactId>
     <version>4.12</version>
   </dependency>

   <dependency>
     <groupId>com.danga</groupId>
     <artifactId>memcached</artifactId>
     <version>2.6.6</version>
   </dependency>
   <dependency>
     <groupId>org.slf4j</groupId>
     <artifactId>slf4j-simple</artifactId>
     <version>1.6.1</version>
   </dependency>
   <dependency>
     <groupId>org.slf4j</groupId>
     <artifactId>slf4j-api</artifactId>
     <version>1.6.1</version>
   </dependency>
   <dependency>
     <groupId>commons-pool</groupId>
     <artifactId>commons-pool</artifactId>
     <version>1.5.6</version>
   </dependency>
 </dependencies>
</project>

好的,就是这些东西了。

这个东西也比较简单(我的意思是代码的字面表达很清晰,不是说原理简单),一看就能理解是什么意思。

  涉及到了新的知识点:

Assert.assertEquals("world"hello);

这个是junit的断言,用来检验和报错。语法如下:

Assert.assertEquals([String message],expected,actual)

参数说明:

 message是个可选的消息,假如提供,将会在发生错误时报告这个消息。

 expected是期望值,通常都是用户指定的内容。

 actual是被测试的代码返回的实际值。

这样说很难理解,我下面举个栗子来说明一下:

可以看到,我在我的测试类里面加了一句代码,同样是hello这个键,对应的值我写了个xizi,那么运行结果:

可以看到输出的是xizi,我认为这是因为就近原则,然后继续看下面的报错,因为我们在测试类里面断言了hello对应的是world,而输出的是xizi,所以断言报错,期待的是wirld,事实是xizi。

这么一整大家应该都能明白这个断言是啥东西了吧,我认为这是一个检查的关卡。

最后,注意点

第一、memcached是在服务器端的内存中缓存对象的,不是缓存或硬盘;

第二、memcached的pool可以关联多个server,

String[] servers = {"10.20.185.12:11001","10.20.185.25:11001"};  
Integer[] weights = {3,7};  

该配置表示30%的缓存在放在第一台服务器,70%的将放在第二台服务器,这样便可以充分利用不同服务器的内存了;

第三、我最困惑的是client是如何得到相应的pool的,后然看了点源码才知道是这样的。client是通过pool的name关联到某个pool的,上面的例子中在SockIOPool pool = SockIOPool.getInstance();  和MemCachedClient client=<span new<="" span="" style="word-break: break-all;"> MemCachedClient();虽然都没写poolName,但就是新建了一个”default“的pool,然后client关联到了这个”default“的pool。当然我们在新建这两个对象时可以给定具体的poolName。

<span new<="" span="" style="word-break: break-all;">

3.然后看任务要求,有点读不太懂,分析一波:

  我的理解就是将首页(t10)的数据放到缓存中,然后从缓存中取出显示。进行压测。所以先压测一波没加缓存的:

于是设置了100线程1s启动循环2次:

可以看到吞吐量很低,而且响应时间很长。再看看TPS视图:

很低,接下来是用了缓存的:

不知道为啥用了缓存之后的页面打开要三分钟以上。。。很难受,正在致力于解决这个问题。。

目前推测是将数据放进缓存的时候出现了问题,于是将代码复原,重新加进缓存:

然后报错500:

Handler processing failed; nested exception is java.lang.VerifyError: Bad type on operand stack

去谷歌了一下,大概说是jar包的问题

然后更换了jar包,现在的报错是:

java.io.NotSerializableException

百度了一下是序列化失败,简直他妈的完美解决了我的问题

于是我加上接口,再次运行,通过我的日志,发现成功了!!!!!!!!!!!先上代码再上图:

public List<Pros> getAllPros(){
System.out.println("要进入缓存了");
   List<Pros> pross ;
   if (MemcachedUtil.get("pross")!= null){
System.out.println("这说明有缓存啊");
       pross = (List<Pros>) MemcachedUtil.get("pross");
       return pross;
   }else{
System.out.println("这说明没有缓存啊");
       pross = pageDao.getAllPros();
       MemcachedUtil.put("pross",pross,600);
       return pross;
   }

第一次登录肯定是没有缓存的,第二次就有了。哈哈哈哈,成功搞定。

  那么就在这说说从头到尾的问题吧

  一开始是请教了师兄,师兄告诉我是我的Memcached工具类有问题,于是我换了工具类,换了之后还是有问题,我百度之后更换了jar包,最后就是这个地方了,加上接口。那么完整的jar包其实只有一个,受之前教程毒害太重,浪费好多时间。在这里放一下jar:

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

就这一个足矣。之前的教程让放四个,结果各种冲突。

然后是工具类:其实知识因为jar包换了,所以引入类发生了一点变化:

import com.whalin.MemCached.MemCachedClient;
import com.whalin.MemCached.SockIOPool;

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

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

       //服务器列表及其权重
//        可以是多个服务器
       String[] servers = {"127.0.0.1:11211"};
       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);
   }
}

我做了这些之后,在项目中加入缓存就成功了,很开心。


今天遇到的问题

  上面都说到了,而且解决方法也都在上面。重点还是教程的选择,我就走了不少弯路。

今天的收获

  Memcached的使用以及将数据加入缓存和从缓存中取出;telnet的使用,以及junit的断言的知识点

 明天计划的事情

  明天继续推进任务六,估计明天要开始搞redis了


最后,辛苦我英姿伟岸,风流倜傥,貌比潘安,剑眉星目的艳行大师兄审核日报。


返回列表 返回列表
评论

    分享到