Docker Compose部署的REST服务与Keycloak闲置后请求超时问题
问题分析与解决方案
核心问题定位
错误显示连接host.docker.internal:8085超时,结合Docker Compose默认网络部署的场景,核心原因有两个:
- 错误的服务寻址逻辑:你在REST应用中配置的Keycloak地址是
host.docker.internal,但同一Compose默认网络内的服务,应当使用容器服务名(即Compose文件中Keycloak的服务名称)互相访问。host.docker.internal指向宿主机,闲置后宿主机端口映射可能出现网络波动或连接回收问题,导致首次调用超时。 - HTTP客户端连接池失效:你的Resteasy客户端使用的连接池在闲置过久后,连接被Keycloak或Docker网络层主动关闭,但客户端未检测到连接失效,首次调用时尝试使用失效连接触发超时;后续调用会自动重建新连接,因此恢复正常。
具体修复步骤
1. 修正Keycloak服务地址配置
将REST应用中Keycloak的访问地址,从host.docker.internal:8085改为Docker Compose里Keycloak的服务名称+容器内部端口(默认8080)。例如:
# 原错误配置 keycloak.url=http://host.docker.internal:8085/auth # 修改后的正确配置(假设Keycloak服务名是keycloak) keycloak.url=http://keycloak:8080/auth
同一Docker网络内通过服务名直接寻址,可规避宿主机端口映射的网络不稳定问题。
2. 配置HTTP客户端连接池失效检测
针对Resteasy客户端,添加连接池存活检测逻辑,确保闲置连接失效时自动重建:
// 构建带连接池配置的Resteasy客户端 ApacheHttpClient4Engine engine = new ApacheHttpClient4Engine(); PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(); // 设置闲置连接验证时长(30秒),使用前自动检查连接有效性 connectionManager.setValidateAfterInactivity(30000); // 配置连接池容量 connectionManager.setMaxTotal(200); connectionManager.setDefaultMaxPerRoute(20); HttpClient httpClient = HttpClientBuilder.create() .setConnectionManager(connectionManager) .build(); engine.setHttpClient(httpClient); ResteasyClient client = new ResteasyClientBuilder() .httpEngine(engine) .build();
如果使用Spring Boot等框架,也可通过配置文件直接设置连接池参数,实现相同效果。
3. 可选:优化Keycloak的连接保留配置
在Docker Compose中给Keycloak添加相关环境变量,避免快速回收闲置连接:
services: keycloak: image: quay.io/keycloak/keycloak:latest environment: - KC_HEALTH_ENABLED=true - KC_HTTP_ENABLED=true - KC_HTTP_CONNECTION_TIMEOUT=30000 - KC_HTTP_SOCKET_TIMEOUT=60000 ports: - "8085:8080"
注:环境变量需根据Keycloak版本调整,新版本以KC_为前缀。
验证方法
修改配置后重启服务,闲置超过设置的连接闲置时长后再次调用API,检查是否仍出现连接超时错误。
内容的提问来源于stack exchange,提问作者Jags
相关产品推荐
相关产品推荐

