文章字数:476,阅读全文大约需要1分钟
浏览器访问java
后端的页面,然后一直在转圈圈。很久了也没有反应
解决过程
首先一直转圈圈肯定是http
连接没有设置超时
查看java
的日志,发现没有任何日志输出。
平常即使什么都不做也会有一下定时任务偶尔输出一些信息,但是这次却异常平静
看了一下最新写的代码是获取redis
信息
1 redisTemplate.getConnectionFactory().getConnection().info()
刚写的功能是定时访问这个接口获取redis
信息,并且输出信息到前端。
这里从connectionFactory
获取了连接,但是会不会自动释放。看了一下源代码,似乎没有释放的环节。
查看redisTemplate
代码,看看执行其他命令的时候是怎么获取到连接的
execute
方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 public <T> T execute (RedisCallback<T> action, boolean exposeConnection, boolean pipeline) { Assert.isTrue(this .initialized, "template not initialized; call afterPropertiesSet() before using it" ); Assert.notNull(action, "Callback object must not be null" ); RedisConnectionFactory factory = this .getConnectionFactory(); RedisConnection conn = null ; Object var11; try { if (this .enableTransactionSupport) { conn = RedisConnectionUtils.bindConnection(factory, this .enableTransactionSupport); } else { conn = RedisConnectionUtils.getConnection(factory); } boolean existingConnection = TransactionSynchronizationManager.hasResource(factory); RedisConnection connToUse = this .preProcessConnection(conn, existingConnection); boolean pipelineStatus = connToUse.isPipelined(); if (pipeline && !pipelineStatus) { connToUse.openPipeline(); } RedisConnection connToExpose = exposeConnection ? connToUse : this .createRedisConnectionProxy(connToUse); T result = action.doInRedis(connToExpose); if (pipeline && !pipelineStatus) { connToUse.closePipeline(); } var11 = this .postProcessResult(result, connToUse, existingConnection); } finally { RedisConnectionUtils.releaseConnection(conn, factory); } return var11; }
RedisConnectionUtils.getConnection(factory);
的内部实现也是getConnectionFactory().getConnection()
,所以可以知道确是没有自动释放,需要手动释放一下
于是模仿源代码的形式获取连接,然后执行,释放
1 2 3 4 5 6 7 8 RedisConnectionFactory factory = redisTemplate.getConnectionFactory(); RedisConnection conn = null ; try { conn = RedisConnectionUtils.getConnection(factory); redisInfo = conn.info(); } finally { RedisConnectionUtils.releaseConnection(conn, factory); }
再次进行之前的操作,发现无响应的问题解决了。
分析 现在看来无响应应该就是获取redis
连接的代码堵塞了,循环导致被占用的连接数越来越多,直到连接池被沾满。这也解释了为什么后台无信息输出,因为很多的线程也是依赖redis