单例模式在生产环境jedis集群中的应用
2017-01-12 13:51
357 查看
背景:不久前单位上线一款应用,上了生产环境之后,没过多久,便吃掉了服务器所有的内存,最后导致网站服务挂了。
在解决了这一问题之后,我发现这其实是典型的一单例模式,现分享一下。
之前存在问题的老代码如下:
这是导致问题所在的那个关键方法
以上这段代码是有问题的,大家看出来了吗?
问题在于,虽然方法声明为synchronized static,但是在并发多线程的情况下,并不能保证每个用户线程只生成一个JedisCluster的实例。
这样就会导致每个线程都会创建jedisCluster的实例,就会消耗内存,而且这块内存又没有被及时地释放掉,导致多用户并发以后,快速吃光了服务器的内存。
解决方法就是使用单例模式,把JedisCluster作为static的类成员,且使用懒汉单例模式,代码如下:
这样就会保证即使在高并发的环境下,所有用户线程还是只会拥有一个JedisCluster的实例。
在解决了这一问题之后,我发现这其实是典型的一单例模式,现分享一下。
之前存在问题的老代码如下:
这是导致问题所在的那个关键方法
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的实例。
相关文章推荐
- 面向生产环境的大集群模式安装Hadoop
- 生产环境部署swarm集群及 swarm-overlay-portainer(webui) 实战应用
- 5 构建Mysql+heartbeat+DRBD+LVS集群应用系统系列之生产环境下drbd裂脑处理
- 分支模式在SVN环境下的应用——代码线规则(规则模式)
- 纪念日:服务构件环境(SCE)挑起企业级架构的栋梁,下一代的应用开发模式日渐清晰
- 分支模式在SVN环境下的应用——宽松访问线(规则模式)
- 在应用环境中如何构造最优的数据库模式
- {转载}PUSH-PULL集成生产管理模式在制造执行系统中的应用
- 【APP】RabbitMQ集群环境生产实例部署 推荐
- ASP.NET Memory:如果你的应用已经在生产环境中,那为什么还要debug=true
- 在应用环境中如何构造最优的数据库模式 (1)
- awk在生产环境中高端应用
- 纪念日:服务构件环境(SCE)挑起企业级架构的栋梁,下一代的应用开发模式日渐清晰
- ASP.NET Memory:如果你的应用已经在生产环境中,那为什么还要debug=true
- Websphere6集群环境应用部署手册
- 分支模式在SVN环境下的应用——主线(结构模式)
- 纪念日:服务构件环境(SCE)挑起企业级架构的栋梁,下一代的应用开发模式日渐清晰
- ASP.NET Memory:如果你的应用已经在生产环境中,那为什么还要debug=true
- 分支模式在SVN环境下的应用——代码所有权(规则模式)
- 无线Clinet模式的应用环境