1. 介绍

Puma is a simple, fast, threaded, and highly concurrent HTTP 1.1 server for Ruby/Rack applications.

按照官方的定义,puma是一个多进程,多线程,高并发的web容器。相比于unicorn,puma是多线程的,线程是进程之上更小的执行单位,而创建线程是额外的cpu开销的,但是puma用了一个线程池,它能实现高并发。由于c语言实现的ruby是存在GIL(全局锁),ruby的多线程并不能有效地利用多核,因为那个GIL是同一时间只能执行一段ruby代码的,虽然它IO操作并不阻塞,但这样也并不能实现真正的高并发,不过,Rubinius和JRuby没有GIL,和它们结合就是一个比较好的组合。

而且,使用puma,还要保证代码,框架,还有各种gem都是线程安全的。这对开发者的编程能力是一个考验。

2. 使用

我们是使用mina-puma结合nginx来部署Puma应用的。

使用puma来部署ruby on rails应用和使用unicorn的方法基本差不多。所以我们可以更多的参考前一篇文章部署之使用mina来部署ruby on rails应用之unicorn(八)。唯一有不同的是unicorn的地方改成puma,还有配置文件的内容也是要按照puma的来。

安装的gem是下面两个。

gem 'puma'
gem 'mina-puma', require: false

require 'mina/puma'添加到config/deploy.rb中。

设置puma的配置文件的位置。

set :puma_config, -> { "#{deploy_to}/#{current_path}/config/puma_app.rb" }

其他关于config/deploy.rb文件的部分要改成下面这样。

require 'mina/puma'

task :setup => :environment do
  # Puma needs a place to store its pid file and socket file.
  queue! %(mkdir -p "#{deploy_to}/#{shared_path}/tmp/sockets")
  queue! %(chmod g+rx,u+rwx "#{deploy_to}/#{shared_path}/tmp/sockets")
  queue! %(mkdir -p "#{deploy_to}/#{shared_path}/tmp/pids")
  queue! %(chmod g+rx,u+rwx "#{deploy_to}/#{shared_path}/tmp/pids")

  ...

end

# Add pids and sockets directories to shared paths
set :shared_paths, ['config/database.yml', 'tmp/pids', 'tmp/sockets']
set :puma_config, -> { "#{deploy_to}/#{current_path}/config/puma_app.rb" }

task :deploy do
  deploy do
    invoke :'git:clone'
    invoke :'deploy:link_shared_paths'
    ...

    to :launch do
      ...
      invoke :'puma:restart'
    end
  end
end

puma的配置文件config/puma_app.rb是这样子的。

app_path = File.expand_path( File.join(File.dirname(__FILE__), '..'))
# Change to match your CPU core count
workers 1

# Min and Max threads per worker
threads 1, 6

# Default to production
rails_env = ENV['RAILS_ENV'] || "production"
environment rails_env

# Set up socket location
bind "unix://#{app_path}/tmp/sockets/pumactl.sock"

# Logging
stdout_redirect "#{app_path}/log/puma.stdout.log", "#{app_path}/log/puma.stderr.log", true

# Set master PID and state locations
pidfile "#{app_path}/pids/puma.pid"
state_path "#{app_path}/tmp/sockets/puma.state"
activate_control_app

on_worker_boot do
  require "active_record"
  ActiveRecord::Base.connection.disconnect! rescue ActiveRecord::ConnectionNotEstablished
  ActiveRecord::Base.establish_connection(YAML.load_file("#{app_path}/config/database.yml")[rails_env])
end

而nginx的地方基本是一样的,唯一需要修改的是将upstream rails365部份的puma的unix socket的文件指向正确即可。

先使用mina puma:start命令把puma启动起来。

最后使用mina deploy来部署。

完结。


回复数量: 0
暂无评论~~