如何使用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 上运行一个。