Rails in production
What is rails?
Rails
- Web MVC Framework
- Convention over Configuration
- Scaffolding
- Ruby
- Monkey Patching
Rack
- Ruby Web Server Interface
- HTTP Response code
- Hash of headers
- response body
#my_rack_app.rb
require 'rack'
app = Proc.new do |env|
['200', { 'Content-Type' => 'text/html' },
['Hello World']]
end
Rack::Handler::WEBRick.run app
#config.ru
run Proc.new { |env| ['200', { 'Content-Type' => 'text/html' },
['Hello World']] }
Other Web Framework?
Web Framework
- Sinatra
- Padrino
- Lotus
- Volt
- Grape
Rails compoenet
- active model
- active record
- active job
- active view
- active support
- action pack
- action mailer
- railties
Tool
- Rails Generator
- Rails Console
- db migration
- asset pipeline
- Thor
- Spring
- Guard
- xip.io
- better erros
- pry
Etc Tool
- Pow
- Foreman
Which Server do we have to use?
- webrick
- thin
- unicorn
- puma
- passenger
Ruby Process Model
It depends on implementation!
Ruby Implementation
- MRI CRuby
- JRuby
- Rubinius
- RubyMotion
- MacRuby
MRI CRuby
- Most popular ruby implementation
- MultiThread ( since 2.x ~)
- JIT
- But, still GIL limitation
- multithread for I/O
JRuby
- Based on jvm
- JRuby9000 released(support ruby2.2)
- true multithreaded implementation
- invoke dynamic
Rubinius
- ruby implementation based on LLVM
- multithead implementation
- performance penalty
Unicorn
- Master and worker process model
- slow client problem
- nginx with unicorn
- unix domain socket
Puma
- multithread web server
- recommended in the heroku
- rails supports thread safe
- hybrid model - multi process and multithread
- apache / nginx module
- support hybrid - multi process and multithread
unicorn
worker_processes Integer(ENV["WEB_CONCURRENCY"] || 3)
timeout 15
preload_app true
before_fork do |server, worker|
Signal.trap 'TERM' do
puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
Process.kill 'QUIT', Process.pid
end
defined?(ActiveRecord::Base) and
ActiveRecord::Base.connection.disconnect!
end
after_fork do |server, worker|
Signal.trap 'TERM' do
puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to send QUIT'
end
defined?(ActiveRecord::Base) and
ActiveRecord::Base.establish_connection
end
puma
workers Integer(ENV['WEB_CONCURRENCY'] || 2)
threads_count = Integer(ENV['MAX_THREADS'] || 5)
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
environment management
- .env
- dotenv gem
- config/environments/*
view
- ERB
- Haml
- Slim
slim
- more simple than Haml
- It's like Jade
- Fast
ERB
- useful for custom view (json, yaml, config)
API
JSON View
- Active Model Serializer
- Rabl
- Jbuilder
presenter / decorator
Authentication / authorization
- Devise
- Cancan
- Omniauth
asset pipeline
- coffeescript
- sass / scss
- compress / bundling
- compass
- s3 sync
Background Job
- Sidekiq
- Resque
- Delayed Job
Resque
- Process fork
- heavy rather than sidekiq
Sidekiq
- multithread background job
- Redis is used for queue
- open source / commercial
- based on celluloid
- provide job monitoring page
- easy to use
- best performance in the JRuby
Sidekiq
# config/initializers/sidekiq.rb
Sidekiq.configure_server do |config|
database_url = ENV['DATABASE_URL']
if database_url
ENV['DATABASE_URL'] = "#{database_url}?pool=25"
ActiveRecord::Base.establish_connection
end
end
Resque
Resque.before_fork do
defined?(ActiveRecord::Base) and
ActiveRecord::Base.connection.disconnect!
end
Resque.after_fork do
defined?(ActiveRecord::Base) and
ActiveRecord::Base.establish_connection
end
Test
- Rspec
- Factory Girl
deploy
- Git
- Heroku
- Jenkins
- AWS Opsworks (chef solo)
AWS OPSWORKS
- Based on Chef Solo
- opsworks cookbook
- attributes / receipe
- pros and cons
Docker
Immutable Infrastructure
docker
- slow build
- fast deployment
- docker registry sucks
- AWS ECS
- versioning - rollback is easy
- docker image
- log management (host option)
- network (native mapping, dhcp)
- cluster management
monitoring
- new Relic
- sentry
Log Management
- ELK(Elastic Search + Logstash + Kibana)
- FluentD
rails in production
By odyss
rails in production
- 2,298