背景:

一个中小型H5游戏

核心错误信息:

  (1): java.lang.ClassCastException: [B cannot be cast to java.lang.Long

  at redis.clients.jedis.Connection.getIntegerReply(Connection.java:201)
  at redis.clients.jedis.Jedis.del(Jedis.java:129) 

 

  (2):redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketException: Socket closed

  at redis.clients.jedis.Protocol.process(Protocol.java:131)
  at redis.clients.jedis.Protocol.read(Protocol.java:187)
  at redis.clients.jedis.Connection.getIntegerReply(Connection.java:201)
  at redis.clients.jedis.Jedis.del(Jedis.java:129)

贴上核心问题代码(Jedis工具类):

/**
* 获取连接池.
*
* @return 连接池实例
*/
private static JedisPool getPool() {
String key = ip + ":" + port;
JedisPool pool = null;
//这里为了提供大多数情况下线程池Map里面已经有对应ip的线程池直接返回,提高效率
if (maps.containsKey(key)) {
pool = maps.get(key);
return pool;
}
//这里的同步代码块防止多个线程同时产生多个相同的ip线程池
synchronized (JedisUtil.class) {
if (!maps.containsKey(key)) {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(maxTotal);
config.setMaxIdle(maxIdle);
config.setTestOnBorrow(true);
config.setTestOnReturn(true);
config.setMaxWaitMillis(maxWaitMillis);
config.setBlockWhenExhausted(blockWhenExhausted);
try {
if (password != null && !"".equals(password)) {
pool = new JedisPool(config, ip, port, timeout, password);
} else {
pool = new JedisPool(config, ip, port, timeout);
}
maps.put(key, pool);
} catch (Exception e) {
e.printStackTrace();
}
} else {
pool = maps.get(key);
}
}
return pool;
} /**
* 获取Redis实例.
*
* @return Redis工具类实例
*/
public Jedis getJedis() {
Jedis jedis = null;
int count = 0;
while (jedis == null && count < retryNum) {
try {
JedisPool pool = getPool();
jedis = pool.getResource();
} catch (Exception e) {
logger.error("get redis master failed!", e);
} finally {
closeJedis(jedis);
}
count++;
}
return jedis;
} /**
* 释放redis实例到连接池.
*
* @param jedis redis实例
*/
public void closeJedis(Jedis jedis) {
if (jedis != null) {
getPool().returnResource(jedis);
}
}

  

问题剖析:

  查阅了线上资料,发现是由于多线程使用了同一个Jedis实例导致的并发问题.

结果:

  一开始,我发现我调用了getJedis()获取了jedis实例并使用后没有关闭.

  于是我把关闭Jedis的操作加上去了

  结果是错误的量少了

  但还是有报错,说明这是其中一个问题.

  最后还是没能使用Jedis连接池搞定这个问题

解决办法:

  抛弃使用连接池

  每次使用Jedis都生成一个独立的实例

  每次用完以后就close()

  这样也就不存在并发的问题了

  这样做有一个潜在的问题是如果并发量达到很大值,Redis连接数被塞满的话还是会出现问题.

  一般情况下不是非常大的并发,用完就close的话,没那么容易到这个瓶颈

相关代码:

    /**
* 获取一个独立的Jedis实例
* @return jedis
*/
public Jedis getSingleJedis() {
Jedis jedis = new Jedis(ip, port, timeout);
jedis.connect();
if (StringUtils.isNotBlank(password)) {
jedis.auth(password);
}
return jedis;
}   // 关闭Jedis直接调用 jedis.close() 即可

  

Java中多线程服务中遇到的Redis并发问题?的更多相关文章

  1. WIN7中组件服务中的DCOM配置找不到Microsoft Excel应用程序的解决办法

    转自:http://blog.csdn.net/lploveme/article/details/8215265 在运行栏中输入命令:dcomcnfg,打开组件服务管理窗口,但是却发现找不到Micro ...

  2. GDAL库中WFS服务中含有中文不能获取数据的问题

    GDAL库中目前提供了对WFS服务发布的数据进行获取,目前发现对于中文的服务名称或者图层名为中文,GDAL不能正确识别.通过调试发现,其原因有下面两点: 1.输入的URL路径没有使用UTF8编码而从网 ...

  3. geoserver中WMS服务详细说明

    官方geoserver中WMS服务中几种操作的API的详细说明地址: http://docs.geoserver.org/stable/en/user/services/wms/reference.h ...

  4. Java中多线程并发体系知识点汇总

    一.多线程 1.操作系统有两个容易混淆的概念,进程和线程. 进程:一个计算机程序的运行实例,包含了需要执行的指令:有自己的独立地址空间,包含程序内容和数据:不同进程的地址空间是互相隔离的:进程拥有各种 ...

  5. 2.1多线程(java学习笔记) java中多线程的实现(附静态代理模式)

    一.多线程 首先我们要清楚程序.进程.线程的关系. 首先进程从属于程序,线程从属于进程. 程序指计算机执行操作或任务的指令集合,是一个静态的概念. 但我们实际运行程序时,并发程序因为相互制约,具有“执 ...

  6. Java 在spring cloud中使用Redis,spring boot同样适用

    1.本地安装redis服务,官网下载. 2.在开发中要使用redis,首先要启动本地redis服务,启动后页面如下: 3.在spring boot项目pom.xml文件中添加Redis需要的依赖包,可 ...

  7. 庐山真面目之十三微服务架构中如何在Docker上使用Redis缓存

    一.介绍     1.开始说明 在微服务器架构中,有一个组件是不能少的,那就是缓存组件.其实来说,缓存组件,这个叫法不是完全正确,因为除了缓存功能,它还能完成其他很多功能.我就不隐瞒了,今天我们要探讨 ...

  8. 利用Java Service Wrapper将java项目添加到windows服务中

    1.web项目,即tomcat/resin添加至window系统服务,步骤如下:第一步:找到tomcat的bin目录,如:D:\apache-tomcat-8.0.26\bin第二步:打开cmd,cd ...

  9. Java程序员面试中的多线程问题

    很多核心Java面试题来源于多线程(Multi-Threading)和集合框架(Collections Framework),理解核心线程概念时,娴熟的实际经验是必需的.这篇文章收集了Java线程方面 ...

随机推荐

  1. pc端前端和手機端區別

    1.pc端寬度比較固定,手機端可以橫屏或者豎屏: 2.pc端不需要處理手機觸摸,而手機端需要: 3.pc端不需要處理鍵盤事件: 3.pc的瀏覽器內核很多,手機端基本上是webkit或者是基於webki ...

  2. Lodop、c-lodop注册与角色简短问答

    注册与角色:参考http://www.c-lodop.com/demolist/t1.html参考链接里的三种场景,是哪种角色.客户端访问网站后用自己的打印机打印.是客户端本地打印角色.IP和域名注册 ...

  3. 用Pytorch训练线性回归模型

    假定我们要拟合的线性方程是:\(y=2x+1\) \(x\):[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] \(y\):[1, 3, 5, 7, ...

  4. vsftp配置文件详解

    匿名用户相关参数 anonymous_enable=YES # 是否允许匿名用户登陆 no_anon_password=NO # 是否忽略对匿名用户的密码检测 anon_root # 匿名登陆后尝试更 ...

  5. pgsql 并行相关配置

  6. 交互题[CF1103B Game with modulo、CF1019B The hat、CF896B Ithea Plays With Chtholly]

    交互题就是程序与电脑代码的交互. 比如没有主函数的程序,而spj则给你一段主函,就变成了一个整体函数. 还有一种就是程序和spj之间有互动,这个用到fflush(stdout);这个函数就可以实现交互 ...

  7. 看毛片就能AC算法

    KMP && ACA KMP: 吼哇! 反正网上教程满天飞,我就不写了. 发个自己写的模板 /** freopen("in.in", "r", ...

  8. tarjan模板

    tarjan #include <cstdio> #include <cstdlib> #include <cmath> #include <cstring& ...

  9. IDEA 破解

    推荐三篇文章  : 1:    https://blog.csdn.net/nishiwodebocai21/article/details/71359619?fps=1&locationNu ...

  10. The 19th Zhejiang University Programming Contest Sponsored by TuSimple (Mirror) B"Even Number Theory"(找规律???)

    传送门 题意: 给出了三个新定义: E-prime : ∀ num ∈ E,不存在两个偶数a,b,使得 num=a*b;(简言之,num的一对因子不能全为偶数) E-prime factorizati ...