验证代码如下:
JedisPoolConfig config = new JedisPoolConfig(); config.setNumTestsPerEvictionRun(3); config.setTimeBetweenEvictionRunsMillis(Duration.ofMinutes(5).toMillis()); config.setMinIdle(5); config.setMaxTotal(20); config.setTestOnBorrow(false); config.setTestWhileIdle(true); JedisPool pool = new JedisPool(config, "x.x.x.x", 6379, 5000, "123456", 0); List<Integer> connectionNumbers = Stream.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9).collect(Collectors.toList()); // 从池中获取10个连接后并一起关闭 connectionNumbers.stream().map(i -> pool.getResource()).collect(Collectors.toList()) .forEach(Jedis::close); System.out.println(String.format("active: %d", pool.getNumActive())); System.out.println(String.format("idle: %d", pool.getNumIdle())); // 等待5分钟 + 5秒钟(避免刚好卡在5分钟时间点) Thread.sleep(Duration.ofMinutes(5).toMillis() + 5000); System.out.println(LocalDateTime.now()); System.out.println(String.format("active: %d", pool.getNumActive())); System.out.println(String.format("idle: %d", pool.getNumIdle())); // 从Pool中取出10个连接,来进行redis操作 connectionNumbers.stream() .map(i -> pool.getResource()) .collect(Collectors.toList()) .forEach(resource -> { try { resource.get("key"); } catch (Exception e) { e.printStackTrace(); } });结果如下:
确实发生了5次 Unexpected end of stream 异常。 写在最后
Jedis的连接池基于Apache Common中的连接池,大多数java中的连接池都是基于Apache。
所以该问题同样适用于常见的JDBC连接池。
可以发现,TCP协议"一厢情愿"总会出问题,更多时候得"你知我知"才能正常的使用。
TCP协议是真的很复杂的一个通信协议,不单单是三次握手4次挥手这么简单的内容。