开发者社区> master_haku> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

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

简介: 背景:不久前单位上线一款应用,上了生产环境之后,没过多久,便吃掉了服务器所有的内存,最后导致网站服务挂了。   在解决了这一问题之后,我发现这其实是典型的一单例模式,现分享一下。 之前存在问题的老代码如下: 这是导致问题所在的那个关键方法 public synchronized sta...
+关注继续查看

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

 

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

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

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

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的实例。

 

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
闯祸了,生产环境执行了DDL操作《死磕MySQL系列 十四》(2)
闯祸了,生产环境执行了DDL操作《死磕MySQL系列 十四》
32 0
阿大:“我们将在 D2 首次对外披露阿里前端在安全生产建设上的思考和成果”
如果你的前端团队已经具备一定规模,并且正在高质量研发和高效业务迭代之间矛盾苦恼,那么我相信在这个安全生产专题一定能让你有所收获。
3306 0
阿里巴巴NACOS(3)- 部署Nacos的生产集群环境
上一篇文章介绍了如何在Spring Cloud中使用Nacos,让我感觉是无缝支持Spring Cloud,可惜的是阿里云的MSE暂时只支持Nacos的服务注册和发现,配置中心还是需要用阿里云的ACM来完成,本文将介绍如何部署Nacos的生产集群环境。
10193 0
使用 React.js 的渐进式 Web 应用程序:第 4 部分 - 渐进增强
本文讲的是使用 React.js 的渐进式 Web 应用程序:第 4 部分 - 渐进增强,一个比较完善的 Web 应用要对它所面对的市场的大部分用户是可用的。如此,如果一个 Web 应用遵循弹性开发的理念,那么它可以避免用户在第一次进入应用时遭受好几秒的白屏而非正常要展示的内容的情况:
1496 0
使用 Kubernetes 和 OpenStack-Salt ,打造生产环境可用的 OpenStack (上)
本文讲的是使用 Kubernetes 和 OpenStack-Salt ,打造生产环境可用的 OpenStack (上)【编者的话】本教程介绍和解释了如何使用 Docker 容器和 Kubernetes 构建一个配备 OpenContrail SDN 的企业 OpenStack 私有云,包括它的生命周期管理和运维。
2078 0
生产环境中的容器之工作流
本文讲的是生产环境中的容器之工作流,【编者的话】很多公司已经在生产环境里大规模使用容器。前一篇文章里介绍了Spotify,DramaFever,Built.io和IIIEPE如何以及为什么使用容器。本文继续深入讨论这几个公司的工作流。
1760 0
+关注
master_haku
Master HaKu
502
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载