0%

javaWeb程序前端发起请求后端一直无响应

文章字数:476,阅读全文大约需要1分钟

浏览器访问java后端的页面,然后一直在转圈圈。很久了也没有反应

解决过程

  1. 首先一直转圈圈肯定是http连接没有设置超时
  2. 查看java的日志,发现没有任何日志输出。
  3. 平常即使什么都不做也会有一下定时任务偶尔输出一些信息,但是这次却异常平静
  4. 看了一下最新写的代码是获取redis信息
1
redisTemplate.getConnectionFactory().getConnection().info()
  1. 刚写的功能是定时访问这个接口获取redis信息,并且输出信息到前端。
  2. 这里从connectionFactory获取了连接,但是会不会自动释放。看了一下源代码,似乎没有释放的环节。
  3. 查看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. 于是模仿源代码的形式获取连接,然后执行,释放
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);
}
  1. 再次进行之前的操作,发现无响应的问题解决了。

分析

现在看来无响应应该就是获取redis连接的代码堵塞了,循环导致被占用的连接数越来越多,直到连接池被沾满。这也解释了为什么后台无信息输出,因为很多的线程也是依赖redis