乘客使用的PostgreSQL连接数超出预期

6
长期以来,在生产中发生了一个困难的问题,我们不知道它来自哪里。有时可以在本地主机上重现此问题,但Heroku企业支持对此毫无头绪。
在我们的生产数据库中,我们目前拥有以下设置:
- Passenger Standalone,线程禁用,最多限制为25个进程。没有最小设置。 - 3个Web Dynos
使用SELECT * FROM pg_stat_activity GROUP BY client_addr并计算每个实例的连接数,显示在我们的高峰期间,一个Passenger进程打开了超过1个PSQL连接。
假设:
- 单个地址大约是单个Dyno(由Heroku工作人员确认) - Passenger在同时不会生成超过25个进程(在这些高峰期间通过passenger-status确认)
这是一个SELECT * FROM pg_stat_activity;的截屏。

在这里输入图片描述 从截图中我们可以看到,有45个psql连接来自运行passenger的同一个dyno。如果按照以前的逻辑,每个Passenger进程不应该超过1个连接,所以应该是25个。

日志看起来并不异常,没有提到任何dyno崩溃/进程崩溃的情况。

以下是我们为同一dyno获取的passenger状态的屏幕截图(不同的时间,只是为了证明一个dyno不会创建超过25个进程): 在这里输入图片描述

最后,我们从Heroku支持团队得到的一个响应(非常好的支持团队):

我之前也见过关于Passenger使用比预期更多连接的报告,但大多数都因难以复制而关闭了。

在Passenger文档中,解释了Passenger如何处理ActiveRecord连接。

非常感谢任何线索!

各种信息:

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

如果您需要更多信息,请在评论中让我知道,我会很乐意更新此帖子。

最后一件事:我们使用ActionCable。我在某个地方读到过,Passenger处理奇怪的套接字连接(打开一个有点隐蔽的进程以保持连接)。这是我们的其中之一线索,但到目前为止,在本地主机上无法复制它。如果有人可以确认Passenger如何处理ActionCable连接,将不胜感激。

更新1(01/10/2018):

实验:

1个回答

0

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

修复方法

如果您使用ActionCable,并且默认的cable路由是/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不要使用整个进程来处理一个套接字连接,而是将一个完整的进程专门用于处理所有套接字连接。

文档

修复后的三周指标

  • Passenger上分叉进程的数量显著减少(从75个进程到约15个进程)
  • Web dynos上的全局内存使用量显著减少(与前面关于分叉Passenger进程的点有关)
  • PSQL连接的全局数量显著减少,并已经保持稳定两天(即使在部署后)。 (从150个连接到约30个连接)
  • 每个dyno上的PSQL连接数显著减少,(从每个dyno的约50个连接到每个dyno的不到10个连接)
  • Redis连接数减少,并已经保持稳定两天(即使在部署后)
  • PostgreSQL上的平均内存使用率显著减少,并已经保持稳定两天。
  • 总吞吐量略高于平常(吞吐量是每分钟处理的请求数)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接