###**WEBrick**
Ruby 标准库有一个名为 [WEBrick](http://ruby-doc.org/stdlib-2.1.1/libdoc/webrick/rdoc/WEBrick.html) 的默认 web server。它会随着Ruby的安装自动安装到系统中。大多数开发框架,如Rack和Rails默认使用 WEBrick 作为开发环境的web server。
虽然说 WEBrick 在开发过程极大的方便了开发者调试程序,但它并不能处理大规模的并发任务,因此在生产环境中需要用其它的web server来代替WEBrick。
### **生产环境为什么不能用 WEBrick**
默认情况下 WEBrick 是单任务,单线程的。这意味着,如果在同一时刻来了2个请求,第二个请求必须等待第一个请求处理完成后才能被执行。
如果用户没有在 Procfile 文件中指定web server,那么平台会在生产环境中默认运行 WEBrick ,这样一来,如果您的服务有大批量用户访问的话,用户会感觉速度很慢,或者会超时,无法打开,即便是将应用水平扩容到10个节点也无法解决这种问题。
因此,如果您在好雨云平台运行生产环境的应用,一定要更换默认的web server。
### **生产环境 web server**
生产环境的 web server 应该具备处理大规模并发任务的能力。我们强烈建议使用 Puma web server。
用户需要将 puma 添加到 Gemfile 文件中,然后在 Procfile 文件中指定用puma来运行Ruby 应用,最后提交代码并在平台上部署,接下来就给大家介绍puma部署Rails应用。
###**Puma部署Rails应用**
Puma 是 Unicorn 的有力竞争者,他们都可以处理大规模的并发请求。
除了worker进程外,Puma 默认使用线程来处理请求,这样可以更加充分的利用CPU资源。但这要求用户的所有代码都必须是线程安全的,即便不是也没关系,用户仍然可以通过横向(水平)扩展worker进程的方式来达到处理高并发请求的目的。
本篇文档将一步步指导您利用 puma web server 将 Rails 应用部署到好雨云平台。
##### **注意**
>#####将程序部署到生产环境之前,一定要确保再测试环境中可以正常运行。
### **添加 Puma 到程序中**
#### **Gemfile 文件**
首先,添加 puma 到应用的 Gemfile文件中:
echo "gem 'puma'" >> Gemfile
本地安装puma
bundler install
#### **Procfile 文件**
将 Puma 作为应用的 web 处理程序,用户可以在一行中设置多个参数:
web: bundle exec puma -t 5:5 -p ${PORT:-3000} -e ${RACK_ENV:-development}
通常情况下我们建议将puma的配置存成配置文件:
web: bundle exec puma -C config/puma.rb
请确保Procfile的内容正确,并添加到git代码仓库中。
#### **配置文件**
可以将puma的配置文件存在`config/puma.rb`或者你喜欢的位置。下面是一个简单的Rails应用配置文件:
~~~
workers Integer(ENV['WEB_CONCURRENCY'] || 2)
threads_count = Integer(ENV['MAX_THREADS'] || 5)
# 若程序不是线程安全的需要将threads_count设置为1
# threads_count = 1
threads threads_count, threads_count
preload_app!
rackup DefaultRackup
port ENV['PORT'] || 3000
environment ENV['RACK_ENV'] || 'development'
on_worker_boot do
# Worker specific setup for Rails 4.1+
# See: http://docs.goodrain.com/ruby/rails-puma.html#On_worker_boot
ActiveRecord::Base.establish_connection
end
~~~
用户需要确认配置了正确的数据库连接并可以正常的连接到数据库。下文会介绍如何设置数据库连接。
#### **Workers**
workers Integer(ENV['WEB_CONCURRENCY'] || 2)
>WEB_CONCURRENCY
环境变量根据应用的单个实例的内存大小而设置,默认情
况下一个128内存的应用实例默认WEB_CONCURRENCY=2
目前好雨云平台的一个实例的内存固定为128M,后续会支>持自定义调整。同时WEB_CONCURRENCY 变量会随着内存的调整而调整。
#### **Threads**
threads_count = Integer(ENV['MAX_THREADS'] || 5)
threads threads_count, threads_count
Puma 可以将请求交给一个内部的线程池去处理,这样可以处理更多的并发请求,减少响应时间,同时占用内存更小也可以最大化的使用CPU资源。
Puma 允许用户对线程数做最大和最小的限制,动态的调整操作由Puma主实例来完成。最小的线程数的意思就是当没有请求时线程数最小数目,最大就是说请求量上来后可以开线程的最大数。默认是 0:16 也就是 最小0,最大16,用户可以自由设置。我们建议将最大值和最小值设置为一样的,这样可以有效的处理请求,且不必因为动态调整线程数而浪费CPU资源。
##### **Preload app**
preload_app!
预加载应用减少了单个Puma worker处理进程的启动时间,可以利用独立的worker使用 on_worker_boot 方法来管理外部的连接。这样的配置可以保证每个worker进程可以使用优雅的方式进行数据库连接。
##### **Rackup**
rackup DefaultRackup
使用rackup命令来告诉 Puma如何启动你的rack应用。这个配置默认情况下Rails会自动写入到config.ru文件中。因此后续的Puma可能不需要设置了
##### **Port**
port ENV['PORT'] || 3000
Puma启动后监听的端口。在好雨云平台应用启动后回自动设置PORT变量,以便可以将应用添加到负载均衡中。本地默认设置为3000 这也是Rails默认值。
##### **Environment**
environment ENV['RACK_ENV'] || 'development'
设置Puma的环境变量,在好雨云平台上运行的Rails应用默认将ENV['RACK_ENV']设置为'production'
**On worker boot**
`on_worker_boot` 定义部分 是worker启动后未接受请求前执行的部分。主要是解决数据库连接并发问题,如果用户使用的是Rails 4.1+ 则可以直接再 database.yml 设置连接池大小来解决。
on_worker_boot do
# Valid on Rails 4.1+ using the `config/database.yml` method of setting `pool` size
ActiveRecord::Base.establish_connection
end
否则必须对这部分进行特定的设置:
on_worker_boot do
# Valid on Rails up to 4.1 the initializer method of setting `pool` size
ActiveSupport.on_load(:active_record) do
config = ActiveRecord::Base.configurations[Rails.env] ||
Rails.application.config.database_configuration[Rails.env]
config['pool'] = ENV['MAX_THREADS'] || 5
ActiveRecord::Base.establish_connection(config)
end
end
默认情况下我们都需要设置数据库连接池大小
如果程序中使用了其他的数据存储,如redis,memcached,postgres等,也需要在pre-load区域设置活动记录的重连机制。如果使用Resque连接到Redis需要使用重连机制:
~~~
on_worker_boot do
# ...
if defined?(Resque)
Resque.redis = ENV["<redis-uri>"] || "redis://127.0.0.1:6379"
end
end
~~~
### **线程安全**
线程安全的代码可以在多个线程无差错地运行。并非所有的Ruby代码都是线程安全的。如果你的代码和库正在多个线程中运行,很难检测到是否是线程安全的。
直到 Rails 4,出现了一种可以自动切换的线程安全兼容模式。虽然Rails是线程安全的,但并不能保证用户的代码也是。如果你的程序没有在多线程环境中运行过,我们建议部署的时候将最大线程和最小线程数同时设置为1,也就是禁用线程模式
threads_count = 1
threads threads_count, threads_count
即便禁用了线程模式,用户仍然可以调整worker的数量来增加并非处理能力。每个进程是使用独立内存的,即便代码是非线程安全的也可以跨多个进程处理。
### **数据库连接**
当调整线程数或进程数后,程序对数据库的连接也会增加,当检测到数据库连接丢失或时断时续情况时,就需要调整数据库的连接池大小。当Rails应用遇到连接池占满的时候会有如下报错:
ActiveRecord::ConnectionTimeoutError - could not obtain a database connection within 5 seconds
这意味着Rails的连接池设置得不够合理
### **部署到好雨云平台**
#### **将puma添加到Gemfile**
~~~
echo "gem 'puma'" >> Gemfile
# 本地安装puma并重新生成Gemfile.lock文件
bundler install
~~~
#### **写好puma.ru配置文件**
~~~
$ cat ./config/puma.rb
workers Integer(ENV['WEB_CONCURRENCY'] || 2)
threads_count = Integer(ENV['MAX_THREADS'] || 5)
# 若程序不是线程安全的需要将threads_count设置为1
# threads_count = 1
threads threads_count, threads_count
preload_app!
rackup DefaultRackup
port ENV['PORT'] || 3000
environment ENV['RACK_ENV'] || 'development'
on_worker_boot do
# Worker specific setup for Rails 4.1+
# See: https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server#on-worker-boot
ActiveRecord::Base.establish_connection
end
~~~
#### **写好Procfile**
echo "web: bundle exec puma -C config/puma.rb" > ./Procfile
#### **提交代码**
git add .
git commit -m "add puma"
git push origin master
详情可参见 `新建应用`-`代码提交`
#### **一键部署**
参见 `应用详情`-`一键部署`
- 介绍
- 从这里开始
- 注册
- 登陆
- 云帮界面
- 功能介绍
- 新增应用
- 从镜像
- 从源码
- 应用市场
- 应用框架
- 我的应用
- 界面介绍
- 应用控制台
- 概览
- 依赖
- 监控
- 日志
- 设置
- 费用
- 端口
- 存储
- 扩容
- 总览
- 团队
- 财务中心
- 帐户充值
- 应用扣费
- 批量续费
- 语言支持
- 概述
- Java
- java-maven
- java-war
- java-jar
- web程序部署
- 使用Webapp Runner部署
- 使用Jetty Runner部署
- 示例代码
- gradle
- Scala
- play
- Ruby
- 语言支持
- ruby应用部署
- Rails 应用概述
- 部署Rails3.x应用
- 使用Puma 部署 Rails 应用
- 示例代码
- Python
- 语言支持
- Web框架支持
- 示例代码
- PHP
- 平台特性
- 语言支持
- 运行环境设置与调优
- 部署ThinkPHP框架程序
- 示例代码
- Go
- 语言支持
- 部署Beego等框架程序
- 示例代码
- Node.JS
- 语言支持
- 示例代码
- Html
- 语言支持
- 示例代码
- Dockerfile
- 语言支持
- 示例代码
- 相关文档
- Procfile
- Cron计划任务
- 参考知识
- 好雨Gogs使用说明
- Artifactory对接本地仓库
- 好雨如何对接Git Server
- Git使用技巧
- 服务框架支持
- dubbo
- springcloud
- 技术支持