ruby-on-rails - 乘客使用的 PostgreSQL 连接比预期的要多
问题描述
生产中长期发生的难题,我们不知道它来自哪里。有时可以在 localhost 上重现它,Heroku Enterprise 支持对此一无所知。
在我们的生产数据库中,我们目前有以下设置:
- 乘客独立,线程禁用,最多 25 个进程。没有最低设置。
- 3个网络测功机
aSELECT * FROM pg_stat_activity GROUP BY client_addr
并计算每个实例的连接数表明在我们的高峰期为一个乘客进程打开了超过 1 个 PSQL 连接。
假设:
- 一个地址大约是一个 Dyno(由 Heroku 工作人员确认)
- 乘客当时产生的进程不超过 25 个(
passenger-status
在这些高峰期确认)
这是看起来的屏幕截图SELECT * FROM pg_stat_activity;
:
在屏幕截图中,我们可以看到有45 个 psql 连接来自运行乘客的同一台测功机。如果我们按照之前的逻辑,每个Passenger进程的连接不应该超过1个,所以25个。
日志看起来并不异常,没有提到测功机崩溃/进程崩溃。
这是我们对同一个测功机的乘客状态的屏幕截图(不同的时间,只是为了证明为一个测功机创建的进程不超过 25 个):
最后是我们从 Heroku 支持中得到的回应之一(Amazing support btw)
我还看到过有关乘客使用比预期更多的连接的先前报告,但不幸的是,大多数由于难以复制而被关闭。
在乘客文档中,解释了乘客自己处理 ActiveRecord 连接。
任何线索表示赞赏。谢谢!
各种资料:
- 红宝石版本:
2.4.x
- 导轨版本:
5.1.x
- 乘客版:
5.3.x
- PG版:
10.x
- 活动记录版本:
5.1.x
如果您需要更多信息,请在评论中告诉我,我会很乐意更新这篇文章。
最后一件事:我们使用 ActionCable。我在某处读到乘客正在奇怪地处理套接字连接(打开一个有点隐藏的过程以保持连接处于活动状态)。这是我们的线索之一,但到目前为止,在 localhost 上复制它还没有运气。如果有人可以确认乘客如何处理 ActionCable 连接,将不胜感激。
更新 1(2018 年 1 月 10 日):
实验:
- 禁用 NewRelic 自动解释功能,如下所述:https ://devcenter.heroku.com/articles/forked-pg-connections#disabling-new-relic-explain
- 在本地运行一个乘客服务器,将最小和最大池大小设置为 3(更多会使我的计算机烧毁),然后使用各种信号(SIGKILL、SIGTERM)终止进程以尝试查看连接是否正确关闭。他们是。
解决方案
我们终于设法解决了关于乘客的问题。实际上,我们已经有这个问题很长时间了。
修复
如果您使用 ActionCable,并且您的默认电缆路线是/cable
,则将 Procfile 更改为:
web: bundle exec passenger start -p $PORT --max-pool-size $PASSENGER_MAX_POOL_SIZE
至
web: bundle exec passenger start -p $PORT --max-pool-size $PASSENGER_MAX_POOL_SIZE --unlimited-concurrency-path /cable
解释
在更改之前,每个套接字连接 (ActionCable) 将在Passenger 中占用一个进程。但是一个 Socket 实际上是不应该占用整个过程的东西。一个进程可以处理许多打开的套接字连接。(对于一些大牌来说,很多同时超过一万)。幸运的是,我们的套接字连接要少得多,但仍然如此。
改完之后,我们基本上告诉Passenger不要用一整个进程来处理一个socket连接,而是专门用一个进程来处理所有的socket连接。
文档
- 关于如何使用乘客进行套接字的深入文档:https ://www.phusionpassenger.com/library/config/standalone/tuning_sse_and_websockets/
- 传递给乘客的标志:https ://www.phusionpassenger.com/library/config/standalone/reference/#--unlimited-concurrency-path-unlimited_concurrency_paths
修复 3 周后的一些指标
- 乘客上的分叉进程数量显着减少(从 75 个进程到约 15 个进程)
- Web dynos 上的全局内存使用量急剧下降(与前一点关于分叉的乘客进程有关)
- PSQL 连接的全球数量急剧下降,并且已经稳定了两天(即使在部署之后)。(从 150 到 ~30 个连接)
- 每个测功机的 PSQL 连接数显着减少(从每个测功机约 50 个到每个测功机不到 10 个)
- Redis 连接数减少,并且已经稳定了两天(即使在部署之后)
- PostgreSQL 上的平均内存使用量急剧下降,并且已经稳定了两天。
- 整体吞吐量比平时高一点(吞吐量是每分钟处理的请求数)
推荐阅读
- javascript - 在 javascript 中使用 echo'd ++$value 作为 html5 音频播放器页面的一部分时出现问题
- mysql - 通过编写脚本在 mysql Workbench 8.0.19 中导入 .csv 文件
- android - 如何生成不同的调试 sha1-key
- php - 数组中的 Html 代码显示不正确?
- reactjs - 以编程方式附加组件
- python - 设置迷你 Dask 集群
- amazon-web-services - Amazon Corretto 11 不包括 jFX
- discord.js - Discord.js 将人移动到随机 VoiceChannel
- python - 如何在python ffmpeg中组合2个流
- android - Flutter cloud_firestore 包导致应用崩溃