在维护 ruby on rails 的一个项目中,有个新需求:将原来本地数据库切换成远程的微软云数据库,原 database.yml 如下:
default: &default
adapter: mysql2
encoding: utf8
username: root
password: 123456
pool: 20
timeout: 5000
切换到远程数据库的 database.yml 如下:
default: &default
adapter: mysql2
encoding: utf8
host: '*********'
username: '********'
password: '********'
pool: 10
timeout: 5000
#reconnect: true
切换到微软云数据库后现象为:项目部署后 4 分钟左右再访问,网页卡死等待,后台连接数据库超时,截取日志如下:
F, [2016-11-30T15:33:27.114071 #26108] FATAL -- :
ActiveRecord::ConnectionTimeoutError (could not obtain a database connection within 5.000 seconds (waited 1902.103 seconds)):
activerecord (4.1.16) lib/active_record/connection_adapters/abstract/connection_pool.rb:190:in `block in wait_poll'
activerecord (4.1.16) lib/active_record/connection_adapters/abstract/connection_pool.rb:181:in `loop'
activerecord (4.1.16) lib/active_record/connection_adapters/abstract/connection_pool.rb:181:in `wait_poll'
activerecord (4.1.16) lib/active_record/connection_adapters/abstract/connection_pool.rb:136:in `block in poll'
/usr/local/rvm/rubies/ruby-2.1.5/lib/ruby/2.1.0/monitor.rb:211:in `mon_synchronize'
activerecord (4.1.16) lib/active_record/connection_adapters/abstract/connection_pool.rb:146:in `synchronize'
activerecord (4.1.16) lib/active_record/connection_adapters/abstract/connection_pool.rb:134:in `poll'
activerecord (4.1.16) lib/active_record/connection_adapters/abstract/connection_pool.rb:418:in `acquire_connection'
activerecord (4.1.16) lib/active_record/connection_adapters/abstract/connection_pool.rb:351:in `block in checkout'
/usr/local/rvm/rubies/ruby-2.1.5/lib/ruby/2.1.0/monitor.rb:211:in `mon_synchronize'
activerecord (4.1.16) lib/active_record/connection_adapters/abstract/connection_pool.rb:350:in `checkout'
activerecord (4.1.16) lib/active_record/connection_adapters/abstract/connection_pool.rb:265:in `block in connection'
/usr/local/rvm/rubies/ruby-2.1.5/lib/ruby/2.1.0/monitor.rb:211:in `mon_synchronize'
activerecord (4.1.16) lib/active_record/connection_adapters/abstract/connection_pool.rb:264:in `connection'
activerecord (4.1.16) lib/active_record/connection_adapters/abstract/connection_pool.rb:541:in `retrieve_connection'
activerecord (4.1.16) lib/active_record/connection_handling.rb:113:in `retrieve_connection'
activerecord (4.1.16) lib/active_record/connection_handling.rb:87:in `connection'
activerecord (4.1.16) lib/active_record/query_cache.rb:32:in `call'
activerecord (4.1.16) lib/active_record/connection_adapters/abstract/connection_pool.rb:621:in `call`
actionpack (4.1.16) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'
activesupport (4.1.16) lib/active_support/callbacks.rb:82:in `run_callbacks'
actionpack (4.1.16) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
actionpack (4.1.16) lib/action_dispatch/middleware/remote_ip.rb:76:in `call'
rollbar (2.12.0) lib/rollbar/middleware/rails/rollbar.rb:24:in `block in call'
rollbar (2.12.0) lib/rollbar.rb:735:in `scoped'
rollbar (2.12.0) lib/rollbar/middleware/rails/rollbar.rb:22:in `call'
actionpack (4.1.16) lib/action_dispatch/middleware/debug_exceptions.rb:17:in `call'
rollbar (2.12.0) lib/rollbar/middleware/rails/show_exceptions.rb:22:in `call_with_rollbar'
actionpack (4.1.16) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
railties (4.1.16) lib/rails/rack/logger.rb:38:in `call_app'
railties (4.1.16) lib/rails/rack/logger.rb:20:in `block in call'
activesupport (4.1.16) lib/active_support/tagged_logging.rb:68:in `block in tagged'
activesupport (4.1.16) lib/active_support/tagged_logging.rb:26:in `tagged'
activesupport (4.1.16) lib/active_support/tagged_logging.rb:68:in `tagged'
railties (4.1.16) lib/rails/rack/logger.rb:20:in `call'
actionpack (4.1.16) lib/action_dispatch/middleware/request_id.rb:21:in `call'
rack (1.5.5) lib/rack/methodoverride.rb:21:in `call'
rack (1.5.5) lib/rack/runtime.rb:17:in `call'
activesupport (4.1.16) lib/active_support/cache/strategy/local_cache_middleware.rb:26:in `call'
rack (1.5.5) lib/rack/sendfile.rb:112:in `call'
railties (4.1.16) lib/rails/engine.rb:514:in `call'
railties (4.1.16) lib/rails/application.rb:144:in `call'
puma (3.6.0) lib/puma/configuration.rb:225:in `call'
puma (3.6.0) lib/puma/server.rb:578:in `handle_request'
puma (3.6.0) lib/puma/server.rb:415:in `process_client'
puma (3.6.0) lib/puma/server.rb:275:in `block in run'
puma (3.6.0) lib/puma/thread_pool.rb:116:in `call'
puma (3.6.0) lib/puma/thread_pool.rb:116:in `block in spawn_thread'
个人分析,由于微软云数据库有网络层,负载均衡服务器对其设置了无访问超时时间,导致连接中断,但是并未通知其连接的两端。现在请教前辈该如何配置 rails 的连接池对其中断的连接进行管理或者有其他好的办法保证连接的持续性? ruby 版本 2.1.5 rails 4.1.16 puma 3.6.0
另有一个问题:现知道微软云的 mysql 数据库的连接总数为 202 个,约 200. puma 工作进程数:2 已知每个进程的线程数为 0~16 个。那个该怎样配置 database.yml 的 pool 数?也就是 pool 连接池数量是配置的每个线程的最大连接数吗?
望不吝赐教!!!!