我们遇到了一些超时问题。我们正在使用多线程运行sidekiq。他们每个人都执行一些http操作。有时,工作人员陷入Net HTTP调用,而不会超时。然后所有线程都空闲,什么都不做。
read_timeout
似乎设置为60,而ruby默认open_timeout
设置为nil
。这可能是问题吗?堆栈跟踪:
2014-07-07T07:59:22Z 26495 TID-otmt0zt9s INFO: /home/deployer/.rbenv/versions/2.1.2/lib/ruby/2.1.0/net/http.rb:879:in `initialize'
/home/deployer/.rbenv/versions/2.1.2/lib/ruby/2.1.0/net/http.rb:879:in `open'
/home/deployer/.rbenv/versions/2.1.2/lib/ruby/2.1.0/net/http.rb:879:in `block in connect'
/home/deployer/.rbenv/versions/2.1.2/lib/ruby/2.1.0/timeout.rb:76:in `timeout'
/home/deployer/.rbenv/versions/2.1.2/lib/ruby/2.1.0/net/http.rb:878:in `connect'
/home/deployer/.rbenv/versions/2.1.2/lib/ruby/2.1.0/net/http.rb:863:in `do_start'
/home/deployer/.rbenv/versions/2.1.2/lib/ruby/2.1.0/net/http.rb:852:in `start'
/home/deployer/.rbenv/versions/2.1.2/lib/ruby/2.1.0/net/http.rb:1369:in `request'
/home/deployer/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rack-mini-profiler-0.9.1/lib/patches/net_patches.rb:7:in `block in request_with_mini_profiler'
/home/deployer/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rack-mini-profiler-0.9.1/lib/mini_profiler/profiling_methods.rb:40:in `step'
/home/deployer/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rack-mini-profiler-0.9.1/lib/patches/net_patches.rb:6:in `request_with_mini_profiler'
/home/deployer/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/rest-client-1.6.7/lib/restclient/net_http_ext.rb:51:in `request'
/home/deployer/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/faraday-0.9.0/lib/faraday/adapter/net_http.rb:80:in `perform_request'
/home/deployer/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/faraday-0.9.0/lib/faraday/adapter/net_http.rb:39:in `call'
/home/deployer/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/faraday-0.9.0/lib/faraday/request/url_encoded.rb:15:in `call'
/home/deployer/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/signet-0.5.0/lib/signet/oauth_2/client.rb:875:in `fetch_access_token'
/home/deployer/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/signet-0.5.0/lib/signet/oauth_2/client.rb:898:in `fetch_access_token!'
/home/deployer/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/signet-0.5.0/lib/signet/oauth_2/client.rb:913:in `refresh!'
/home/deployer/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/google-ads-common-0.9.5/lib/ads_common/auth/oauth2_handler.rb:91:in `refresh_token!'
/home/deployer/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/google-ads-common-0.9.5/lib/ads_common/auth/oauth2_handler.rb:83:in `get_token'
/home/deployer/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/google-ads-common-0.9.5/lib/ads_common/auth/oauth2_handler.rb:75:in `auth_string'
/home/deployer/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/google-ads-common-0.9.5/lib/ads_common/savon_headers/oauth_header_handler.rb:45:in `generate_headers'
/home/deployer/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/google-ads-common-0.9.5/lib/ads_common/savon_headers/base_header_handler.rb:75:in `prepare_request'
/home/deployer/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/google-ads-common-0.9.5/lib/ads_common/savon_service.rb:103:in `block in execute_soap_request'
/home/deployer/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/savon-1.2.0/lib/savon/client.rb:129:in `yield_objects'
/home/deployer/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/savon-1.2.0/lib/savon/client.rb:122:in `process'
/home/deployer/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/savon-1.2.0/lib/savon/client.rb:84:in `block in request'
/home/deployer/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/savon-1.2.0/lib/savon/soap/request_builder.rb:56:in `call'
/home/deployer/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/savon-1.2.0/lib/savon/soap/request_builder.rb:56:in `request'
/home/deployer/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/savon-1.2.0/lib/savon/client.rb:86:in `request'
/home/deployer/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/google-ads-common-0.9.5/lib/ads_common/savon_service.rb:101:in `execute_soap_request'
/home/deployer/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/google-ads-common-0.9.5/lib/ads_common/savon_service.rb:80:in `execute_action'
/home/deployer/.rbenv/versions/2.1.2/lib/ruby/gems/2.1.0/gems/google-adwords-api-0.11.1/lib/adwords_api/v201402/campaign_service.rb:25:in `mutate'
/home/deployer/apps/robot/lib/adwords_helper.rb:1355:in `toggle_campaign'
/home/deployer/apps/robot/app/models/adwords_campaign.rb:262:in `adwords_toggle'
/home/deployer/apps/robot/app/workers/update_campaign_status.rb:13:in `perform'
/home/deployer/apps/robot/app/workers/recurring/refresh_campaign_status.rb:12:in `block in perform'
修改
我修补了http库。不确定问题是否会再次发生。如果是,我会在这里发布。
module Net
class HTTP < Protocol
alias_method :old_initialize, :initialize
def initialize(address, port = nil, open_timeout: 60)
old_initialize(address, port)
self.open_timeout = open_timeout
end
end
end
答案 0 :(得分:1)
问题在于您在更新中发布的Net::HTTP
中的默认超时值。对于Ruby 2.1.0,open_timeout
的默认值为nil
。 read_timeout
安全默认为60秒。
从Ruby 2.3开始,open_timeout
has changed from nil
to 60s的默认值。在您最初提出这个问题之后,Ruby 2.3将不会再发布一年半,但我向您或遇到此问题的任何人提出的建议是升级到Ruby 2.3或更高版本。 (而不是monkeypatch核心库,如果可能的话)