在弹性beantalk中运行sidekiq时Redis连接超时错误

Posted

技术标签:

【中文标题】在弹性beantalk中运行sidekiq时Redis连接超时错误【英文标题】:Redis connection timeout error when running sidekiq in elastic beanstalk 【发布时间】:2021-03-16 05:32:47 【问题描述】:

我正在尝试设置 sidekiq 以从我的 AWS elastic beanstalk (Amazon Linux 2) 实例连接到 redis elasticache(已启用传输中加密)。我已经关注了诸如this 之类的链接,但是当我这样做时,我得到了“Redis::TimeoutError: Connection timed out”。因此,现在我没有部署运行“bundle exec sidekiq -e production”命令的脚本,而是使用 root 权限在我的 ec2 实例的 /var/app/current 目录中运行该命令。不幸的是,该错误仍然出现,我不确定为什么。我的安全组都配置正确,我可以确认端点是正确的。

奇怪的是,我可以通过运行以下命令连接到我在 elasticache 上的 redis 端点: openssl s_client -quiet -connect my_redis_endpoint:6379 并且它工作正常。但是sidekiq会启动,然后当我运行它时会超时。这是输出:


[root@ip-10-0-2-138 current]# bundle exec sidekiq -e production 2020-12-04T05:30:39.930Z pid=2910 tid=2xygu 信息:使用 redis 选项启动 Sidekiq 6.0.0 :url=>"redis://master.redisproductionelasticache.bmxvqz.use2.cache.amazonaws.com: 6379/12", :ssl=>true, :network_timeout=>5, :id=>"Sidekiq-server-PID-2910"

2020-12-04T05:31:04.271Z pid=2910 tid=1e7u1a class=MessageBroadcastJob jid=82dd4217186de283e9d9bb70 elapsed=10.251 INFO:失败

2020-12-04T06:10:30.391Z pid=2910 tid=1e7wm6 WARN: "context":"作业引发异常","job":"class":"ActiveJob::QueueAdapters::SidekiqAdapter: :JobWrapper","wrapped":"MessageBroadcastJob","queue":"default","args":["job_class":"MessageBroadcastJob","job_id":"4d7d5195-7444-44c9-81c7-7f9a0c6b1f75", "provider_job_id":null,"queue_name":"default","priority":null,"arguments":["_aj_globalid":"gid://e-wagers/Message/57bed09a-ef2d-4963-8288-65fe733347ba "],"executions":0,"locale":"en"],"retry":true,"jid":"a8f258e1feeecbf8c40a21a5","created_at":1607059284.1670992,"enqueued_at":1607062220.2854364,"error_message": "连接超时","error_class":"Redis::TimeoutError","failed_at":1607059284.1989071,"retry_count":6,"retry_at":1607060724.9108222,"jobstr":"


这是我的配置文件:

# config/initializers/sidekiq.rb

require 'sidekiq'
require 'sidekiq/web'

rails_root = Rails.root || File.dirname(__FILE__) + '/../..'
rails_env = Rails.env || 'development'
redis_config = YAML.load_file(rails_root.to_s + '/config/redis.yml')
redis_config.merge! redis_config.fetch(Rails.env, )
redis_config.symbolize_keys!

Sidekiq.configure_server do |config|
 config.redis =  url: "redis://#redis_config[:host]:#redis_config[:port]/12", ssl: true, network_timeout: 5 
end

Sidekiq.configure_client do |config|
 config.redis =  url: "redis://#redis_config[:host]:#redis_config[:port]/12", ssl: true, network_timeout: 5 
end
development:
  host: 'localhost'
  port: 6379
  db: 5
production:
  host: 'master.my_redis_endpoint.bmxvqz.use2.cache.amazonaws.com'
  port: 6379
  db: 5
# config/sidekiq.yml

:concurrency: 25
:queues:
  - [mailers, 3]
  - ["priority", 2]
  - ["default", 1]

任何想法可能导致这种情况?不幸的是,网上没有很多关于 sidekiq 与 elasticache、elastic beanstalk 和更新的 Amazon Linux 2 平台的资源。

【问题讨论】:

【参考方案1】:

您是否尝试过使用rediss:// 而不是redis://

【讨论】:

我有。还尝试使用非加密连接,但仍然出现同样的错误。所以我相信与 SSL 无关。 检查您的安全组和网络 ACL 的配置,这可能是导致非加密连接中出现该问题的原因,我还发现要与 redis 建立加密连接,您需要设置隧道。 Here 是关于如何在 EC2 实例上执行此操作的简短文档 【参考方案2】:

由于您的 Sidekiq 进程正在从服务器接收作业,它能够连接到 Redis。您可能看到的是另一个 gem 与 Redis 的连接由于过度激进的超时而失败。在我的例子中,那个 gem 是 Redlock,它设置了一个 100 毫秒的超时时间(对于 Elasticache 连接来说有点太慢了,它有大约 120 毫秒的延迟):https://github.com/leandromoreira/redlock-rb/blob/40756981932ca53c3e32bf3c68aa5ea9b772ef16/lib/redlock/client.rb#L9

【讨论】:

以上是关于在弹性beantalk中运行sidekiq时Redis连接超时错误的主要内容,如果未能解决你的问题,请参考以下文章

尝试通过弹性 beantalk 运行救援时忽略 .ebextensions 文件

botocore.exceptions.ProfileNotFound 当代码在AWS弹性beantalk上运行时,但在本地没问题

使用弹性 beantalk 运行后台作业

如何在弹性 beantalk 配置上运行 wget cron 命令

在部署弹性 beantalk 之前运行正确的脚本

AWS 弹性 beantalk 上的 postgraphile 出现 408 超时错误