经过:  

项目上线后经常报

Unexpected end of stream.; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Unexpected end of stream.

  白天平均半个小时报一次,晚上频率低些,但是在测试环境和预发环境就没有出现过这种问题。

  当时我们项目是从公司的另一个项目拆分出来的,所有配置和另一个环境基本一样

分析:

  JedisConnectionException: Unexpected end of stream这个异常是由于redis服务器端设置了5分钟关闭空闲连接,但是连接池还认为该链接有效,继续使用导致的结果。

  使用spring boot、spring data redis这些库,默认会开启空闲连接检测,每30秒执行一次,如果PING命令没有返回PONG,或者60秒内该连接还是空闲,就会被清理释放,一次释放一个(默认)所以正常情况下是不会出现这个异常的。

  有一种可能是,一下新建了很多连接,一分钟只释放一个,5分钟后空闲连接仍然没有释放完,这时就会报异常,因此需要调整每次释放资源个数(参数:numTestsPerEvictionRun)

  由于spring boot通过application.properties方式,只能设置max-active、max-wait、max-idle、min-idle这四个参数哈。如果要设置numTestsPerEvictionRun,需要通过代码。

解决:

  1、新增配置

spring.redis.numTestsPerEvictionRun =
spring.redis.maxActive =
spring.redis.maxIdle =
spring.redis.minIdle =

  2、新增redis配置类

@Getter
@Setter
@Component
@ConfigurationProperties(prefix = "spring.redis")
public class RedisProperties {
private String host;
private int port;
private String password;
private String maxActive;
private String maxIdle;
private String minIdle;
private String timeout;
private String numTestsPerEvictionRun;
}

  3、新增RedisConnectionFactory

@Configuration
@RequiredArgsConstructor
@Slf4j
public class RedisConfig {
@NonNull
private RedisProperties redisProperties; /**
* 连接池配置信息
* @return
*/
@Bean
public JedisPoolConfig jedisPoolConfig() {
JedisPoolConfig poolConfig=new JedisPoolConfig();
//最大连接数
poolConfig.setMaxIdle(Integer.parseInt(redisProperties.getMaxIdle()));
//最小空闲连接数
poolConfig.setMinIdle(Integer.parseInt(redisProperties.getMinIdle()));
/*poolConfig.setTestOnBorrow(true);
poolConfig.setTestOnReturn(true);
poolConfig.setTestWhileIdle(true);*/
poolConfig.setNumTestsPerEvictionRun(Integer.parseInt(redisProperties.getNumTestsPerEvictionRun()));
//poolConfig.setTimeBetweenEvictionRunsMillis(60000);
//当池内没有可用的连接时,最大等待时间
//poolConfig.setMaxWaitMillis(10000);
//------其他属性根据需要自行添加-------------
return poolConfig;
}
/**
* jedis连接工厂
* @param jedisPoolConfig
* @return
*/
@Bean
public RedisConnectionFactory redisConnectionFactory(JedisPoolConfig jedisPoolConfig) {
//单机版jedis
RedisStandaloneConfiguration redisStandaloneConfiguration =
new RedisStandaloneConfiguration();
//设置redis服务器的host或者ip地址
redisStandaloneConfiguration.setHostName(redisProperties.getHost());
//设置密码
redisStandaloneConfiguration.setPassword(RedisPassword.of(redisProperties.getPassword()));
//设置redis的服务的端口号
redisStandaloneConfiguration.setPort(redisProperties.getPort());
//获得默认的连接池构造器(怎么设计的,为什么不抽象出单独类,供用户使用呢)
JedisClientConfiguration.JedisPoolingClientConfigurationBuilder jpcb =
(JedisClientConfiguration.JedisPoolingClientConfigurationBuilder)JedisClientConfiguration.builder().usePooling();
//指定jedisPoolConifig来修改默认的连接池构造器(真麻烦,滥用设计模式!)
jpcb.poolConfig(jedisPoolConfig); //通过构造器来构造jedis客户端配置
JedisClientConfiguration jedisClientConfiguration = jpcb.build();
//单机配置 + 客户端配置 = jedis连接工厂
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(redisStandaloneConfiguration, jedisClientConfiguration);
return jedisConnectionFactory;
} }

后记:

其实中间出现了一个小插曲,就是第一个改完,没有加红色部分代码(usePooling()),虽然报错频率有了很大改善,但是仍然会有报错出现,最后发现是没有开启redis连接池导致,后面加了开启连接池(usePooling())后,经过一天的观察,没有再出现过该错误现象。

  记录一下没有开启连接池和开启连接池时stringRedisTemplate的参数(忽略截图中maxTotal等参数,上面说的50是线上的配置,截图是本地的测试结果,本地配置的8)

开启连接池后:

最新文章

  1. ITTC数据挖掘平台介绍(五) 数据导入导出向导和报告生成
  2. 基于SSM的租赁管理系统0.2_20161225_开发环境
  3. Y86模拟器安装
  4. 禅道Linux一键安装版
  5. c#读取INI文件类
  6. nginx fastcgi 超时问题解决记录
  7. 网络IPC:套接字之寻址
  8. 对.Net WebSocket 和Socket的原理的思考
  9. java新手笔记17 参数
  10. Java反射及依赖注入简单模拟
  11. BZOJ 2761 不重复数字 (Hash)
  12. Swift1_关闭
  13. 推荐 iOS 网站:
  14. make执行过程
  15. 离职了,在家温故而知新----1 设计模式 & 开头
  16. 对python编程的初步理解
  17. [DeeplearningAI笔记]ML strategy_2_3迁移学习/多任务学习
  18. 线程UI同步
  19. vue-cli利用router创建单页面
  20. C#线程同步--线程通信

热门文章

  1. .net remoting(一)
  2. Rocket - tilelink - HintHandler
  3. 概念辨析-Hardware Description还是Hardware Developing?
  4. Java实现 LeetCode 445 两数相加 II
  5. Java实现 蓝桥杯VIP 算法训练 黑白无常
  6. Java实现 LeetCode 179 最大数
  7. Java实现 LeetCode 56 合并区间
  8. 第三届蓝桥杯C++B组国(决)赛真题
  9. java实现高斯日记
  10. PAT 科学计数法