在 Elastic Beanstalk 部署后自动重启 SolR

Posted

技术标签:

【中文标题】在 Elastic Beanstalk 部署后自动重启 SolR【英文标题】:Automatic restart of SolR after Elastic Beanstalk deployment 【发布时间】:2015-09-11 21:30:25 【问题描述】:

我在 AWS 上有一个 RoR 应用程序。 我的应用程序使用 SolR 作为搜索引擎,但每次部署后,应用程序无法再次索引。所以我必须手动重置权限并重新启动 Solr:

chmod 777 -R /solr /tmp /log
RAILS_ENV=production rake sunspot:solr:stop # or I kill the processus if it doesn't work :D 
RAILS_ENV=production rake sunspot:solr:start
RAILS_ENV=production rake sunspot:reindex

现在我正在尝试将其设置为 eb 扩展以自动化部署。 这是我在 .ebextensions/deploy.config 中尝试的:

container_commands:
  1_change_permissions:
    command: chmod 700 .ebextensions/setup.sh 
  2_restart_solr:
    command: bash .ebextensions/setup.sh 

这里是 setup.sh 脚本:

#!/bin/bash
chmod 777 -R solr/ log/ tmp/
RAILS_ENV=production rake sunspot:solr:restart

结果是部署没有失败,只是权限被正确更改,solr 服务正在运行,但是当我尝试索引某些内容时,它失败了(查询工作正常)。

我还尝试通过在我的 .ebextensions/deploy.config 中添加一个 commands 块在部署应用程序之前停止服务器(并且我将我的 sh 脚本更改为启动服务而不是重新启动):

commands:
  1_stop_solr:
    command: cd /var/app/current & RAILS_ENV=production rake sunspot:solr:stop

我得到了这个错误(我不知道它是从哪里执行的):

[2015-06-25T09:51:35.510Z] 信息 [13207] - [CMD-AppDeploy/AppDeployStage0/EbExtensionPreBuild/Infra-EmbeddedPreBuild/prebuild_0_My_First_Elastic_Beanstalk_Application/Command 1_stop_solr]:活动执行失败,因为:rake 中止! 找不到 HOME 环境 -- 展开 `~'

编辑 1(根据 jay 的评论): 当我保存对象时,索引过程就完成了。

这是一个实体的示例(以及失败的地方):

class Document < ActiveRecord::Base

  # .....

  # SolR entity 
  searchable do
    text :title, :description, :tags 
    integer :user_id
  end 

  # .....

end

**编辑2:**

James 的回答并不能解决问题,但是, 我意识到在我的 EC2 实例上手动运行,我可以运行以下 2 行:

chmod 777 -R solr/ tmp/ log/
RAILS_ENV=production rake sunspot:reindex"

我尝试使用 James 的链接创建一个部署后脚本,并且 chmod 运行良好,但是当我将 reindex 命令添加到文件中时,部署失败并出现以下错误:

[2015-07-07T16:26:25.509Z] INFO  [20402] - [CMD-AppDeploy/AppDeployStage1/AppDeployPostHook/99_restart_delayed_job.sh] : Activity execution failed, because: rake aborted!
Could not find rake-10.4.2 in any of the sources 
/var/app/current/config/boot.rb:3:in `<top (required)>'
/var/app/current/config/application.rb:1:in `<top (required)>'
/var/app/current/Rakefile:4:in `<top (required)>'

另外,如果我尝试手动运行该命令(在部署后脚本 chmod 之后),它会失败并在每个要重新索引的项目上出现 500 个错误。所以我需要杀死solr服务器,启动然后重新索引。

真的很痛苦:)

【问题讨论】:

如何索引文档?使用脚本?使用 solr 的 post.jar 文件?我的猜测是索引的进程对solr的索引文件夹没有写权限。这也许可以解释为什么您可以查询(只需要读取权限)但不能索引。 我用索引示例更新了我的帖子。感谢您的帮助! 【参考方案1】:

我对 Beanstalk 一无所知,但看起来执行您的命令的 shell 没有您期望的环境变量。假设post-deployment scripts 上的这篇博文是正确的,您应该能够将您的setup.sh 脚本更改为如下内容:

 #!/usr/bin/env bash
 . /opt/elasticbeanstalk/support/envvars
 cd $EB_CONFIG_APP_CURRENT
 su -c "RAILS_ENV=production /usr/local/bin/rvm 2.2 do rake sunspot:solr:restart" $EB_CONFIG_APP_USER

【讨论】:

感谢 James 的回答,但这并不能解决我的问题。我在主帖中添加了一个 EDIT2 部分来解释我的尝试 绝对是环境问题。看起来 EB 可能正在使用 RVM?尝试更新的脚本。您可能需要使用它来获得正确的 RVM 路径和 Ruby 版本。 我不在服务器上使用 RVM。通常该命令是通过捆绑器执行的,但它也不起作用。当我深入研究时,我在 /opt/elasticbeanstalk/support/envvars 文件中看不到任何 EB_* vars 的导出。应该在里面吧?我需要手动设置吗?因为当我尝试打印变量时,它没有返回任何内容。 我认为硬编码值应该没问题。只要路径不经常更改,应该没问题。尝试编写一个带有硬编码路径的命令到bundler。看看这是否能让你走得更远。 好的,它不适用于我尝试在 /var/app/current 中 cd 并执行:su -c 与用户“ec2-user”的硬编码值。它甚至无法执行 chmod 操作。如果我尝试使用 bundle 的完整路径执行“bundle exec rake”,则会出现分段错误错误。我只用 rake 没有收到任何错误,但它什么也没做(它不手动)。【参考方案2】:

我知道这是一个老问题,但我编写了一个似乎适用于这种情况的 ebextensions 脚本。如果人们仍然遇到这个问题,希望这会有所帮助。

commands:
    000_sudo:
        command: sudo su
    001_cd_to_app:
        command: cd /var/app/current
    002_rm_solr:
        command: rm -rf solr/
    003_start_solr:
        command: bundle exec rails sunspot:solr:start RAILS_ENV=production
    004_reindex_solr:
        command: bundle exec rails sunspot:solr:reindex RAILS_ENV=production

【讨论】:

以上是关于在 Elastic Beanstalk 部署后自动重启 SolR的主要内容,如果未能解决你的问题,请参考以下文章

使用 Elastic Beanstalk 部署后在容器中运行命令

Elastic Beanstalk 未部署在所有实例上

在 Elastic Beanstalk 上部署 Rails 应用程序 - WEBrick 会自动被乘客取代吗?

超时后无法部署到 AWS Elastic Beanstalk

如何在部署到 Elastic Beanstalk 后运行 Python 脚本

Elastic Beanstalk 运行部署后脚本