DigitalOcean上Node.js+PostgreSQL随机出现ECONNREFUSED问题求助
排查Node.js+PostgreSQL随机ECONNREFUSED及内存异常问题
一、优先排查连接资源耗尽问题
随机出现的ECONNREFUSED,在PostgreSQL服务活跃、端口正常监听的前提下,最可能是连接数打满导致的:
- 实时查看当前PostgreSQL连接数:
对比SELECT count(*) FROM pg_stat_activity;/etc/postgresql/14/main/postgresql.conf里的max_connections值(默认100),如果数值接近或达到上限,直接说明连接资源耗尽。 - 检查Node.js应用的连接池配置:
用pg模块的话,确保连接被正确释放(client.release()),同时合理设置池大小,避免超过PostgreSQL的连接上限:const pool = new Pool({ // 其他配置... max: 20, // 根据服务器内存调整,建议不超过PostgreSQL max_connections的1/3 idleTimeoutMillis: 30000, // 闲置连接自动回收 });
二、处理日志中的恶意/无效连接
日志里的"不支持的前端协议"、不存在的角色(cms、admin)、连接重置,是恶意扫描或无效请求在消耗连接资源:
- 收紧PostgreSQL的连接来源限制:
修改/etc/postgresql/14/main/pg_hba.conf,只允许本地应用和必要的管理IP连接,不要开放给所有IP:
修改后重启服务:# 本地应用连接(仅允许127.0.0.1) host your_db_name your_db_user 127.0.0.1/32 scram-sha-256 # 仅允许特定外部IP管理(如果需要) host all postgres x.x.x.x/32 scram-sha-256sudo systemctl restart postgresql - 启用连接超时与限制:
在postgresql.conf中添加以下配置,自动清理闲置连接并限制单IP并发:tcp_keepalives_idle = 60 tcp_keepalives_interval = 10 tcp_keepalives_count = 5 max_connections_per_ip = 5
三、定位内存异常根源
数据库不大但内存占用高,通常和连接数或配置不合理有关:
- 调整PostgreSQL内存参数:
如果Droplet内存较小(比如1GB),降低shared_buffers和work_mem,避免内存被过度占用:shared_buffers = 256MB # 1GB内存的Droplet建议值,默认是内存的1/4 work_mem = 4MB # 单个查询的工作内存,防止小内存服务器被大查询拖垮 - 监控进程内存:
用htop或pm2 monit分别查看PostgreSQL和Node.js应用的内存变化:- 如果是PostgreSQL内存持续上涨,结合连接数看是否是无效连接未释放;
- 如果是Node.js应用内存异常,排查代码是否存在内存泄漏(比如未关闭的定时器、全局变量堆积)。
四、模拟并发验证问题
- 用
ab工具模拟并发请求,触发问题场景:
同时实时查看PostgreSQL连接数和系统内存,定位问题触发的临界点。ab -n 1000 -c 20 http://your-domain.com/ - 开启详细日志定位根源:
修改postgresql.conf开启连接日志,记录所有连接细节:
重启服务后,通过日志追踪导致连接耗尽的具体请求来源。log_connections = on log_disconnections = on log_statement = 'all'
内容的提问来源于stack exchange,提问作者junior_ali
相关产品推荐
相关产品推荐

