Rails部署k8偶发PostgreSQL发送到后端I/O错误异常排查咨询
报错诱因与排查方向
该错误本质是应用到数据库的TCP连接已经失效,尝试读写时触发I/O异常,除了连接超时外,常见诱因和对应排查方向如下:
- 网络中间节点断连:K8集群与生产数据库之间的防火墙、负载均衡、NAT网关等设备,通常会默认清理空闲超过阈值的TCP连接(多数云厂商默认阈值为300秒),如果应用连接池的空闲连接存活时间超过该阈值,再次调用就会触发报错。优先排查链路中所有网络设备的空闲超时规则。
- 数据库侧主动断连:PostgreSQL的
idle_in_transaction_session_timeout、tcp_keepalives_idle等参数如果配置值小于应用端连接空闲保留时间,数据库会主动断开闲置过久的连接。可对接DBA核对生产库的相关超时参数。 - K8容器网络异常:检查K8集群CNI插件是否存在偶发丢包、K8节点TCP参数
tcp_retries2是否配置过低,短时间网络波动就会判定连接失效。 - 应用连接池配置缺陷:ActiveRecord未开启死连接回收机制,导致已经失效的连接没有被及时清理,被业务逻辑调用时触发报错。可先检查
database.yml中是否配置了reaping_frequency、idle_timeout参数。
gem适配方案
不需要自定义修改activerecord-jdbcpostgresql-adapter的源码,按以下优先级处理即可:
- 先将该gem升级到61.x分支的最新补丁版本,该版本已经内置了基础的连接失效检测逻辑,无需自行适配。
- 调整ActiveRecord连接池配置,在
database.yml中增加以下参数,确保连接回收时间小于链路中所有节点的最小空闲超时值:
reaping_frequency: 10 # 每10秒检测清理一次死连接 idle_timeout: 120 # 空闲超过120秒的连接自动回收
- 必要时可在业务逻辑外层增加异常重试逻辑,捕获
ActiveRecord::JDBCError且异常信息包含An I/O error occurred while sending to the backend时,调用ActiveRecord::Base.connection.reconnect!后重试操作即可。
内容的提问来源于stack exchange,提问作者Peabrain
相关产品推荐
相关产品推荐

