nginx + puma,rails 5,纯 api 模式提供 json 接口
不定期出现所有接口都无响应的症状,去服务器 lsof 的结果:非常多的 CLOSE_WAIT,如下图:
此时只能 kill puma 进程然后重开。
nginx 配置:
puma.rb:
database.yml:
请问大佬们,可能是什么原因?有什么彻底的解决方法么?(手动抠鼻)
A connection pool synchronizes thread access to a limited number of database connections. The basic idea is that each thread checks out a database connection from the pool, uses that connection, and checks the connection back in. ConnectionPool is completely thread-safe, and will ensure that a connection cannot be used by two threads at the same time, as long as ConnectionPool's contract is correctly followed. It will also handle cases in which there are more threads than connections: if all connections have been checked out, and a thread tries to checkout a connection anyway, then ConnectionPool will wait until some other thread has checked in a connection. pool 的值应该与 puma 最大 thread 数一致,大于 thread 数其实是无效的。
这个线程池个数设置方式 应该比较靠谱。
特例是,在 puma 的一个 thread 里并行用到了一个以上的连接。但是似乎我也没想到这种情况的场景。
而且算法是在 puma max threads 的情况下的,一般压力不会那么大
简化一下情况
假设运行后端的服务器只有 1 核的 CPU
之后开一个 PUMA , puma 跑 20 个线程,
现在有大量数据库事务的任务,每个事务执行需要 1s,
再假设除了执行数据库,其他操作小于 1ms 的响应
如果 pool 的大小是 2, 那么是不是此时就只能并发两个请求?
是否能等效理解为 在执行事务的时候,此时服务器的 cpu 是空闲状态,但是却因为数据库连接池的问题不能进行服务?
如果此时连接池开到 20, 将 puma 的线程池满
似乎就可以进入 20 个并发了
或者我的理解有问题,有一些概念上的错误?
我的理解是:线程数也是和 cpu 数量相关的,1 核的 cpu,你线程设置成 20,反而使 cpu 花费大量时间做上下文切换,导致性能降低。 所以我认为 puma 线程数,数据库连接池都应和 cpu 数量挂钩的
cpu 是跟 puma 进程数挂钩的吧。IO wait puma 多线程就管用了... DB pool 是要跟 puma 线程数挂钩的吧,如果 20 个线程全在跑,pool 数为 2,那显然是不够用...
在我举的例子当中,当进行数据库事务的时候 本机的 CPU 是闲置的状态,这个时候切换上下文是会提高 cpu 效率的,而这种情况的变种我觉得还经常会发生 (瓶颈在数据库). 所以我会对您那个公式有点不同意见
你可以查看一下 postgresql 的配置文件,检查下,下面三项配置,可以参考这里
tcp_keepalives_idle
tcp_keepalives_interval
tcp_keepalives_count