Jodis解决方案

codis的proxy层HA
对Java用户来说,可以使用经过修改过的Jedis-------Jodis,来实现proxy层的HA。它会通过监控zk上的注册信息来实时获得当前可用的proxy列表,既可以保证高可用性,也可以通过轮流请求所有的proxy实现负载均衡。

jodis的地址如下:

https://github.com/wandoulabs/codis/tree/master/extern/jodis

具体使用如下:

JedisResourcePool jedisPool = new RoundRobinJedisPool("zkserver:2181", 30000, "/zk/codis/db_xxx/proxy", new JedisPoolConfig());
try (Jedis jedis = jedisPool.getResource()) {
    jedis.set("foo", "bar");
    String value = jedis.get("foo");
}

其中部分jedis参数设置如下:

//可用连接实例的最大数目,默认值为8;
//如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
private static int MAX_ACTIVE = 10;
//控制一个pool最多有多少个状态为idle(空闲的)的jedis实例,默认值也是8。
private static int MAX_IDLE = 5;
//等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException;
private static int MAX_WAIT = 3000;
private static int TIMEOUT = 5000;

在实际运行过程中会报错,部分错误如下:
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
at redis.clients.util.Pool.getResource(Pool.java:50)
at redis.clients.jedis.JedisPool.getResource(JedisPool.java:86)
at xt.city.edi.dao.redis.RedisUtil.getJedis(RedisUtil.java:81)
at xt.city.edi.service.account.pojo.DefaultAccountManager.addUserlist(DefaultAccountManager.java:172)
……
……
Caused by: java.util.NoSuchElementException: Timeout waiting for idle object
at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:449)
at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:363)
at redis.clients.util.Pool.getResource(Pool.java:48)

正如上面提示:

我们jedis设置的连接池设置的太小,当连接池全被占用后,在“MAX_WAIT”的等待时间内,没有实例被释放,从而超时等待,导致could not get a resource from the pool。

在zookeeper的输出日志zookeeper.out也可以看到:

2015-07-24 10:15:35,247 [myid:1] - INFO [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxnFactory@197] - Accepted socket connection from /192.168.1.119:30275
2015-07-24 10:15:35,254 [myid:1] - INFO [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:ZooKeeperServer@868] - Client attempting to establish new session at /192.168.1.119:30275
2015-07-24 10:15:35,257 [myid:1] - INFO [CommitProcessor:1:ZooKeeperServer@617] - Established session 0x14e67e71be5003d with negotiated timeout 5000 for client /192.168.1.119:30275
2015-07-24 10:20:24,576 [myid:1] - WARN [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxn@357] - caught end of stream exception
EndOfStreamException: Unable to read additional data from client sessionid 0x14e67e71be5003d, likely client has closed socket
at org.apache.zookeeper.server.NIOServerCnxn.doIO(NIOServerCnxn.java:228)
at org.apache.zookeeper.server.NIOServerCnxnFactory.run(NIOServerCnxnFactory.java:208)
at java.lang.Thread.run(Thread.java:745)
2015-07-24 10:20:24,577 [myid:1] - INFO [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxn@1007] - Closed socket connection for client /192.168.1.119:30275 which had sessionid 0x14e67e71be5003d
2015-07-24 10:20:30,000 [myid:1] - INFO [SessionTracker:ZooKeeperServer@347] - Expiring session 0x14e67e71be5003d, timeout of 5000ms exceeded
2015-07-24 10:20:30,001 [myid:1] - INFO [ProcessThread(sid:1 cport:-1)::PrepRequestProcessor@494] - Processed session termination for sessionid: 0x14e67e71be5003dG

从上面红色标注处可以得出结论:

jodis客户端超时了会关闭socket,导致zookeeper刚建立的session过期释放。

解决方案:

重新设置以下参数,将连接池中的连接实例和空闲实例增大,另外适当增大超时等待时间,以保证连接实例被释放。

MAX_ACTIVE=1024

MAX_IDLE = 200

MAX_WAIT = 10000

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值