简体   繁体   English

在AWS Elastic Beanstalk中使用Resque和/或Redis部署Rails

[英]Deploying Rails with Resque and/or Redis in AWS Elastic Beanstalk

I am trying to deploy my Rails app with Websockets-Rails in standalone mode, Resque, and Redis on AWS Elastic Beanstalk. 我正在尝试在独立模式,Resque和Redis上以Websockets-Rails部署我的Rails应用程序到AWS Elastic Beanstalk上。 The Ubuntu 14.04 server is running Ruby 2.2 on Puma. Ubuntu 14.04服务器在Puma上运行Ruby 2.2。

Everything works fine in development mode on Puma. 在Puma的开发模式下,一切正常。 The errors I'm getting in production on AWS Elastic Beanstalk seem to be related to Redis. 我在AWS Elastic Beanstalk上生产时遇到的错误似乎与Redis有关。

Redis::CannotConnectError (Error connecting to Redis on my.domain:6379 (ECONNREFUSED)):
  redis (3.2.0) lib/redis/client.rb:320:in `rescue in establish_connection'
  redis (3.2.0) lib/redis/client.rb:311:in `establish_connection'
  redis (3.2.0) lib/redis/client.rb:91:in `block in connect'
  redis (3.2.0) lib/redis/client.rb:273:in `with_reconnect'
  redis (3.2.0) lib/redis/client.rb:90:in `connect'
  redis (3.2.0) lib/redis/client.rb:337:in `ensure_connected'
  redis (3.2.0) lib/redis/client.rb:204:in `block in process'
  redis (3.2.0) lib/redis/client.rb:286:in `logging'
  redis (3.2.0) lib/redis/client.rb:203:in `process'
  redis (3.2.0) lib/redis/client.rb:109:in `call'
  redis (3.2.0) lib/redis.rb:1874:in `block in hget'
  redis (3.2.0) lib/redis.rb:37:in `block in synchronize'
  /opt/rubies/ruby-2.2.3/lib/ruby/2.2.0/monitor.rb:211:in `mon_synchronize'
  redis (3.2.0) lib/redis.rb:37:in `synchronize'
  redis (3.2.0) lib/redis.rb:1873:in `hget'
  redis-objects (1.2.1) lib/redis/hash_key.rb:29:in `hget'
  /opt/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/bundler/gems/websocket-rails-cf5d59b671c5/lib/websocket_rails/synchronization.rb:184:in `block in find_user'

And sometimes I get a Redis::TimeoutError (I can't seem to reproduce this anymore). 有时我会收到Redis::TimeoutError (我似乎再也无法重现)。

I've added pre appdeploy scripts for Redis and Resque: 我为Redis和Resque添加了预部署脚本:

# .ebextensions/redis_server.config
files:
  "/opt/elasticbeanstalk/hooks/appdeploy/pre/14_redis_server.sh":
    mode: "000755"
    owner: root
    group: root
    content: |
      #!/usr/bin/env bash
      . /opt/elasticbeanstalk/support/envvars
      cd $EB_CONFIG_APP_ONDECK
      su -c "leader_only redis-server" $EB_CONFIG_APP_USER ||
      echo "Redis server startup failed, skipping."
      true

# .ebextensions/resque_workers.config
files:
  "/opt/elasticbeanstalk/hooks/appdeploy/pre/16_resque_workers.sh":
    mode: "000755"
    owner: root
    group: root
    content: |
      #!/usr/bin/env bash
      . /opt/elasticbeanstalk/support/envvars
      cd $EB_CONFIG_APP_ONDECK
      su -c "leader_only TERM_CHILD=1 QUEUES=* rake environment resque:work & rake environment resque:scheduler" $EB_CONFIG_APP_USER ||
      echo "Resque initialization failed, skipping."
      true

I have a suspicion that this might be due to Redis not actually deploying, but I am not sure how to check if it is or not. 我怀疑这可能是由于Redis并未实际部署,但是我不确定如何检查它是否是由于。

What is the correct way to starting up Redis and other rake tasks like Resque upon deployment on Elastic Beanstalk? 在Elastic Beanstalk上部署时,启动Redis和其他rake任务(如Resque)的正确方法是什么?

Another possible issue is using websockets with Redis. 另一个可能的问题是将Websockets与Redis一起使用。 I've read somewhere that I need to modify nginx.conf and its Upgrade header tag to permit Websockets, but I'm not sure if this is the direct cause of this problem. 我读过某个地方,我需要修改nginx.conf及其Upgrade标头标签以允许Websocket,但是我不确定这是否是导致此问题的直接原因。

EDIT: 编辑:

Redis is now running on Elasticache. Redis现在在Elasticache上运行。 I'm not getting any Redis connection errors anymore, but Resque and Websockets doesn't seem to be working. 我再也没有收到任何Redis连接错误,但是Resque和Websockets似乎不起作用。 I don't think it's Redis that's causing the issue, but probably isolated issues with Resque and Websockets. 我认为不是Redis引起了问题,但可能与Resque和Websockets无关。

I tried using a monit script to ensure Resque scheduler and workers persist: 我尝试使用监控脚本来确保Resque调度程序和工作程序持久存在:

packages:
  yum:
    monit: []

files:
  "/etc/monit.d/resque_worker":
    mode: "000644"
    owner: root
    group: root
    content: |
      check process resque_worker_QUEUE
        with pidfile /var/app/resque_worker_QUEUE.pid
        start program = "/bin/sh -l -c 'cd /var/app/current; nohup rake environment resque:scheduler PIDFILE=/var/app/resque_scheduler.pid >> log/resque_scheduler.log 2>&1' && nohup rake nohup rake environment resque:work TERM_CHILD=1 QUEUE=* VERBOSE=1 PIDFILE=/var/app/resque_worker_QUEUE.pid >> log/resque_worker_QUEUE.log 2>&1'" as uid webapp and gid webapp
        stop program = "/bin/sh -c 'cd /var/app/current && kill -9 $(cat tmp/pids/resque_scheduler.pid) && rm -f /var/app/resque_scheduler.pid && kill -9 $(cat tmp/pids/resque_worker_QUEUE.pid) && rm -f /var/app/resque_worker_QUEUE.pid; exit 0;'"
        if totalmem is greater than 300 MB for 10 cycles then restart  # eating up memory?
        group resque_workers

commands:
  remove_bak:
    command: "rm /etc/monit.d/resque_worker.bak"
    ignoreErrors: true

service:
  sysvinit:
    monit:
      ensureRunning: true
      enabled: true

Which doesn't seem to be working. 哪个似乎不起作用。

It works in development since I run the commands manually and instance aren't destroyed. 由于我手动运行命令且实例未销毁,因此它在开发中有效。

I also need to persist a standalone server for Websockets (I'm using the gem 'Websocket-Rails') on port 3001. 我还需要在端口3001上保留用于Websockets的独立服务器(我正在使用gem'Websocket-Rails')。

I don't think it is a good idea to run a queue process within an Elastic Beanstalk web environment. 我认为在Elastic Beanstalk Web环境中运行队列进程不是一个好主意。 I think it makes more sense to use a vanilla EC2 instance to host the queue process. 我认为使用香草EC2实例托管队列过程更有意义。 However, you can also use Amazon Simple Queue Service (SQS) instead of Resque. 但是,您也可以使用Amazon Simple Queue Service(SQS)代替Resque。 Then you don't have to monitor and maintain the queue instance and have a very scalable solution. 这样,您就不必监视和维护队列实例,并且拥有一个非常可扩展的解决方案。

If you use Resque to coordinate background jobs in a Rails >= 4.2 application, then have a look at the Active Elastic Job gem. 如果您使用Resque协调Rails> = 4.2应用程序中的后台作业,请查看Active Elastic Job gem。 It might solve your problem in an elegant way. 它可以用一种优雅的方式解决您的问题。

Disclaimer: I'm the author of Active Elastic Job . 免责声明:我是Active Elastic Job的作者。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM