2012-02-03 61 views
0

我有一个JRuby/Rails web应用程序。我使用rbenv和JRuby在本地进行测试(使用“rails server”),并且它工作正常。 我还将生产版本作为WAR文件分发并在Tomcat中运行,并且该机器没有安装JRuby。有用。 我现在需要能够使用Resque和Redis来处理长时间运行的作业。我在本地安装Resque/Redis的和命令行运行Resque 作为如何在没有安装JRuby并仅使用Java的JRuby/Tomcat deploymet中使用Resque应用运行Ruby/Rails?

linux> "QUEUE=* bundle exec rake environment resque:work 

它的工作原理。我创建了一个小工人类(FooClass)刚刚打印出的参数,由Resque, 打来电话,我可以通过运行

irb(main):041:0>Resque.enqueue(FooWorker, [1,"4"]) 
在Rails的控制台

入队的请求,并Resque最终处理请求并打印[1,“4”]

我想能够在Tomcat/Java环境(没有安装JRuby)中运行此Resque Rake任务, ,我有3个选项可以运行Resque耙任务。

  1. 在Tomcat中运行它,但在单独的Java线程中运行。我宁愿不这样做,因为我希望能够杀死工作进程并重新启动它。
  2. 从命令行运行它,并在启动时通过etc/init.d调用该命令。
  3. 从Web应用程序的单独Tomcat运行它。

我莺配置使得下列文件存在于应用程序WAR文件,并获得爆炸到的webapps/WEB-INF 出来的webapps/ABC/WEB-INF当Tomcat启动应用程序。

Gemfile 
Rakefile 
web.xml 
lib/jruby-core-1.6.4.jar 
lib/jruby-rack-1.0.10.jar 
lib/jruby-stdlib-1.6.4.jar 
lib/tasks/abc.rake 
lib/tasks/resque.rake 
gems/gems/bundler-1.0.21 
gems/gems/warbler-1.3.2 
gems/gems/rails-3.0.10 
(other gem files in gems/gems) 
config/warble.rb 

文件的config/warble.rb看起来是这样的:

Warble::Config.new do |config| 
    config.dirs=%w{app config lib lob vendor tmp} 
    config.includes=FileList["./Rakefile"] 
    config.webxml.jruby.compat.version = "1.9"  
end 

,将文件lib /任务/ resque.rake有

require "resque/tasks" 
task "resque:setup" => :environment 
task "resque:work" => :environment 

我的Gemfile包括下面几行:

source 'http://rubygems.org' 
gem 'bundler', '1.0.21' 
gem 'rails', '3.0.10' 
gem 'rake', '0.8.7' 
gem 'resque' 

在网上搜索产生运行Rake任务(从WEB-INF /内)通过以下方式,而不使用JRuby:

linux> java -cp lib/jruby-core-1.6.4.jar -S rake 

的结果

Unrecognized option: -S 
Could not create the Java virtual machine 

只是为了好玩,我试图

linux> java -jar lib/jruby-core-1.6.4.jar -S rake 

结果是

jruby: No such file or directory -- rake (LoadError) 

然后我尝试下载jruby-complete-1.6。4到那个目录,我跑

linux> java -jar lib/jruby-complete-1.6.4.jar -S rake -T 
(in /WEB-INF) 
rake aborted! 
no such file to load -- bundler/setup 
/WEB-INF/Rakefile:4:in `(root)' 

在这一点上,我在一个完整的损失。如何在Java/Tomcat或Java环境中运行我所需的Resque Rake任务,而无需在该服务器上安装JRuby?

回答

0

所以,你需要做的基本事情是编写一个小的shell脚本,并从解压后的war文件的WEB-INF目录中运行它。

  1. 确保您拥有此脚本以及Rakefile以及包含在war文件中的任何其他支持脚本(例如db/migrations)。
  2. 脚本看起来应该像下面这样:
 
#!/bin/bash 
# 
# Put in WEB-INF/; call this rake.sh or whatever you prefer. 

dir=$(dirname $0) 

# Put all jar files in the classpath 
for jar in $dir/*; do 
    CLASSPATH="$jar:$CLASSPATH" 
done 

# You might need to adjust Java memory settings; currently JRuby sets 512m by default 
JAVA_OPTS=-Xmx512m 

# Set up GEM_HOME and GEM_PATH 
GEM_HOME=$dir/gems 
GEM_PATH=$GEM_HOME 

export CLASSPATH GEM_HOME GEM_PATH 

java $JAVA_OPTS org.jruby.Main -S rake [email protected] 
1

或者您可以在守护线程使用https://github.com/kares/jruby-rack-worker您的应用程序(而不是单独的耙进程)运行Resque。

只需要配置莺(或您的的Gemfile),包括JRuby的架工宝石(或者你也可以下载.jar和告诉莺它放置在您的WEB-INF/lib目录),并设置部署描述符中的Resque。用莺创建config/web.xml.erb文件并在其中放置以下代码:

<!DOCTYPE web-app PUBLIC 
    "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" 
    "http://java.sun.com/dtd/web-app_2_3.dtd"> 
<web-app> 
<% webxml.context_params.each do |k,v| %> 
    <context-param> 
    <param-name><%= k %></param-name> 
    <param-value><%= v %></param-value> 
    </context-param> 
<% end %> 

    <filter> 
    <filter-name>RackFilter</filter-name> 
    <filter-class>org.jruby.rack.RackFilter</filter-class> 
    </filter> 
    <filter-mapping> 
    <filter-name>RackFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
    </filter-mapping> 

    <listener> 
    <listener-class><%= webxml.servlet_context_listener %></listener-class> 
    </listener> 

<% if webxml.jndi then [webxml.jndi].flatten.each do |jndi| %> 
    <resource-ref> 
    <res-ref-name><%= jndi %></res-ref-name> 
    <res-type>javax.sql.DataSource</res-type> 
    <res-auth>Container</res-auth> 
    </resource-ref> 
<% end; end %> 

    <!-- jruby-rack-worker setup using the built-in libraries support : --> 

    <context-param> 
    <param-name>jruby.worker</param-name> 
    <param-value>resque</param-value> 
    </context-param> 

    <listener> 
    <listener-class>org.kares.jruby.rack.WorkerContextListener</listener-class> 
    </listener> 

</web-app> 
相关问题