单例模式在生产环境jedis集群中的应用
背景:不久前单位上线一款应用,上了生产环境之后,没过多久,便吃掉了服务器所有的内存,最后导致网站服务挂了。
在解决了这一问题之后,我发现这其实是典型的一单例模式,现分享一下。
之前存在问题的老代码如下:
这是导致问题所在的那个关键方法
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的实例。
单例模式在生产环境jedis集群中的应用的更多相关文章
- 使用ubuntu charmed kubernetes 部署一套生产环境的集群
官方文档: https://ubuntu.com/kubernetes/docs 搭建一个基本的集群 集群ip规划 hostname ip ubuntu-1 10.0.0.10 juju-contro ...
- Storm官方文档翻译之在生产环境集群中运行Topology
在进群生产环境下运行Topology和在本地模式下运行非常相似.下面是步骤: 1.定义Topology(如果使用Java开发语言,则使用TopologyBuilder来创建) 2.使用StormSub ...
- Hadoop学习笔记—13.分布式集群中节点的动态添加与下架
开篇:在本笔记系列的第一篇中,我们介绍了如何搭建伪分布与分布模式的Hadoop集群.现在,我们来了解一下在一个Hadoop分布式集群中,如何动态(不关机且正在运行的情况下)地添加一个Hadoop节点与 ...
- 负载均衡集群中的session解决方案
前言 在我们给Web站点使用负载均衡之后,必须面临的一个重要问题就是Session的处理办法,无论是PHP.Python.Ruby还是Java,只要使用服务器保存Session,在做负载均衡时都需要考 ...
- 【分布式事务】基于RocketMQ搭建生产级消息集群?
导读 目前很多互联网公司的系统都在朝着微服务化.分布式化系统的方向在演进,这带来了很多好处,也带来了一些棘手的问题,其中最棘手的莫过于数据一致性问题了.早期我们的软件功能都在一个进程中,数据的一致性可 ...
- 负载均衡集群中的session解决方案【转】
通常面临的问题 从用户端来解释,就是当一个用户第一次访问被负载均衡代理到后端服务器A并登录后,服务器A上保留了用户的登录信息:当用户再次发送请求时, 根据负载均衡策略可能被代理到后端不同的服务器,例如 ...
- hadoop 集群中数据块的副本存放策略
HDFS采用一种称为机架感知(rack-aware)的策略来改进数据的可靠性.可用性和网络带宽的利用率.目前实现的副本存放策略只是在这个方向上的第一步.实现这个策略的短期目标是验证它在生产环境下的有效 ...
- 针对负载均衡集群中的session解决方案的总结
在日常运维工作中,当给Web站点使用负载均衡之后,必须面临的一个重要问题就是Session的处理办法,无论是PHP.Python.Ruby还是Java语言环境,只要使用服务器保存Session,在做负 ...
- 【转载】浅析从外部访问 Kubernetes 集群中应用的几种方式
一般情况下,Kubernetes 的 Cluster Network 是属于私有网络,只能在 Cluster Network 内部才能访问部署的应用.那么如何才能将 Kubernetes 集群中的应用 ...
随机推荐
- DirectX全屏游戏中弹出窗口(转)
一直有人问如何在DirectX全屏游戏中弹出窗口就象金山游侠一样.我答应过要给出原码,只是一直没有时间整理,不过现在总算是弄玩了.代码不长,大致作了些注释,但愿你能看懂:)按照我的说明一步步作应该就能 ...
- ECSHOP商城网站建设之自定义调用广告方法(二)
原文地址:http://www.cnblogs.com/zgzy/p/3598991.html 使用ecshop进行商城网站建设时,ecshop默认的很多功能对于我们个性化设计之后不太使用.今天我们主 ...
- SharePoint PowerShell 修改计时器任务
前言 最近碰到需要修改计时器任务的需求,然后搜了搜,发现有powershell命令可以搞定,记录一下. $timerJob = Get-SPTimerJob -Identity "DocID ...
- 单因素方差分析(One Way ANOVA)
Analysis of variance (ANOVA) is a collection of statistical models and their associated estimation p ...
- 【转】group_concat函数详解
转自: http://hchmsguo.iteye.com/blog/555543 问了好多人,都不知道group_concat这个函数. 这个函数好啊,能将相同的行组合起来,省老事了. MySQL中 ...
- Java调用DLL有多种方式,常用的方式有JNative、JNA、JNI等。
JNative方式调用dll JNative是一种能够使Java语言使调用DLL的一种技术,对JNI进行了封装,可能有些读者会有这样一个问题,JNative对JNI进行了封装,并且是一种跨语言的使用D ...
- Codeforces Round #258 (Div. 2)-(A,B,C,D,E)
http://blog.csdn.net/rowanhaoa/article/details/38116713 A:Game With Sticks 水题.. . 每次操作,都会拿走一个横行,一个竖行 ...
- NIO中的heap Buffer和direct Buffer区别
在Java的NIO中,我们一般采用ByteBuffer缓冲区来传输数据,一般情况下我们创建Buffer对象是通过ByteBuffer的两个静态方法: ByteBuffer.allocate(int c ...
- SharePoint _layouts下自定义程序页面权限管理
在sharepoint中,_layouts下的自定义页面没有特别的权限,只要用户能访问sharepoint站点就可以访问_layouts下的自定义程序页面,现在我们需要给自定义页面做一下权限认证.要求 ...
- 异常捕获 崩溃 Bugly ACRC 简介 总结 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...