乘客使用了比预期更多的PostgreSQL连接

时间:2018-10-01 14:16:01

标签: ruby-on-rails postgresql heroku passenger actioncable

长期以来,生产中一直存在着棘手的问题,我们不知道问题的根源。有时可以在localhost上重现它,Heroku Enterprise支持对此一无所知。

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

  • 独立的乘客,禁用线程,最多限制25个进程。没有最低设置。
  • 3个Web dynos

a SELECT * FROM pg_stat_activity GROUP BY client_addr并计算每个实例的连接数表明,在我们的高峰期,为一个乘客流程打开了1个以上的PSQL连接。

假设:

  • 一个地址大约是一个Dyno(由Heroku员工确认)
  • Passenger一次生成的进程不超过25个(在这些高峰期间已通过passenger-status确认)

以下是SELECT * FROM pg_stat_activity;的屏幕截图:

enter image description here 在屏幕截图中,我们可以看到有 45个psql连接来自运行乘客的同一个dyno。如果我们遵循以前的逻辑,则每个“乘客”进程的连接数不应超过1,因此应为25。

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

以下是同一次dyno的乘客状态的屏幕截图(不同的时间,只是为了证明一个dyno所创建的流程不超过25个): enter image description here

最后,我们从Heroku支持小组获得的回应之一(惊人的支持顺便说一句)

  

我还看到过以前的报道,《乘客使用比预期更多的连接》,但不幸的是,大多数都由于复制困难而关闭。

在“乘客”文档中,解释了“乘客”自行处理ActiveRecord连接。

任何潜在客户均表示赞赏。谢谢!

各种信息:

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

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

最后一件事:我们使用ActionCable。我读过某个地方,乘客在奇怪地处理套接字连接(打开一个有点隐藏的过程以保持连接有效)。这是我们的领先者之一,但到目前为止,在本地主机上复制它并不算运气。如果有人能确认乘客如何处理ActionCable连接,将不胜感激。

更新1(01/10/2018):

实验:

1 个答案:

答案 0 :(得分:0)

我们终于设法解决了关于旅客的问题。实际上,我们已经有很长时间了。

修复

如果您使用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实际上不应该占用整个过程。一个进程可以处理许多许多开放的套接字连接。 (对于一些知名品牌,许多人同时拥有超过一万个)。幸运的是,我们的套接字连接要少得多,但是仍然如此。

更改后,我们基本上告诉乘客不要用整个过程来处理一个套接字连接,而是要用一个完整的过程来处理所有套接字连接。

文档

某些指标,修复3周后

  • 乘客的分叉过程数量急剧减少(从75个过程减少到约15个过程)
  • 网络测功机上的
  • 全局内存使用量显着降低(与分叉的旅客流程的先前点有关)
  • 全球PSQL连接数量急剧下降,并稳定了两天(甚至在部署之后)。 (从150到30个连接)
  • 每个dyno的PSQL连接数量(从每个dyno的50个减少到每个dyno的10个以下)
  • Redis连接数减少并且稳定了两天(即使在部署之后)
  • PostgreSQL上的平均内存使用量急剧下降,并稳定了两天。
  • 总体吞吐量比平常高一点(吞吐量是每分钟处理的请求数)