Passenger使用比预期更多的PostgreSQL连接

Ero*_*lin 6 postgresql ruby-on-rails passenger heroku actioncable

生产中存在很长时间的难题,我们不知道它来自何处.有时候可以在localhost上重现它,Heroku Enterprise支持一直没有这个.

在我们的生产数据库中,我们目前有以下设置:

  • Passenger Standalone,禁用线程,限制为25个进程MAX.没有设置.
  • 3网络dynos

a SELECT * FROM pg_stat_activity GROUP BY client_addr并计算每个实例的连接数,表明在高峰期间为一个客运进程打开了超过1个PSQL连接.

假设:

  • 单个地址大约是一个Dyno(由Heroku员工确认)
  • 乘客当时不会产生超过25个进程(passenger-status在这些峰值期间确认)

这是一个截图SELECT * FROM pg_stat_activity;:

在此输入图像描述 在屏幕截图中,我们可以看到有45个psql连接来自同一个运行乘客的dyno.如果我们遵循先前的逻辑,那么每个乘客流程不应该有超过1个连接,所以25.

日志看起来并不寻常,没有提到dyno崩溃/进程崩溃.

以下是相同dyno的乘客状态的屏幕截图(不同的时间,只是为了证明没有比为一个dyno创建的25个更多的进程): 在此输入图像描述

最后我们从Heroku支持获得了一个响应(惊人的支持btw)

我还看到之前有关乘客利用比预期更多连接的报告,但不幸的是,大多数人因复制困难而被关闭.

在Passenger文档中,解释了Passenger自己处理ActiveRecord连接.

任何线索赞赏.谢谢!

各种信息:

  • Ruby版本: 2.4.x
  • Rails版本: 5.1.x
  • 乘客版本: 5.3.x
  • PG版本: 10.x
  • ActiveRecord版本: 5.1.x

如果您需要更多信息,请在评论中告诉我,我很乐意更新这篇文章.

最后一件事:我们使用ActionCable.我读过某个地方乘客正在处理奇怪的套接字连接(打开一个隐藏的过程以保持连接活着).这是我们的一个主角,但到目前为止,没有运气在localhost上重现它.如果任何人都可以确认Passenger如何处理ActionCable连接,那将非常感激.

更新1(01/10/2018):

尝试:

Ero*_*lin 0

我们终于成功解决了 Passenger 上的问题。实际上我们已经有这个问题很长时间了。

修复

如果您使用 ActionCable,并且您的默认电缆路线是/cable,则将 Procfile 更改为:

web: bundle exec passenger start -p $PORT --max-pool-size $PASSENGER_MAX_POOL_SIZE
Run Code Online (Sandbox Code Playgroud)

web: bundle exec passenger start -p $PORT --max-pool-size $PASSENGER_MAX_POOL_SIZE --unlimited-concurrency-path /cable
Run Code Online (Sandbox Code Playgroud)

解释

在更改之前,每个套接字连接 (ActionCable) 将在 Passenger 中占用一个进程。但Socket实际上是不应该占用整个过程的东西。一个进程可以处理很多很多打开的套接字连接。(对于一些大牌来说,很多是同时超过一万)。幸运的是,我们的套接字连接要少得多,但仍然如此。

更改后,我们基本上告诉 Passenger 不要使用整个进程来处理一个套接字连接,而是专门使用整个进程来处理所有套接字连接。

文档

修复三周后的一些指标

  • Passenger 上的分叉进程数量大幅减少(从 75 个进程减少到约 15 个进程)
  • Web dynos 上的全局内存使用量显着下降(与分叉 Passenger 进程的前一点相关)
  • 全球 PSQL 连接数急剧下降,并连续两天保持稳定(即使在部署后)。(从 150 个连接到约 30 个连接)
  • 每个 dyno的 PSQL 连接数量大幅减少(从每个 dyno 约 50 个减少到每个 dyno 不到 10 个)
  • Redis 连接数减少,两天保持稳定(部署后也是如此)
  • PostgreSQL 的平均内存使用量急剧下降,并连续两天保持稳定。
  • 整体吞吐量比平常高一点(吞吐量是每分钟处理的请求数)