[学习积累]memcached客户端和连接池

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

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

服务端:

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();
    }

}

客户端:

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!

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

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

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:

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端:

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端:

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来取得后进行数据的保存和查找的;

虽然问题算是解决了,但还是比较迷糊;

希望有懂的大神帮忙指点指点;

时间: 2025-01-19 20:59:43

[学习积累]memcached客户端和连接池的相关文章

Java进阶学习第十八天——事物与连接池

文档版本 开发工具 测试平台 工程名字 日期 作者 备注 V1.0 2016.05.13 lutianfei none 事务 事务的概念 事务就是一个事情,组成这个事情可能有多个单元,要求这些单元,要么全都成功,要么全都不成功. 在开发中,有事务的存在,可以保证数据完整性. 例如:A--B转帐,对应于如下两条sql语句 update account set money=money-100 where name='a'; update account set money=money+100 whe

HttpClient 4.3连接池参数配置及源码解读

目前所在公司使用HttpClient 4.3.3版本发送Rest请求,调用接口.最近出现了调用查询接口服务慢的生产问题,在排查整个调用链可能存在的问题时(从客户端发起Http请求->ESB->服务端处理请求,查询数据并返回),发现原本的HttpClient连接池中的一些参数配置可能存在问题,如defaultMaxPerRoute.一些timeout时间的设置等,虽不能确定是由于此连接池导致接口查询慢,但确实存在可优化的地方,故花时间做一些研究.本文主要涉及HttpClient连接池.请求的参数

[转载] 基于zookeeper、连接池、Failover/LoadBalance等改造Thrift 服务化

转载自http://blog.csdn.net/zhu_tianwei/article/details/44115667 http://blog.csdn.net/column/details/slimina-thrift.html 对于Thrift服务化的改造,主要是客户端,可以从如下几个方面进行: 1.服务端的服务注册,客户端自动发现,无需手工修改配置,这里我们使用zookeeper,但由于zookeeper本身提供的客户端使用较为复杂,因此采用curator-recipes工具类进行处理服

SQLSERVER连接池内部机制

前言介绍: 当应用程序运行的时候,会有一个连接池的管理控件运行在应用程序的进程里,统一管理应用程序和SQLSERVER建立的所有连接, 并且维护这些连接一直处于活动状态.当有用户发出一个connection open指令时连接池会在自己维护的连接池中找一个处于空闲状态 的连接放回自己管理的连接池里,给这个用户使用.当用户使用完毕后,发出connection close指令,连接池会把这个连接放回自己 管理的连接池里,让他重新处于空闲状态,而不是真的从SQL里登出.这样如果下次有用户需要相同连接,

基于zookeeper、连接池、Failover/LoadBalance等改造Thrift 服务化

对于Thrift服务化的改造,主要是客户端,可以从如下几个方面进行: 1.服务端的服务注册,客户端自动发现,无需手工修改配置,这里我们使用zookeeper,但由于zookeeper本身提供的客户端使用较为复杂,因此采用curator-recipes工具类进行处理服务的注册与发现. 2.客户端使用连接池对服务调用进行管理,提升性能,这里我们使用Apache Commons项目commons-pool,可以大大减少代码的复杂度. 3.关于Failover/LoadBalance,由于zookeep

支持并发的http客户端(基于tcp连接池以及netty)

闲来无事,将以前自己写的一个库放出来吧.. 有的时候会有这样子的需求: (1)服务器A通过HTTP协议来访问服务器B (2)服务器A可能会并发的像B发送很多HTTP请求 类似于上述的需求,可能并不常见...因为在业务中确实遇到了这样子的场景,所以就自己动手开发了一个库... 实现原理: (1)底层IO通过netty搞 (2)维护一个tcp的长连接池,这样子就不用每次发送请求还要建立一个tcp连接了... 下面直接来看怎么用吧: (1)最常规的用法,向www.baidu.com发送100次get请

libmemcached支持连接池访问memcached

#include <stdio.h> #include <libmemcached/memcached.h> #include <libmemcached/util.h> #include <assert.h> //g++ -m32 -g memcached_test.c -o memcached_test -I/usr/lib/libmemcached/include -L/usr/lib/libmemcached/lib -lmemcached -lme

Java基础学习笔记二十七 DBUtils和连接池

DBUtils 如果只使用JDBC进行开发,我们会发现冗余代码过多,为了简化JDBC开发,本案例我们讲采用apache commons组件一个成员:DBUtils.DBUtils就是JDBC的简化开发工具包.需要项目导入commons-dbutils-1.6.jar才能够正常使用DBUtils工具. DBUtils是java编程中的数据库操作实用工具,小巧简单实用. DBUtils封装了对JDBC的操作,简化了JDBC操作,可以少写代码. Dbutils三个核心功能介绍 QueryRunner中

使用连接池访问memcached(libmemcached)的完整例子

#include <stdio.h> #include <libmemcached/memcached.h> #include <libmemcached/util.h> #include <assert.h> //g++ -m32 -g memcached_test.c -o memcached_test -I/usr/lib/libmemcached/include -L/usr/lib/libmemcached/lib  -lmemcached  -l