【问题标题】:How to protect against Redis::TimeoutError: Connection timed out on Heroku如何防止 Redis::TimeoutError:Heroku 上的连接超时
【发布时间】:2016-02-17 01:52:14
【问题描述】:

这似乎是一个愚蠢的问题,但我认为 StackOverflow 上的某个人可能对此有一些想法。什么鬼,对吧?

我正在使用带有 1X Dynos 的 Heroku 工作人员来运行 Resque。有时我会收到此错误:Redis::TimeoutError: Connection timed out。它发生在redis gem 中;这是堆栈跟踪:

Redis::TimeoutError Connection timed out
    vendor/bundle/ruby/2.1.0/gems/redis-3.2.0/lib/redis/connection/ruby.rb:55 rescue in _read_from_socket
    vendor/bundle/ruby/2.1.0/gems/redis-3.2.0/lib/redis/connection/ruby.rb:48 _read_from_socket
    vendor/bundle/ruby/2.1.0/gems/redis-3.2.0/lib/redis/connection/ruby.rb:41 gets
    vendor/bundle/ruby/2.1.0/gems/redis-3.2.0/lib/redis/connection/ruby.rb:273 read
    vendor/bundle/ruby/2.1.0/gems/redis-3.2.0/lib/redis/client.rb:245 block in read
    vendor/bundle/ruby/2.1.0/gems/redis-3.2.0/lib/redis/client.rb:233 io
    vendor/bundle/ruby/2.1.0/gems/redis-3.2.0/lib/redis/client.rb:244 read
    vendor/bundle/ruby/2.1.0/gems/redis-3.2.0/lib/redis/client.rb:175 block in call_pipelined
    vendor/bundle/ruby/2.1.0/gems/redis-3.2.0/lib/redis/client.rb:214 block (2 levels) in process
    vendor/bundle/ruby/2.1.0/gems/redis-3.2.0/lib/redis/client.rb:340 ensure_connected
    vendor/bundle/ruby/2.1.0/gems/redis-3.2.0/lib/redis/client.rb:204 block in process
    vendor/bundle/ruby/2.1.0/gems/redis-3.2.0/lib/redis/client.rb:286 logging
    vendor/bundle/ruby/2.1.0/gems/redis-3.2.0/lib/redis/client.rb:203 process
    vendor/bundle/ruby/2.1.0/gems/redis-3.2.0/lib/redis/client.rb:174 call_pipelined
    vendor/bundle/ruby/2.1.0/gems/redis-3.2.0/lib/redis/client.rb:146 block in call_pipeline
    vendor/bundle/ruby/2.1.0/gems/redis-3.2.0/lib/redis/client.rb:273 with_reconnect
    vendor/bundle/ruby/2.1.0/gems/redis-3.2.0/lib/redis/client.rb:144 call_pipeline
    vendor/bundle/ruby/2.1.0/gems/redis-3.2.0/lib/redis.rb:2101 block in pipelined
    vendor/bundle/ruby/2.1.0/gems/redis-3.2.0/lib/redis.rb:37 block in synchronize
    vendor/ruby-2.1.5/lib/ruby/2.1.0/monitor.rb:211 mon_synchronize
    vendor/bundle/ruby/2.1.0/gems/redis-3.2.0/lib/redis.rb:37 synchronize
    vendor/bundle/ruby/2.1.0/gems/redis-3.2.0/lib/redis.rb:2097 pipelined
    vendor/bundle/ruby/2.1.0/gems/redis-namespace-1.5.1/lib/redis/namespace.rb:413 namespaced_block
    vendor/bundle/ruby/2.1.0/gems/redis-namespace-1.5.1/lib/redis/namespace.rb:265 pipelined
    vendor/bundle/ruby/2.1.0/gems/resque-1.25.2/lib/resque.rb:214 push
    vendor/bundle/ruby/2.1.0/gems/resque-1.25.2/lib/resque/job.rb:153 create
    vendor/bundle/ruby/2.1.0/gems/resque_solo-0.1.0/lib/resque_ext/job.rb:7 create_solo
    vendor/bundle/ruby/2.1.0/gems/resque-1.25.2/lib/resque.rb:317 enqueue_to
    vendor/bundle/ruby/2.1.0/gems/resque-1.25.2/lib/resque.rb:298 enqueue

我们已经设置了resque-retry,但我想enqueue 调用甚至无法连接到redis 也没关系。

我当前的解决方案是用begin/rescue 包装每个Resque.enqueue 调用,以便我们可以重新尝试enqueue 调用(根据https://github.com/resque/resque/issues/840)。但是没有更好的方法吗?

【问题讨论】:

    标签: ruby-on-rails heroku redis resque resque-retry


    【解决方案1】:

    Heroku Redis 允许您更改实例超时和 maxmemory-policy 设置。这些设置将在升级和 HA 故障转移期间保留。

    来自documentation

    超时设置设置 Redis 在终止空闲连接之前等待的秒数。零值意味着连接不会被关闭。默认值为 300 秒(5 分钟)。您可以使用 CLI 更改此值:

    $ heroku redis:timeout maturing-deeply-2628 --seconds 60
    

    maturing-deeply-2628 (REDIS_URL) 的超时设置为 60 秒。 空闲 60 秒后将停止与 redis 实例的连接。

    resque 的情况下,0(不使用连接超时)将是最佳选择(--seconds 0)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-21
      • 1970-01-01
      • 2013-01-24
      • 2013-07-03
      相关资源
      最近更新 更多