如何跨多个Droplet扩展RubyonRails应用程序(第1部分)
介绍
恭喜顺理成章。 您的网站正在获得关注,并且您正在迅速成长。 Ruby 是您选择的编程语言和 Rails 吗? 你的首选框架。现在你正在收获你的努力的好处,并通过你的精彩应用分享你快乐的客户的喜悦。
然而,面对新的挑战,您开始担心:容纳不断增加的客人(即 缩放)。
尽管在这个主题上存在争议,即使您正在运行一个非常繁忙的网站(由 Ruby 和 Rails 提供支持),您也可以继续及时地为您的客户提供服务。 实现这一点的关键是通过扩展您的应用程序,或者换句话说,将其负载分布在多个液滴上,这些液滴旨在处理这些精确的任务,仅此而已。
在这篇 DigitalOcean 文章中,我们将了解如何简单地水平扩展 Ruby on Rails 应用程序,将其负载分布在运行在 Unicorn 上的多台机器上,所有这些都在运行 Nginx HTTP 服务器的主负载均衡器后面精心设置,负责欢迎和处理传入的请求并平衡负载。
本教程涵盖将您的应用程序分发到多个服务器。 但是,为了完全部署您的应用程序,您需要使用数据库对其进行设置。 这些系列的下一篇文章将介绍将您的服务器连接到 MySQL 或 PostgreSQL 数据库。
词汇表
1. 可扩展的应用程序部署
- 独角兽应用服务器
- Nginx HTTP 服务器 / 反向代理 / 负载均衡器
- 我们的部署准备过程
- 最终架构
2. 准备服务器和操作系统
3. 设置应用程序服务器
- 设置 Ruby 环境
- 设置 Rails
- 安装独角兽
- 创建示例 Rails 应用程序
- 配置独角兽
- 运行独角兽
- 查找服务器的 IP 地址来配置 Nginx
4. 将 Nginx 设置为反向代理和负载均衡器
- 设置 Nginx
- 配置 Nginx
可扩展的应用程序部署
部署应用程序,或在线发布它们, 技术上 意味着不同的东西,并且过程本身可以发生在不同的级别。 之前,我们已经介绍了部署 Rails 应用程序的多种方法,使用不同的服务器(即 Unicorn 和Passenger),甚至看到了如何使用不同的工具来自动化流程(例如 卡皮斯特拉诺和米娜)。
为了拥有一个 [简单] 可扩展的架构,我们将把我们的部署结构分为两个主要元素:
- 应用服务器(独角兽/Rails)
- 前端 HTTP 服务器/负载均衡器 (Nginx)
我们偏爱 Unicorn 应用服务器的主要原因是它的高级功能和简单的实现和维护方式。
非常流行的 Nginx HTTP 服务器和反向代理将成为我们的负载均衡器,其任务是在基于 Unicorn 的应用程序服务器之间分配负载。
因此,我们将分别介绍两个不同的领域。
- 准备(和部署)运行 Unicorn 的 Rails 应用程序服务器。
- 准备一个基于 Nginx 的前端负载平衡反向代理,以在 Unicorn 之间分配负载。
与我们之前的手册和文章类似,我们将继续使用最新可用版本的 CentOS 操作系统来进行设计选择,这完全符合我们简单和稳定的目标。
注意: 当您阅读本文时,您会看到其他人的链接,这些链接会更深入地讨论某些主题。 如果您想了解更多关于它们的信息,请考虑查看它们。
独角兽应用服务器
Unicorn 是一个非凡的应用服务器,它包含用于处理传入请求的 Rails 应用程序。 这些应用程序服务器将只处理需要处理的请求,在它们被前端 Nginx 服务器过滤和预处理后,作为负载均衡器工作。
Unicorn 作为一款非常成熟的 Web 应用服务器,功能绝对齐全。 它通过设计拒绝尝试做所有事情,只处理需要由 Web 应用程序完成的事情,并将其余职责委托给操作系统(即 杂耍过程)。
Unicorn 的 master 进程产生 workers 来服务请求。 此过程还监视工作人员,以防止与内存和进程相关的惊人问题。 这对系统管理员来说意味着它会杀死一个进程,例如,如果它最终花费了太多时间来完成一项任务或发生内存问题。
注意: 要了解不同的 Ruby Web 应用程序服务器并了解 Rack 是什么,请查看我们的文章 A Comparison of (Rack) Web Servers for Ruby Web Applications ]。
Nginx HTTP 服务器 / 反向代理 / 负载均衡器
Nginx HTTP 服务器,从一开始就被设计成一个多用途、面向前端的 Web 服务器。 它能够提供静态文件(例如 图片,文本文件等)非常好,平衡连接并处理某些漏洞尝试。 它将作为所有请求的第一个入口点,并将它们分发给运行 Unicorn 的 Web 应用程序服务器进行处理。
我们的部署准备过程
从下一节开始,我们将执行以下过程来准备我们的分布式负载平衡应用程序部署设置。
- 更新操作系统 [*]
- 获取部署所需的基本工具 [*]
- 安装 Ruby、Rails 和库
- 安装应用程序(即 Unicorn) 和 HTTP 服务器 (Nginx)
- 配置 Nginx 以在 TCP 上分配负载
注意: 列表中标记的项目是需要在所有配置的服务器上执行的过程,无论它们被指定为应用程序服务器还是负载平衡器。
最终架构
下面是我们的最终架构的示例,用于在液滴之间分配负载和水平扩展。
Client Request ----> Nginx (Reverse-Proxy / Load-Balancer) | /|\ | | `-> App. Server I. 10.128.xxx.yy1:8080 # Our example | `--> App. Server II. 10.128.xxx.yy2:8080 `----> ..
准备服务器和操作系统
我们将开始创建我们的设置,准备所有将运行 Unicorn 或 Nginx 的服务器。
为了安装 Ruby 和其他必要的应用程序(例如 我们的服务器),我们首先需要准备最小化的 CentOS droplet,并为它配备一些我们需要的开发工具。
运行以下命令来更新基于 CentOS 的 droplet 的默认工具:
yum -y update
通过执行以下命令安装包含多个开发工具的应用程序包:
yum groupinstall -y 'development tools'
本教程需要的一些包(例如 libyaml-devel、nginx 等)在 CentOS 官方存储库中是 not。 为了简化事情而不是手动安装它们,我们将添加 EPEL 软件存储库供 YUM 包管理器使用。
# Enable EPEL Repository sudo su -c 'rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm' # Update everything, once more. yum -y update
最后,我们需要得到 curl-devel
以及本教程的其他几个工具和库(例如 Rails 需要 sqlite-devel)。
为了安装它们,运行以下命令:
yum install -y curl-devel nano sqlite-devel libyaml-devel
设置应用程序服务器
在这一步中,我们将准备运行 Rails on Unicorn 应用服务器的服务器。
让我们从准备 Ruby 和 Rails 开始。
设置 Ruby 环境
注意:本节是我们专门文章如何在CentOS 6.5上安装Ruby 2.1.0的摘要。
注意: 您需要在所有应用程序服务器上执行上一节中的说明以及以下说明。 至少,您需要 一个 应用程序服务器来部署您的应用程序。 为了平衡负载,提供更多液滴并重复这些步骤。
我们将使用 Ruby Version Manager (RVM) 下载并安装 Ruby 解释器。
运行以下两条命令安装 RVM 并为 Ruby 创建系统环境:
curl -L get.rvm.io | bash -s stable source /etc/profile.d/rvm.sh
最后,为了在我们的系统上完成 Ruby 的安装,让我们让 RVM 下载并安装 Ruby 版本 2.1.0:
rvm reload rvm install 2.1.0
设置 Rails
因为 Rails 首先需要一个 JavaScript 解释器才能工作,所以我们还需要设置 Node.js
。 为此,我们将使用默认的系统包管理器 YUM。
运行以下命令以使用 yum 下载并安装 nodejs
:
yum install -y nodejs
使用gem执行以下命令下载并安装rails
:
gem install bundler rails
安装独角兽
有几种方法可以轻松下载 Unicorn。 既然是应用相关的依赖,最合乎逻辑的方式就是使用RubyGems。
运行以下命令以使用 gem
下载并安装 Unicorn:
gem install unicorn
注意: 我们将在下一节中了解如何使用此工具。
创建示例 Rails 应用程序
注意: 为了让我们的示例正常工作,我们现在将创建一个基本的 Rails 应用程序。 为了运行您的,您需要上传您的应用程序源代码。
上传您的源代码
对于实际部署,您当然希望将代码库上传到服务器。 为此,您可以使用 SFTP 或 FileZilla 等图形工具来安全地传输和管理远程文件。 同样,您可以使用 Git 和 Github 等中央存储库来下载和设置您的代码。
- 要了解如何使用 SFTP,请查看文章:如何使用 SFTP。
* 要了解 FileZilla,请查看有关该主题的文章:如何使用 FileZilla。
让我们从在我们的主目录中创建一个非常基本的 Rails 应用程序开始,以便为 Unicorn 服务。
执行以下命令让 Rails 创建一个名为 my_app 的新应用程序:
# Create a sample Rails application cd /var mkdir www cd www rails new my_app # Enter the application directory cd my_app # Create a sample resource rails generate scaffold Task title:string note:text # Create a sample database RAILS_ENV=development rake db:migrate RAILS_ENV=production rake db:migrate # Create a directory to hold the PID files mkdir pids
要测试您的应用程序是否设置正确并且一切正常,请进入应用程序目录并使用 rails s
运行一个简单的服务器:
# Enter the application directory cd /var/www/my_app # Run a simple server rails s # You should now be able to access it by # visiting: http://[your droplet's IP]:3000/tasks # In order to terminate the server process, # Press CTRL+C
配置独角兽
Unicorn 可以通过多种方式进行配置。 对于本教程,重点关注关键元素,我们将从头开始创建一个文件,Unicorn 在启动应用程序服务器守护进程时将使用该文件。
使用 nano
文本编辑器打开一个空白的 unicorn.rb
文档,该文档将保存在 config/
目录中:
nano config/unicorn.rb
放置以下代码块,根据需要进行修改:
# Set the working application directory # working_directory "/path/to/your/app" working_directory "/var/www/my_app" # Unicorn PID file location # pid "/path/to/pids/unicorn.pid" pid "/var/www/my_app/pids/unicorn.pid" # Path to logs # stderr_path "/path/to/log/unicorn.log" # stdout_path "/path/to/log/unicorn.log" stderr_path "/var/www/my_app/log/unicorn.log" stdout_path "/var/www/my_app/log/unicorn.log" # Number of processes # Rule of thumb: 2x per CPU core available # worker_processes 4 worker_processes 2 # Time-out timeout 30
按 CTRL+X 并用 Y 确认保存并退出。
注意: 要简单地使用 Unicorn 测试您的应用程序,您可以在应用程序目录中运行 unicorn_rails
。
注意:要了解更多关于配置独角兽的信息,请查看其官方文档页面这里。
运行独角兽
我们已准备好使用 Unicorn 运行我们的应用程序。
使用我们的配置文件 (config/unicorn.rb
) 运行以下命令以守护程序模式启动 Unicorn:
unicorn_rails -c config/unicorn.rb -D
查找服务器的 IP 地址来配置 Nginx
让我们找到我们的虚拟服务器的私有网络/私有IP地址。
运行以下命令以显示服务器的私有 IP 地址:
ifconfig
样本输出:
eth0 Link encap:Ethernet HWaddr 04:01:10:4B:B8:01 inet addr:107.170.13.134 Bcast:107.170.13.255 Mask:255.255.255.0 inet6 addr: fe80::601:10ff:fe4b:b801/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:164298 errors:0 dropped:0 overruns:0 frame:0 TX packets:46316 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:230223345 (219.5 MiB) TX bytes:4969058 (4.7 MiB) eth1 Link encap:Ethernet HWaddr 04:01:10:4B:B8:02 inet addr:10.128.241.135 Bcast:10.128.255.255 Mask:255.255.0.0 inet6 addr: fe80::601:10ff:fe4b:b802/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:120 errors:0 dropped:0 overruns:0 frame:0 TX packets:13 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:6810 (6.6 KiB) TX bytes:874 (874.0 b) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)
这里的第二位信息,从 eth1
开始并继续 inet adde:
显示分配给我们服务器的 private IP 地址,在我们的例子中是 10.128.241.135
.
我们将使用这个 IP 地址让 Nginx 与我们的应用程序服务器进行通信。
记下此地址并继续下一步设置和配置 Nginx。
注意: 要了解有关 DigitalOcean 专用网络的更多信息,请查看社区文章部分的 如何设置和使用 DigitalOcean 专用网络 教程。
将 Nginx 设置为反向代理和负载均衡器
在本节中,我们将在前端服务器上工作并设置 Nginx 以欢迎传入请求并平衡应用程序服务器之间的负载。
设置 Nginx
由于我们启用了 EPEL 存储库,因此可以使用 yum 获取 Nginx。
运行以下命令以使用 yum 下载并安装 Nginx:
yum install -y nginx
配置 Nginx
安装 Nginx 后,下一步是使用其配置文件 nginx.conf
,默认位于 /etc/nginx
。
执行以下命令以使用 nano
文本编辑器开始编辑此文件:
nano /etc/nginx/nginx.conf
向下滚动文件下方并注释掉以下行:
# Before: include /etc/nginx/conf.d/*.conf; # After: # include /etc/nginx/conf.d/*.conf;
在 http {
节点内,添加以下配置,修改它们以适合您自己的设置:
# Set your server # server_name www.example.com; upstream unicorn_servers { # Add a list of your application servers # Each server defined on its own line # Example: # server IP.ADDR:PORT fail_timeout=0; server 10.128.241.135:8080 fail_timeout=0; # server 10.128.241.136:8080 fail_timeout=0; # server 10.128.241.137:8080 fail_timeout=0; } server { # Port to listen on listen 80; location / { # Set proxy headers proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://unicorn_servers; } }
按 CTRL+X 并用 Y 确认保存并退出。
首先,使用以下命令运行 Nginx 守护进程:
service nginx start
修改配置文件后,可以使用以下命令重启服务器:
service nginx restart
注意: 要了解更多配置和设置提供静态文件的指令,请查看官方 Unicorn nginx.conf 示例 。