如何使用JRuby在ApacheTomcat7和Ubuntu14.04上运行Rails应用程序
介绍
Ruby on Rails (RoR) 是一个非常流行的框架,它使开发人员能够快速创建符合现代设计模式的 Web 应用程序。 使用 Rails,只需几个命令,您就可以构建一个生产就绪的 vanilla CRUD(创建、读取、更新、删除)应用程序,而无需编写任何代码。 Apache Phusion Passenger、Unicorn 和 Puma 是一些用于运行 Rails 应用程序的流行服务器。
多年来,Ruby MRI 的性能有了显着提高。 但是,与 Java 或 C 等语言相比,它仍然很慢。 如果您对更快的写入时间感兴趣,这是关键、并发、分布式和企业级应用程序所必需的,您应该改用 JRuby,它是 Ruby 的 Java 实现。
JRuby 相对于 Ruby MRI 的一些优势
Concurrency — Ruby MRI 使用 GIL(全局解释器锁),因此并发性有限。 另一方面,JRuby 能够使用 JVM 的线程,允许您实现更高级别的并发性。 这通常是选择 JRuby 而不是其他 Ruby 的最重要原因。
线程安全 — Ruby 的大多数核心类都不是线程安全的。 在多线程应用程序中使用此类类很容易出错。 JRuby 能够改为使用 Java 的类,这些类是为并行处理而设计的。
更多库 — 当您使用 JRuby 时,您不仅可以使用 Ruby gems,还可以使用所有 Java 和 Scala 库。 这使您可以更专注于应用程序的核心功能。
易于部署 — 可以将 JRuby on Rails 应用程序打包到单个 WAR 文件中,该文件可以轻松部署到任何 Java EE 服务器。 他们中的许多甚至具有基于浏览器的界面来管理应用程序。
本教程涵盖的内容
在本教程中,您将学习:
- 使用 Rails 创建一个简单的 CRUD 应用程序(使用 Ruby MRI 的应用程序)
- 将我们的 Ruby on Rails 应用程序转换为 JRuby on Rails 应用程序
- 为应用程序生成 WAR 文件
- 安装 Apache Tomcat 7
- 将 WAR 文件部署到 Tomcat 服务器
在本教程结束时,您将部署一个可工作的 JRuby on Rails 应用程序。
先决条件
- 部署 32 位 Ubuntu 14.04 Droplet。 Tomcat 和 JRuby 将在 64 位服务器上运行,但可能会更慢。
- 创建一个 sudo 用户。
- 如果您的 Droplet 的 RAM 小于 2 GB,则应添加至少 1 GB 的交换空间。 有关详细信息,请参阅以下教程:如何在 Ubuntu 14.04 上添加交换。
- 在您的机器上安装最新版本的 RVM。 请参阅以下教程的第一步:如何在 Ubuntu 12.04 LTS (Precise Pangolin) 上使用 RVM 安装 Ruby on Rails。 在安装 RVM 之前,您可能需要添加密钥:
gpg --keyserver hkp://keys.gnupg.net --recv-keys D39DC0E3
通过 rvm requirements 命令按照该教程进行操作。
第 1 步 — 创建一个简单的 CRUD RoR 应用程序
初始化 RVM。 对于您打开的每个新终端,此初始化都是必需的。
. ~/.rvm/scripts/rvm
注意:如果您已经有一个使用 Ruby 1.9.3 的 Rails 应用程序,您现在可以跳到第 2 步。
创建一个目录来存放所有 Rails 应用程序,然后输入该目录。
mkdir ~/my_applications cd ~/my_applications
我们在本教程中使用 Ruby 1.9.3,因为这是 JRuby 支持的最新版本的 Ruby。
rvm install 1.9.3 rvm use 1.9.3
安装导轨。
gem install rails -N
创建一个名为 simple 的新 Rails 应用程序。
rails new simple
输入应用程序的目录。
cd ~/my_applications/simple
使用 nano 编辑 Gemfile 并取消注释 gem therubyracer 的行。 必须添加这个 gem,因为我们的 Rails 应用程序需要一个 JavaScript 运行时。
nano ~/my_applications/simple/Gemfile
忽略评论,您更新的文件应如下所示:
source 'https://rubygems.org' gem 'rails', '4.1.7' gem 'sqlite3' gem 'sass-rails', '~> 4.0.3' gem 'uglifier', '>= 1.3.0' gem 'coffee-rails', '~> 4.0.0' gem 'therubyracer' gem 'jquery-rails' gem 'turbolinks' gem 'jbuilder', '~> 2.0' gem 'sdoc', '~> 0.4.0', group: :doc gem 'spring', group: :development
您需要删除注释的 therubyracer
行的 , platforms: :ruby
部分,因为最终我们将使用 JRuby 而不是 Ruby。
安装 Gemfile 中列出的所有 gem。
bundle install
使用 Rails 的脚手架功能向应用程序添加一些页面。
rails g scaffold Employee name:string age:integer address:text
rails g scaffold
命令会生成一些迁移。 应用它们:
rake db:migrate
更改应用程序的根以显示所有员工的列表。 使用 nano 编辑 ~/my_applications/simple/config/routes.rb
并将其内容更改为如下所示,减去注释:
Rails.application.routes.draw do resources :employees root 'employees#index' end
使用 Ruby MRI 的 Rails 应用程序现已准备就绪。 通过键入以下内容在开发服务器上运行它:
rails s
这将需要一两分钟才能启动。
您可以通过访问在浏览器中访问该应用程序 http:// :3000 . 创建几条记录以确保一切都按预期工作。
返回控制台,按 Ctrl+C 停止服务器。
第 2 步 — 安装 Java 8
为了安装和使用 JRuby,需要一个 JDK。 添加 webupd8team/java
PPA 后,可以使用 apt-get 安装 Oracle JDK 8。
通过键入以下内容添加存储库:
sudo add-apt-repository ppa:webupd8team/java
按 Enter 接受新的存储库。
更新 apt-get 的包索引文件。
sudo apt-get update
安装 Oracle JDK 8。
sudo apt-get install oracle-java8-installer
注意:在实际安装开始之前,系统会提示您接受许可协议。
选择'并按下进入 ,然后选择'并按下进入 .
安装完成后,运行命令:
java -version
您应该能够看到以下输出,这意味着 Java 已正确安装:
java version "1.8.0_25" Java(TM) SE Runtime Environment (build 1.8.0_25-b17) Java HotSpot(TM) Client VM (build 25.25-b02, mixed mode)
第 3 步 — 安装 JRuby 和 JRuby on Rails
使用 RVM 安装和使用 JRuby。
rvm install jruby rvm use jruby
最新版本的 JRuby(截至 2014 年 11 月的 1.7.16.1)现在可以使用了。 检查版本:
jruby -v
这表明您的服务器正在使用 Oracle JDK 8。 您应该会看到与此类似的输出:
jruby 1.7.16.1 (1.9.3p392) 2014-10-28 4e93f31 on Java HotSpot(TM) Client VM 1.8.0_25-b17 +jit [linux-i386]
在 Rails 上安装 JRuby。
gem install rails -N
现在已安装 JRuby on Rails。
第 4 步 — 配置应用程序以使用 JRuby
虽然 JRuby 无缝支持许多 Ruby MRI gem,但一些具有本机代码的 gem 却不支持。 大多数作为数据库接口的 gem 都属于这一类。 我们的应用程序当前使用 JRuby 不支持的 sqlite3 gem。 activerecord-jdbcsqlite3-adapter 应该被使用。
同样,JRuby 使用 therubyrhino 而不是 therubyracer gem 作为 JavaScript 引擎。
使用 nano 编辑 ~/my_applications/simple/Gemfile
以进行此更改。
nano ~/my_applications/simple/Gemfile
更新两行后,您的文件应如下所示,减去注释:
source 'https://rubygems.org' gem 'rails', '4.1.7' gem 'activerecord-jdbcsqlite3-adapter' gem 'sass-rails', '~> 4.0.3' gem 'uglifier', '>= 1.3.0' gem 'coffee-rails', '~> 4.0.0' gem 'therubyrhino' gem 'jquery-rails' gem 'turbolinks' gem 'jbuilder', '~> 2.0' gem 'sdoc', '~> 0.4.0', group: :doc gem 'spring', group: :development
如果您以前没有,现在您需要从 therrubyrhino 行中删除 platform
设置。
我们的一些 gem 需要原生扩展。 键入以下内容以允许 JRuby 支持 C 扩展。
echo "cext.enabled=true" >> ~/.jrubyrc
您现在可以安装新添加的 gem。
bundle install
如果您不使用 SQLite3 作为数据库,则可能需要以下 gem 之一:
- 对于德比:activerecord-jdbcderby-adapter
- 对于 MySQL:activerecord-jdbcmysql-adapter
- 对于 Postgres:activerecord-jdbcpostgresql-adapter
第 5 步 — 更新 Java 的策略文件
使用浏览器下载 JCE Unlimited Strength Jurisdiction 政策文件。 您必须首先接受 Oracle 的许可协议。
(您不能 wget 文件,因为您必须接受协议。)
在您的 本地计算机 上,使用 scp 将文件上传到您的服务器:
scp Downloads/jce_policy-8.zip user@server-ip:~
在您的 服务器 上,安装解压缩实用程序:
sudo apt-get install unzip
将文件解压到 /tmp 的目录中。
cd /tmp unzip ~/jce_policy-8.zip
将策略文件复制到 JRE 的 lib/security 目录。
cd /tmp/UnlimitedJCEPolicyJDK8 sudo cp *.jar /usr/lib/jvm/java-8-oracle/jre/lib/security/
返回到应用程序的目录。
cd ~/my_applications/simple
执行以下命令加快 JVM 启动。 这是必要的,因为虚拟服务器环境往往会自行生成非常少的随机性。
export JAVA_OPTS="-Djava.security.egd=file:/dev/./urandom"
至此,我们的 Rails 应用程序已完全配置为使用 JRuby。 启动开发服务器:
rails s
此服务器可能需要几秒钟才能启动。 等到看到以下输出后再继续:
=> Booting WEBrick => Rails 4.1.7 application starting in development on http://0.0.0.0:3000 => Run `rails server -h` for more startup options => Notice: server is listening on all interfaces (0.0.0.0). Consider using 127.0.0.1 (--binding option) => Ctrl-C to shutdown server [2014-11-06 04:38:15] INFO WEBrick 1.3.1 [2014-11-06 04:38:15] INFO ruby 1.9.3 (2014-09-25) [java] [2014-11-06 04:38:15] INFO WEBrick::HTTPServer#start: pid=2620 port=3000
使用浏览器访问 http:// :3000 并测试您的应用程序。 除了它当前运行在 JVM 上而不是使用 Ruby MRI 之外,您应该会发现该应用程序没有什么不同。
返回终端并按 Ctrl+C 停止服务器。
第 6 步 — 将应用程序打包为可部署的 WAR 文件
要在 Tomcat 等 servlet 容器上运行 JRuby on Rails 应用程序,首先应将其打包到 WAR(Web 应用程序归档)文件中。 这可以使用 warbler gem 来完成。
安装 莺。
gem install warbler
我们的应用程序使用的 SQLite 数据库当前存在于应用程序的目录中。 当 WAR 文件生成时,当前状态的数据库将被放置在 WAR 文件中。 我们不希望这样,因为如果重新部署应用程序,部署后对数据库所做的任何更改都将被覆盖。
因此,应该将 SQLite 数据库文件移动到应用程序目录之外的位置。
为数据库创建一个新目录:
mkdir -p ~/databases/simple
在本教程中,我们只关注开发数据库。 因此,将开发数据库文件移动到新创建的目录:
mv ~/my_applications/simple/db/development.sqlite3 ~/databases/simple
使用 nano 编辑 database.yml 文件。
nano ~/my_applications/simple/config/database.yml
更新开发数据库的路径。 您还可以删除其他环境的详细信息,因为本教程不需要它们。 更改后,您的文件应如下所示:
default: &default adapter: sqlite3 pool: 5 timeout: 5000 development: <<: *default database: ~/databases/simple/development.sqlite3
Warbler 还需要了解 WAR 的 Rails 环境。 在本教程中,我们坚持使用 开发 环境。 这是使用 config/warble.rb
文件指定的。
使用 nano 创建一个名为 warble.rb 的新文件
nano ~/my_applications/simple/config/warble.rb
将以下内容添加到文件中:
Warbler::Config.new do |config| config.webxml.rails.env = 'development' end
我们的应用程序现在可以打包到 WAR 文件中了。 运行以下命令生成文件:
warble executable war
这将需要一些时间。
成功的输出应如下所示:
Downloading winstone-0.9.10-jenkins-43.jar rm -f simple.war Creating simple.war
此时,您的应用程序目录中将有一个名为 simple.war 的文件。 将参数 executable 添加到命令会生成一个 WAR 文件,其中包含一个微型嵌入式服务器(称为 Winstone)。 该文件可以独立使用(无需任何外部服务器),如下所示:
java -jar simple.war
这是检查 WAR 文件是否存在任何问题的好方法。 您现在可以使用浏览器访问 http:// :8080 . 几分钟后,您应该能够看到您的应用程序正常工作。 您之前在数据库应用程序中创建的所有条目都应该在此处可见。
您应该等到看到类似于以下的输出,让您知道服务器已启动:
Nov 13, 2014 12:24:37 PM winstone.Logger logInternal INFO: Started GET "/assets/application.js?body=1" for 108.29.37.206 at 2014-11-13 12:24:37 -0500
返回终端,按Ctrl+C停止嵌入式服务器。
现在您已经确认应用程序作为 WAR 运行,使用以下命令为 Tomcat 生成一个新的 WAR:
warble war
它将用没有任何嵌入式服务器的新 WAR 文件替换旧的可执行 WAR。
第 7 步 — 安装并启动 Tomcat
下载最新版本的 Tomcat。
cd ~ wget http://mirror.cc.columbia.edu/pub/software/apache/tomcat/tomcat-7/v7.0.56/bin/apache-tomcat-7.0.56.tar.gz
为 Tomcat 创建一个新目录并输入该目录。
mkdir ~/Tomcat cd ~/Tomcat
提取存档:
tar -xvzf ~/apache-tomcat-7.0.56.tar.gz
将 Tomcat 可用的最大堆大小设置为 512m 以避免出现 java.lang.OutOfMemoryError
。 每次启动 Tomcat 服务器时都必须执行此导出。
export CATALINA_OPTS="-Xmx512m"
和以前一样,设置随机生成:
export JAVA_OPTS="-Djava.security.egd=file:/dev/./urandom"
启动Tomcat:
~/Tomcat/apache-tomcat-7.0.56/bin/catalina.sh start
该服务器也需要几秒钟才能启动。 要监控其日志,请输入:
tail -f ~/Tomcat/apache-tomcat-7.0.56/logs/catalina.out
服务器准备就绪后,您将看到如下日志消息:
Nov 10, 2014 4:12:32 AM org.apache.catalina.startup.HostConfig deployDirectory INFO: Deployment of web application directory ~/Tomcat/apache-tomcat-7.0.56/webapps/manager has finished in 210 ms Nov 10, 2014 4:12:32 AM org.apache.coyote.AbstractProtocol start INFO: Starting ProtocolHandler ["http-bio-8080"] Nov 10, 2014 4:12:32 AM org.apache.coyote.AbstractProtocol start INFO: Starting ProtocolHandler ["ajp-bio-8009"] Nov 10, 2014 4:12:32 AM org.apache.catalina.startup.Catalina start INFO: Server startup in 3390 ms
按 Ctrl+C 结束 tail 命令。
Tomcat 现在已安装并正在运行。 您可以使用浏览器访问 http:// :8080 . 您应该能够看到 Tomcat 的欢迎页面。
第 8 步 — 将应用程序部署到 Tomcat
要将 WAR 部署到 Tomcat,您只需将其复制到 Tomcat 的 webapps 文件夹即可。
cp ~/my_applications/simple/simple.war ~/Tomcat/apache-tomcat-7.0.56/webapps
自动部署您的应用程序可能需要一分钟左右的时间。 在等待期间,您可以使用以下命令监视 Tomcat 日志文件的内容:
tail -f ~/Tomcat/apache-tomcat-7.0.56/logs/catalina.out
当您的应用程序准备好使用时,您将看到如下日志消息:
INFO: Deploying web application archive ~/Tomcat/apache-tomcat-7.0.56/webapps/simple.war Oct 30, 2014 4:42:35 AM org.apache.catalina.startup.HostConfig deployWAR INFO: Deployment of web application archive ~/Tomcat/apache-tomcat-7.0.56/webapps/simple.war has finished in 47,131 ms
按 Ctrl+C 结束 tail
命令。
您现在可以使用浏览器访问 http:// :8080/简单/ 并查看在 Tomcat 上运行的 JRuby on Rails 应用程序。
重新开始您的会话
如果您在任何时候断开您的 SSH 会话,您应该运行以下三个命令:
cd ~/my_applications/simple . ~/.rvm/scripts/rvm rvm use jruby
如果需要重启Tomcat,运行前面三个命令,并确保在启动服务器之前设置好两个环境变量:
export CATALINA_OPTS="-Xmx512m" export JAVA_OPTS="-Djava.security.egd=file:/dev/./urandom" ~/Tomcat/apache-tomcat-7.0.56/bin/catalina.sh start
结论
因此,只需更改一些配置,Ruby on Rails 应用程序就可以转换为 JRuby on Rails 应用程序。 JRuby on Rails 应用程序可以在几乎所有 servlet 容器上运行。 在本教程中,您已经了解了如何在 Apache Tomcat 和 Winstone 上运行一个。