memcached客户端和连接池

来源:互联网 发布:事业单位网站域名 编辑:程序博客网 时间:2024/05/29 17:11
链接:


http://my.oschina.net/u/1475616/blog/330232#


前阵子在网上找了个demo学了一下memcached的简单使用.

今天回顾了一下,我想:连接池不是应该算是服务端管理的东西么,Client应该是客户端管理的东西,怎么能放在同一个class里边呢?于是把demo改了改,代码如下:

服务端:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package studyMemcached;
 
import com.danga.MemCached.SockIOPool;
 
public class MemServer {
 
    private static SockIOPool pool;
    public static void main(String[] args) {
        initPool();
         
    }
 
    private static void destroyPool() {
        SockIOPool.getInstance("SP").shutDown();
    }
 
    private static void initPool() {
        String[] addr = { "127.0.0.1:11211" };
        Integer[] weights = { 3 };
        pool = SockIOPool.getInstance("SP");
        pool.setServers(addr);
        pool.setWeights(weights);
        pool.setInitConn(4);
        pool.setMinConn(4);
        pool.setMaintSleep(30);
        pool.setMaxConn(200);
        pool.setMaxIdle(1000 30 30 6);
        pool.setMaintSleep(30);
        pool.setNagle(false);
        pool.setSocketTO(30);
        pool.setSocketConnectTO(0);
        pool.initialize();
    }
 
}

客户端:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package studyMemcached;
 
import java.util.Date;
 
import com.danga.MemCached.MemCachedClient;
 
public class PutToCache {
    public static void main(String[] args) {
        MemCachedClient client = new MemCachedClient("SP" );
         
        client.setCompressEnable(true);
        client.setCompressThreshold(1000 1024);
 
        // 将数据放入缓存
         
        client.set("test2""test2");
 
        // 将数据放入缓存,并设置失效时间
        Date date = new Date(2000000);
        client.set("test1""test1", date);
        client.add("kkk""kkkkk");
        // 删除缓存数据
        // client.delete("test1");
 
        // 获取缓存数据
        String str = (String) client.get("test1");
        String str2 = (String) client.get("test2");
        System.out.println(str);
        System.out.println(str2);
        System.out.println((String)client.get("kkk"));
    }
}

先运行服务端,发现马上程序就结束了;感觉有点儿不对劲;

然后运行客户端,果然什么也没存进去,什么也没取到;

日志里出现这样的提示:Attempting to get SockIO from uninitialized pool!

想了想,可能是连接池初始化以后又马上被销毁了;

于是把服务端改成如下这样:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package studyMemcached;
 
import java.util.Scanner;
 
import com.danga.MemCached.SockIOPool;
 
public class MemServer {
 
    private static SockIOPool pool;
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        initPool();
        while(!sc.nextLine().equals("exit")) {
             
        }
        sc.close();
        destroyPool();
    }
 
    private static void destroyPool() {
        SockIOPool.getInstance("SP").shutDown();
    }
 
    private static void initPool() {
        String[] addr = { "127.0.0.1:11211" };
        Integer[] weights = { 3 };
        pool = SockIOPool.getInstance("SP");
        pool.setServers(addr);
        pool.setWeights(weights);
        pool.setInitConn(4);
        pool.setMinConn(4);
        pool.setMaintSleep(30);
        pool.setMaxConn(200);
        pool.setMaxIdle(1000 30 30 6);
        pool.setMaintSleep(30);
        pool.setNagle(false);
        pool.setSocketTO(30);
        pool.setSocketConnectTO(0);
        pool.initialize();
    }
 
}

让服务端卡在那里等待输入,然后运行客户端,这样会不会就可以从连接池获取到连接了呢?

...

...

果然还是不行;

依然提示:Attempting to get SockIO from uninitialized pool!

难道这两部分代码一定要放在同一个类文件中么?这是什么鬼逻辑;

回头查看公司项目里memcached部分的代码,也是把连接池和创建Client实例的逻辑分开在两个类文件里的,没有任何问题;

想来想去,做了个伪分开,把Client作为服务端的一个静态变量,和线程池一起初始化,然后在另一个类里调用这个Client进行存取,这个自然是可以的;


后来又想到,公司的项目是web项目,是部署在web容器里的,会不会因为Client和线程池对象都在同一个classloader或context里,所以才可以互相找到呢?

但是这个没法验证啊,还得写一个web版的demo,太费劲了,,,

于是,写了这样一样东西:Together类,有两个field,一个Client,一个Server分别是持有缓存Client和连接池对象的独立的类;在初始化Together对象的时候,分别将client和Pool在各自的构造方法中初始化,然后在Together对象中调用Client里的缓存Client进行存取;

代码如下:

Together:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package studyMemcached;
 
public class Together {
 
    private MemC client;
    private MemS server;
 
    public Together() {
        client = new MemC();
        server = new MemS();
    }
 
    public static void main(String[] args) {
        String mistery = "xxx";
        Together t = new Together();
        t.client.set("mis", mistery);
        System.out.println(t.client.get("mis"));
 
    }
 
}

Server端:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package studyMemcached;
 
import com.danga.MemCached.SockIOPool;
 
public class MemS {
 
    private SockIOPool pool;
 
    public MemS() {
        String[] addr = { "127.0.0.1:11211" };
        Integer[] weights = { 3 };
        pool = SockIOPool.getInstance("SP");
        pool.setServers(addr);
        pool.setWeights(weights);
        pool.setInitConn(4);
        pool.setMinConn(4);
        pool.setMaintSleep(30);
        pool.setMaxConn(200);
        pool.setMaxIdle(1000 30 30 6);
        pool.setMaintSleep(30);
        pool.setNagle(false);
        pool.setSocketTO(30);
        pool.setSocketConnectTO(0);
        pool.initialize();
 
    }
 
}

Client端:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package studyMemcached;
 
import java.util.Date;
 
import com.danga.MemCached.MemCachedClient;
 
public class MemC {
    public MemCachedClient client;
 
    public MemC() {
        client = new MemCachedClient("SP");
        client.setCompressEnable(true);
        client.setCompressThreshold(64 1024);
    }
     
    public void set(String key, String value) {
        client.set(key, value, new Date(2000000));
    }
     
    public String get(String key) {
        return (String) client.get(key);
    }
}

这样一来,MemCachedClient和SockIOPool就分开了,只是在实例化的时候两个实例处在同一个classloader里;

这样调用,发现可以进行数据的存取了;

看来互相找不到是一种类似不在同一个会话环境的问题;

我在网上百度了一天,也没发现有人吧Client和Pool的初始化分开写的demo,能找到的demo总共就俩,都是写在一起的;

可能这个pool不算是服务端吧,或者Client不算是客户端;

公司的项目里是把Client作为一个单例,用的时候getInstance来取得后进行数据的保存和查找的;


0 0
原创粉丝点击