x 时间后套接字无响应 (puma - ruby)
Unresponsive socket after x time (puma - ruby)
我的 Puma 设置在随机时间后遇到无响应的套接字。到目前为止,我不知道是什么导致了这个问题。我希望这里有人可以帮助我们提供一些答案或为我指明正确的方向。我有以下设置:
我使用的是官方docker ruby-2.2.3-slim 镜像和最新的puma 版本2.15.3,我还安装了Nginx 作为反向代理。但我已经确定 Nginx 不是这里的问题,因为我已经尝试使用此 script 验证套接字是否正常工作。而且套接字不工作,我在那里也有超时,所以我可以忽略 Nginx。
这是一个测试环境,因此服务器没有遇到任何极端负载,我还检查了内存消耗,它仍有几 GB 的可用空间 space,所以这也不是问题。
促使我查看 puma 套接字的是我在 Nginx 错误日志记录中收到的错误消息:
upstream timed out (110: Connection timed out) while reading response header from upstream
此外,我在 puma 的日志中找不到任何指示出了什么问题的信息,这是我的 puma 设置:
threads 0, 16
app_dir = ENV.fetch('APP_HOME')
environment ENV['RAILS_ENV']
daemonize
bind "unix://#{app_dir}/sockets/puma.sock"
stdout_redirect "#{app_dir}/log/puma.stdout.log", "#{app_dir}/log/puma.stderr.log", true
pidfile "#{app_dir}/pids/puma.pid"
state_path "#{app_dir}/pids/puma.state"
activate_control_app
on_worker_boot do
require 'active_record'
ActiveRecord::Base.connection.disconnect! rescue ActiveRecord::ConnectionNotEstablished
ActiveRecord::Base.establish_connection(YAML.load_file("#{app_dir}/config/database.yml")[ENV['RAILS_ENV']])
end
这是我的 puma 状态文件中的输出:
---
pid: 43
config: !ruby/object:Puma::Configuration
cli_options:
conf:
options:
:min_threads: 0
:max_threads: 16
:quiet: false
:debug: false
:binds:
- unix:///APP/sockets/puma.sock
:workers: 1
:daemon: true
:mode: :http
:before_fork: []
:worker_timeout: 60
:worker_boot_timeout: 60
:worker_shutdown_timeout: 30
:environment: staging
:redirect_stdout: "/APP/log/puma.stdout.log"
:redirect_stderr: "/APP/log/puma.stderr.log"
:redirect_append: true
:pidfile: "/APP/pids/puma.pid"
:state: "/APP/pids/puma.state"
:control_url: unix:///tmp/puma-status-1449260516541-37
:config_file: config/puma.rb
:control_url_temp: "/tmp/puma-status-1449260516541-37"
:control_auth_token: cda8879717be7a645ea323d931b88d4b
:tag: APP
该应用程序本身是一个 Rails 最新版本 4.2.5 上的应用程序,它部署在 GCE(Google 容器引擎)上。
如果有人能给我一些关于如何进一步调试它的指示,将不胜感激。因为现在我在任何地方都看不到任何可以帮助我的输出。
编辑
我用到 Puma 的 tcp 连接替换了 unix 套接字,结果相同,x 时间后仍然挂起
我会从:
开始
- 每个 puma 实例成功处理了多少个请求?
- 确保使用执行它的线程的线程 ID 记录每个请求的开始和结束,您看到了什么?
我对您的应用程序了解不多,我想说线程很可能在执行一些 long/blocking 没有超时的调用或在某些计算上自旋,直到整个线程池耗尽。
我们拭目以待。
我终于找到了为什么我的应用程序表现如此。
在尝试使用 tcp 连接并切换到 Unicorn 后,我开始研究其他可能的来源。
那时我认为我与 Google Cloud SQL 的连接可能是问题所在。在我阅读 Cloud SQL 的常见问题解答后,他们提到您必须调整您的 Compute 实例以确保它们保持打开您的数据库连接。所以我执行了他们推荐的后续步骤并为我解决了问题,我添加了它们以防万一:
# Display the current tcp_keepalive_time value.
$ cat /proc/sys/net/ipv4/tcp_keepalive_time
# Set tcp_keepalive_time to 60 seconds and make it permanent across reboots.
$ echo 'net.ipv4.tcp_keepalive_time = 60' | sudo tee -a /etc/sysctl.conf
# Apply the change.
$ sudo /sbin/sysctl --load=/etc/sysctl.conf
# Display the tcp_keepalive_time value to verify the change was applied.
$ cat /proc/sys/net/ipv4/tcp_keepalive_time
我的 Puma 设置在随机时间后遇到无响应的套接字。到目前为止,我不知道是什么导致了这个问题。我希望这里有人可以帮助我们提供一些答案或为我指明正确的方向。我有以下设置:
我使用的是官方docker ruby-2.2.3-slim 镜像和最新的puma 版本2.15.3,我还安装了Nginx 作为反向代理。但我已经确定 Nginx 不是这里的问题,因为我已经尝试使用此 script 验证套接字是否正常工作。而且套接字不工作,我在那里也有超时,所以我可以忽略 Nginx。
这是一个测试环境,因此服务器没有遇到任何极端负载,我还检查了内存消耗,它仍有几 GB 的可用空间 space,所以这也不是问题。 促使我查看 puma 套接字的是我在 Nginx 错误日志记录中收到的错误消息:
upstream timed out (110: Connection timed out) while reading response header from upstream
此外,我在 puma 的日志中找不到任何指示出了什么问题的信息,这是我的 puma 设置:
threads 0, 16
app_dir = ENV.fetch('APP_HOME')
environment ENV['RAILS_ENV']
daemonize
bind "unix://#{app_dir}/sockets/puma.sock"
stdout_redirect "#{app_dir}/log/puma.stdout.log", "#{app_dir}/log/puma.stderr.log", true
pidfile "#{app_dir}/pids/puma.pid"
state_path "#{app_dir}/pids/puma.state"
activate_control_app
on_worker_boot do
require 'active_record'
ActiveRecord::Base.connection.disconnect! rescue ActiveRecord::ConnectionNotEstablished
ActiveRecord::Base.establish_connection(YAML.load_file("#{app_dir}/config/database.yml")[ENV['RAILS_ENV']])
end
这是我的 puma 状态文件中的输出:
---
pid: 43
config: !ruby/object:Puma::Configuration
cli_options:
conf:
options:
:min_threads: 0
:max_threads: 16
:quiet: false
:debug: false
:binds:
- unix:///APP/sockets/puma.sock
:workers: 1
:daemon: true
:mode: :http
:before_fork: []
:worker_timeout: 60
:worker_boot_timeout: 60
:worker_shutdown_timeout: 30
:environment: staging
:redirect_stdout: "/APP/log/puma.stdout.log"
:redirect_stderr: "/APP/log/puma.stderr.log"
:redirect_append: true
:pidfile: "/APP/pids/puma.pid"
:state: "/APP/pids/puma.state"
:control_url: unix:///tmp/puma-status-1449260516541-37
:config_file: config/puma.rb
:control_url_temp: "/tmp/puma-status-1449260516541-37"
:control_auth_token: cda8879717be7a645ea323d931b88d4b
:tag: APP
该应用程序本身是一个 Rails 最新版本 4.2.5 上的应用程序,它部署在 GCE(Google 容器引擎)上。
如果有人能给我一些关于如何进一步调试它的指示,将不胜感激。因为现在我在任何地方都看不到任何可以帮助我的输出。
编辑
我用到 Puma 的 tcp 连接替换了 unix 套接字,结果相同,x 时间后仍然挂起
我会从:
开始- 每个 puma 实例成功处理了多少个请求?
- 确保使用执行它的线程的线程 ID 记录每个请求的开始和结束,您看到了什么?
我对您的应用程序了解不多,我想说线程很可能在执行一些 long/blocking 没有超时的调用或在某些计算上自旋,直到整个线程池耗尽。
我们拭目以待。
我终于找到了为什么我的应用程序表现如此。 在尝试使用 tcp 连接并切换到 Unicorn 后,我开始研究其他可能的来源。
那时我认为我与 Google Cloud SQL 的连接可能是问题所在。在我阅读 Cloud SQL 的常见问题解答后,他们提到您必须调整您的 Compute 实例以确保它们保持打开您的数据库连接。所以我执行了他们推荐的后续步骤并为我解决了问题,我添加了它们以防万一:
# Display the current tcp_keepalive_time value.
$ cat /proc/sys/net/ipv4/tcp_keepalive_time
# Set tcp_keepalive_time to 60 seconds and make it permanent across reboots.
$ echo 'net.ipv4.tcp_keepalive_time = 60' | sudo tee -a /etc/sysctl.conf
# Apply the change.
$ sudo /sbin/sysctl --load=/etc/sysctl.conf
# Display the tcp_keepalive_time value to verify the change was applied.
$ cat /proc/sys/net/ipv4/tcp_keepalive_time