您的位置:首页 > 其它

单例模式在生产环境jedis集群中的应用

2017-01-12 13:51 357 查看
背景:不久前单位上线一款应用,上了生产环境之后,没过多久,便吃掉了服务器所有的内存,最后导致网站服务挂了。

在解决了这一问题之后,我发现这其实是典型的一单例模式,现分享一下。

之前存在问题的老代码如下:

这是导致问题所在的那个关键方法

public synchronized static JedisCluster getJedisCluster() {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(MAX_ACTIVE);
config.setMaxIdle(MAX_IDLE);
config.setMaxWaitMillis(MAX_WAIT);
config.setTestOnBorrow(TEST_ON_BORROW);

// 集群模式
JedisPoolConfig poolConfig = new JedisPoolConfig();
Set<HostAndPort> nodes = new HashSet<HostAndPort>();

HostAndPort hostAndPort1 = new HostAndPort("服务器地址1", 端口1);
HostAndPort hostAndPort2 = new HostAndPort("服务器地址2", 端口2);
HostAndPort hostAndPort3 = new HostAndPort("服务器地址3", 端口3);

nodes.add(hostAndPort1);
nodes.add(hostAndPort2);
nodes.add(hostAndPort3);

JedisCluster jedisCluster = new JedisCluster(nodes, poolConfig);

return jedisCluster;
}


以上这段代码是有问题的,大家看出来了吗?

问题在于,虽然方法声明为synchronized static,但是在并发多线程的情况下,并不能保证每个用户线程只生成一个JedisCluster的实例。

这样就会导致每个线程都会创建jedisCluster的实例,就会消耗内存,而且这块内存又没有被及时地释放掉,导致多用户并发以后,快速吃光了服务器的内存。

解决方法就是使用单例模式,把JedisCluster作为static的类成员,且使用懒汉单例模式,代码如下:

public class OuterClass{
...
private static JedisCluster jedisCluster = null;
...

public synchronized static JedisCluster getJedisCluster() {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(MAX_ACTIVE);
config.setMaxIdle(MAX_IDLE);
config.setMaxWaitMillis(MAX_WAIT);
config.setTestOnBorrow(TEST_ON_BORROW);

// 集群模式
JedisPoolConfig poolConfig = new JedisPoolConfig();
Set<HostAndPort> nodes = new HashSet<HostAndPort>();

HostAndPort hostAndPort1 = new HostAndPort("服务器地址1", 端口1);
HostAndPort hostAndPort2 = new HostAndPort("服务器地址2", 端口2);
HostAndPort hostAndPort3 = new HostAndPort("服务器地址3", 端口3);

nodes.add(hostAndPort1);
nodes.add(hostAndPort2);
nodes.add(hostAndPort3);

// 只有当jedisCluster为空时才实例化
if (jedisCluster == null) {
jedisCluster = new JedisCluster(nodes, poolConfig);
}

return jedisCluster;
}
}


这样就会保证即使在高并发的环境下,所有用户线程还是只会拥有一个JedisCluster的实例。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: