docker swarm 数据库连接被对端重置

docker swarm 数据库连接被对端重置

我正在使用 docker swarm 运行一个 spring boot 应用程序,并使用 postgres 作为数据库。当我将它们都作为 docker 服务运行时,数据库连接始终随机失败(如您在时间戳上看到的那样),如日志所示:

2017-10-26T17:14:15.200415747Z app-db.1.1ayo6h8ro1og@scw-c2964a | 日志:无法从客户端接收数据:对端重置连接

2017-10-26T17:43:36.481718562Z app-db.1.1ayo6h8ro1og@scw-c2964a | 日志:无法从客户端接收数据:对端重置连接

2017-10-26T17:43:56.954152654Z app-db.1.1ayo6h8ro1og@scw-c2964a | 日志:无法从客户端接收数据:对端重置连接

2017-10-26T17:44:17.434171472Z app-db.1.1ayo6h8ro1og@scw-c2964a | 日志:无法从客户端接收数据:对端重置连接

2017-10-26T17:49:04.154174253Z app-db.1.1ayo6h8ro1og@scw-c2964a | 日志:无法从客户端接收数据:对端重置连接

我无法理解或发现这种情况的原因。如果您能提供任何想法,我将不胜感激。

编辑:

我们意识到,在测试应用程序时,它还会抛出这样的错误:

SQLTransientConnectionException:HikariPool-1 - 连接不可用,请求在 937517 毫秒后超时

谢谢。

答案1

我在部署 Spring Boot 应用程序和 PostgreSQL 的 Docker Swarm 堆栈时遇到了同样的错误。经过大约一周的斗争,我发现问题出在防火墙由于不活动而断开容器之间的连接。快速回答,在 Linux 机器上运行以下 cmd:

sudo sysctl -w \
net.ipv4.tcp_keepalive_time=600 \
net.ipv4.tcp_keepalive_intvl=60 \
net.ipv4.tcp_keepalive_probes=3

另外,我还包含了以下 tomcat 连接池属性:

tomcat:
  max-active: 10
  initial-size: 5
  max-idle: 8
  min-idle: 5
  test-on-borrow: true
  test-while-idle: true
  test-on-return: false
  test-on-connect: true
  validation-query: SELECT 1
  validation-interval: 30000
  max-wait: 30000
  min-evictable-idle-time-millis: 60000
  time-between-eviction-runs-millis: 5000
  remove-abandoned: true
  remove-abandoned-timeout: 60

解决方案来自此博客文章:处理 ELASTICSEARCH 中的 NODENOTAVAILABLE 异常

答案2

还有另一种方法可以防止关闭空闲连接。该问题与默认的 Swarm 服务发现有关,该服务会在 15 分钟后关闭空闲连接。
明确指定dnsrr 端点模式解决问题,例如:

version: '3.3'

services:
  foo-service:
    image: example/foo-service:latest
    hostname: foo-service
    networks:
      - foo_network
    deploy:
      endpoint_mode: dnsrr
      # ...

networks:
  foo_network:
    external: true
    driver: overlay

相关内容