参考:http://my.oschina.net/xdhua/blog/221086
BEFORE:
之前使用的单实例的JedisPool没有这个问题;JedisPool的connected_clients 一般不会超过80;
AFTER:
扩展后6个实例,每个实例可以达到10K,从80徒增到60w;
STEP 0. Jedis使用的是apache common-pool 的 BasePoolableObjectFactory管理对象。
1
2
3
4
5
6
7
|
public
interface
PooledObjectFactory<T> {
PooledObject<T> makeObject();
void
activateObject(PooledObject<T> obj);
void
passivateObject(PooledObject<T> obj);
boolean
validateObject(PooledObject<T> obj);
void
destroyObject(PooledObject<T> obj);
}
|
STEP 1. 代码跟踪的时候,发现一直不断的创建对象,没有使用池中的对象;Redis 服务器接收到很多PING;connected_clients没有降低;
STEP 2.发现进入destroyObject后,没有处理过jedis.disconnect(),定位 (obj instanceof ShardedJedis) == false。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public
void
destroyObject(
final
Object obj)
throws
Exception {
if
((obj !=
null
) && (obj
instanceof
ShardedJedis)) {
ShardedJedis shardedJedis = (ShardedJedis) obj;
for
(Jedis jedis : shardedJedis.getAllShards()) {
try
{
try
{
jedis.quit();
}
catch
(Exception e) {
}
jedis.disconnect();
}
catch
(Exception e) {
}
}
}
}
|
STEP 3. redis.clients.util.Pool中的
1
|
public
void
returnResourceObject(
final
Object resource){}
//为什么是Object,不使用泛型~~~
|
总结:
ShardedJedis在使用完后要将整个ShardedJedis对象放回池中。
but:发布前在本地压测10个线程,每个线程循环10000次,居然没有压出异常,还是不够仔细!