我有一个中等复杂度的 Rails 应用程序在 Apache/Passenger 下运行,它在空闲一段时间后变得无响应。它需要几分钟才能响应,但可以通过重新启动 Web 服务器暂时恢复。
服务器负载可以忽略不计,而且由于它是内部应用程序,所以很少有超过几个并发用户。
我也尝试过 nginx,所以问题不是由 Apache 引起的。
Apache 或 Rails 日志中没有任何有用的信息。根据 Passenger 文档,我发送了 SIGABRT 并有一个堆栈跟踪(如下)。它的数据库负载不重,我尝试禁用可能导致锁定的任何后台处理。
信号异常(SIGABRT): 乘客(3.0.17)lib / phusion_passenger / abstract_request_handler.rb:443:在`install_useful_signal_handlers中的阻止' activerecord (3.2.8) lib/active_record/connection_adapters/mysql2_adapter.rb:73:in`调用' activerecord (3.2.8) lib/active_record/connection_adapters/mysql2_adapter.rb:73:in `ping' activerecord (3.2.8) lib/active_record/connection_adapters/mysql2_adapter.rb:73:in`活动?' activerecord (3.2.8) lib/active_record/connection_adapters/abstract_adapter.rb:219:在`验证!' activerecord (3.2.8) lib/active_record/connection_adapters/abstract/connection_pool.rb:327:in`在 checkout_and_verify 中阻止' activesupport (3.2.8) lib/active_support/callbacks.rb:403:在`_run__352340970312725798__checkout__1600727162984137669__callbacks'中 activesupport (3.2.8) lib/active_support/callbacks.rb:405:在`__run_callback'中 activesupport (3.2.8) lib/active_support/callbacks.rb:385:in `_run_checkout_callbacks' activesupport (3.2.8) lib/active_support/callbacks.rb:81:在`run_callbacks'中 activerecord (3.2.8) lib/active_record/connection_adapters/abstract/connection_pool.rb:326:in`checkout_and_verify' activerecord (3.2.8) lib/active_record/connection_adapters/abstract/connection_pool.rb:247:in `块(2 级)在结帐中' activerecord (3.2.8) lib/active_record/connection_adapters/abstract/connection_pool.rb:236:in `循环' activerecord (3.2.8) lib/active_record/connection_adapters/abstract/connection_pool.rb:236:in`阻止签出' /home/uuuuu/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/monitor.rb:211:in`mon_synchronize' activerecord (3.2.8) lib/active_record/connection_adapters/abstract/connection_pool.rb:233:in `checkout' activerecord (3.2.8) lib/active_record/connection_adapters/abstract/connection_pool.rb:96:in`连接阻塞' /home/uuuuu/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/monitor.rb:211:in`mon_synchronize' activerecord (3.2.8) lib/active_record/connection_adapters/abstract/connection_pool.rb:95:in `连接' activerecord (3.2.8) lib/active_record/connection_adapters/abstract/connection_pool.rb:404:in`retrieve_connection' activerecord (3.2.8) lib/active_record/connection_adapters/abstract/connection_specification.rb:170:in`retrieve_connection' activerecord (3.2.8) lib/active_record/connection_adapters/abstract/connection_specification.rb:144:in `连接' activerecord (3.2.8) lib/active_record/query_cache.rb:61:in `调用' activerecord (3.2.8) lib/active_record/connection_adapters/abstract/connection_pool.rb:473:in`调用' actionpack (3.2.8) lib/action_dispatch/middleware/callbacks.rb:28:in`调用中的阻止' activesupport (3.2.8) lib/active_support/callbacks.rb:405:在`_run__1086758471249540907__call__1600727162984137669__callbacks'中 activesupport (3.2.8) lib/active_support/callbacks.rb:405:在`__run_callback'中 activesupport (3.2.8) lib/active_support/callbacks.rb:385:in `_run_call_callbacks' activesupport (3.2.8) lib/active_support/callbacks.rb:81:在`run_callbacks'中 actionpack (3.2.8) lib/action_dispatch/middleware/callbacks.rb:27:in `call' actionpack (3.2.8) lib/action_dispatch/middleware/remote_ip.rb:31:in`调用' actionpack (3.2.8) lib/action_dispatch/middleware/debug_exceptions.rb:16:in`调用' actionpack (3.2.8) lib/action_dispatch/middleware/show_exceptions.rb:56:in`调用' railties (3.2.8) lib/rails/rack/logger.rb:26:in `call_app' railties (3.2.8) lib/rails/rack/logger.rb:16:in `调用' actionpack (3.2.8) lib/action_dispatch/middleware/request_id.rb:22:in`调用' rack (1.4.1) lib/rack/methodoverride.rb:21:in`调用' rack (1.4.1) lib/rack/runtime.rb:17:in`调用' activesupport (3.2.8) lib/active_support/cache/strategy/local_cache.rb:72:in`调用' 机架(1.4.1)lib/rack/lock.rb:15:in`调用' actionpack (3.2.8) lib/action_dispatch/middleware/static.rb:62:in`调用' 机架缓存 (1.2) lib/rack/cache/context.rb:136:in `前进' 机架缓存 (1.2) lib/rack/cache/context.rb:245:in `fetch' 机架缓存 (1.2) lib/rack/cache/context.rb:185:in `lookup' rack-cache (1.2) lib/rack/cache/context.rb:66:in`调用!' 机架缓存 (1.2) lib/rack/cache/context.rb:51:in `调用' railties (3.2.8) lib/rails/engine.rb:479:in `调用' railties (3.2.8) lib/rails/application.rb:223:in `调用' railties (3.2.8) lib/rails/railtie/configurable.rb:30:in `method_missing' rack-pjax (0.6.0) lib/rack/pjax.rb:12:in `调用' 乘客(3.0.17)lib/phusion_passenger/rack/request_handler.rb:96:in`process_request' 乘客(3.0.17)lib/phusion_passenger/abstract_request_handler.rb:516:in`accept_and_process_next_request' 乘客(3.0.17)lib/phusion_passenger/abstract_request_handler.rb:274:在“main_loop”中 乘客(3.0.17)lib/phusion_passenger/rack/application_spawner.rb:206:in`start_request_handler' 乘客(3.0.17)lib/phusion_passenger/rack/application_spawner.rb:171:in`block in handle_spawn_application' 乘客(3.0.17)lib/phusion_passenger/utils.rb:470:in`safe_fork' 乘客(3.0.17)lib/phusion_passenger/rack/application_spawner.rb:166:in`handle_spawn_application' 乘客(3.0.17)lib/phusion_passenger/abstract_server.rb:357:in`server_main_loop' 乘客(3.0.17)lib/phusion_passenger/abstract_server.rb:206:in`start_synchronously' 乘客(3.0.17)lib/phusion_passenger/abstract_server.rb:180:in`启动' 乘客(3.0.17)lib / phusion_passenger / rack / application_spawner.rb:129:在“启动” 乘客(3.0.17)lib/phusion_passenger/spawn_manager.rb:253:in`块(2 个级别)在 spawn_rack_application 中' 乘客(3.0.17)lib/phusion_passenger/abstract_server_collection.rb:132:in`lookup_or_add' 乘客(3.0.17)lib/phusion_passenger/spawn_manager.rb:246:in`在spawn_rack_application中阻止' 乘客(3.0.17)lib/phusion_passenger/abstract_server_collection.rb:82:in`同步中的阻止' :10:在`同步'中 乘客(3.0.17)lib/phusion_passenger/abstract_server_collection.rb:79:in`同步' 乘客(3.0.17)lib/phusion_passenger/spawn_manager.rb:244:in`spawn_rack_application' 乘客(3.0.17)lib/phusion_passenger/spawn_manager.rb:137:in`spawn_application' 乘客(3.0.17)lib/phusion_passenger/spawn_manager.rb:275:in`handle_spawn_application' 乘客(3.0.17)lib/phusion_passenger/abstract_server.rb:357:in`server_main_loop' 乘客(3.0.17)lib/phusion_passenger/abstract_server.rb:206:in`start_synchronously' 乘客(3.0.17)辅助脚本/乘客生成服务器:99:在''
数据库.yml:
生产: 适配器:mysql2 编码:utf8 数据库: [db] 主持人:[主持人] 池:5 用户名:[用户] 密码:[密码] 超时:2000
我正在运行 Ubuntu 12.04.1 LTS、Ruby 1.9.3p194(通过 RVM)和 Passenger 3.0.18。
在 WEBrick 下的开发模式下我从未遇到过这个问题。
答案1
我在使用 ruby 2.0.0-p0 时遇到了同样的问题。
../bundle/ruby/2.0.0/gems/activerecord-3.2.13/lib/active_record/connection_adapters/mysql2_adapter.rb:73:in `ping'
我尝试过 unicorn、thin 和 pilot。这并没有改变任何东西。
production:
adapter: mysql2
database: ***
username: ***
password: ***
host: an IP
reconnect: true
wait_timeout: 3 # I've tried with this option and without
有任何想法吗 ?
libmysqlclient 5.1.66-0+squeeze1
mysql-server 5.1.66-0+squeeze1
编辑
这似乎是一个防火墙问题具有 TCP Keepalive。如果 MySQL 客户端的 TCP Keepalive 大于防火墙的 Keepalive,则会出现此问题。
答案2
我正在使用 Google Compute Engine,并且一直遇到同样的问题 - 大约 10 分钟的空闲时间后,对我的 Rails 应用程序的请求就会完全挂起,没有明显的日志或问题出现的迹象。
经过多次调试和跟踪,结果发现是防火墙超时——来自 GCE 实例的 TCP 连接在空闲 10 分钟后自动超时。我成功地解决了这个问题,方法是将 TCP keepalive 配置为在空闲 60 秒(而不是默认的 2 小时)时发送其第一个探测,以便与数据库的长寿命 TCP 连接保持活动状态。这里也提到了这一点:https://cloud.google.com/sql/docs/gce-access
# 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