HerokuでRailsアプリ運用の 
パフォーマンス、SEO対策 
株式会社ベストティーチャー 
今 佑介 @kon_yu 
2014/12/04 
Salesforce World Tour Tokyo 2014 DevZone
はじめに 
• Railsでのサービス運用において 
• パフォーマンスの改善 
• SEO対策 
• Herokuと普通のLinuxサーバの環境と比較 
• Herokuならではの対策 
• その他の最近お気に入りのGemについて
本題に入る前に
ちょっとアンケート 
• 自分に当てはまるものに手を上げて、 
少し体を動かしましょう 
• Salesforce社サービスの利用経験を聞きます
Salesforceで仕事をしている
force.comで仕事をしている
Herokuで仕事をしている 
credit::hirodusk
Amazon Web Service 
を使ってるけど様子を見に来た 
credit:fugutabetai_shyashin
Who am I 
• 今 佑介(コン ユウスケ) 
• Twitter: @kon_yu 
• Best Teacher, inc.  CTO 
• オンライン英語学習サービス
https://speakerdeck.com/konyu/ 
herokudewbspao-woda-tifan-sitahua
Best Teacherとは 
既存の英会話サービスBest Teacher 
他人英語自分英語 
教材で学んでも、自分が使わない英語を学 
ばされる 
自分が話す英語をそのまま英語にし 
ていくので、使える英語が学べる
Best Teacherのレッスンフロー 
1. Writingレッスンで! 
自分の『会話文』を作る 
2. 講師が添削と音声録音! 
した『会話文』を復習 
3. Skypeレッスンで! 
『マンツーマン英会話』 
を実践 
この黄金の 
回転が英語 
力を上げる
もう一度目次 
• Railsでのサービス運用において 
• パフォーマンスの改善 
• SEO対策 
• Herokuと普通のLinuxサーバの環境と比較 
• Herokuならではの対策 
• その他の最近お気に入りのGemについて
Unicornパフォーマンス改善 
• Unicornのプロセスをメモリがいっぱいなった 
ら再起動 
• Gem: unicorn-worker-killer 
• これを使うところはLinux、Heroku共通 
参考:https://github.com/kzk/unicorn-worker-killer
普通のLinuxの場合 
• Gemfileに以下を追加 
gem ‘unicorn-worker-killer'
設定ファイルconfig.ru 
# Unicorn self-process killer 
require 'unicorn/worker_killer' 
! 
# Max requests per worker 
# リクエスト数を上限値 
use Unicorn::WorkerKiller::MaxRequests, 3072, 4096 
! 
# Max memory size (RSS) per worker 
# メモリ使用量を上限値 
use Unicorn::WorkerKiller::Oom, (192*(1024**2)), (256*(1024**2))
Herokuの場合 
• Gemfileに以下を追加 
gem ‘unicorn-worker-killer’ 
※ nginxと同じ
設定ファイルconfig.ru 
require 'unicorn/worker_killer' 
max_request_min = ENV['UNICORN_MAX_REQUEST_MIN'].to_i || 3072 
max_request_max = ENV['UNICORN_MAX_REQUEST_MAX'].to_i || 4096 
! 
# Max requests per worker 
use Unicorn::WorkerKiller::MaxRequests, max_request_min, max_request_max 
# メモリ使用量を環境変数で定義 
oom_min = ((ENV['UNICRON_OOM_MIN'].to_i || 250) * (1024**2)) 
oom_max = ((ENV['UNICRON_OOM_MAX'].to_i || 300) * (1024**2)) 
# Max memory size (RSS) per worker 
use Unicorn::WorkerKiller::Oom, oom_min, oom_max
Herokuの場合 
• 環境変数を工夫して、適正値を見つける 
• これをやらないと、パラメタ調整のために 
いちいちデプロイしないといけない 
• 参考: http://qiita.com/Oakbow/items/ 
ef88df07234866c7be30
Unicornのパフォーマンス 
• Rubyが1.9系以下の場合はruby2.1系を使いましょう 
• Unicornのワーカーはメモリをメモリ使用量で再起動 
• GCの利用でワーカーが長生きする分パフォーマンス向上 
• 参考: 
• https://www.digitalocean.com/community/tutorials/how-to-optimize-unicorn- 
workers-in-a-ruby-on-rails-app 
• http://www.sawanoboly.net/contribution/2014/3/13/ruby-21-out-of-band- 
gc
普通のLinuxサーバの場合 
• rbenvのインストール 
• rubyのインストール 
• rbenv instal 2.1.4 
• .ruby-versionに以下を記述 
2.1.4
Herokuの場合 
• Gemfileに以下を記述 
ruby ‘2.1.4' 
と書かいてHerokuに git push でデプロイ 
これだけでRuby2.14で動作
Ruby 2.1 Out-of-Band GC 
• デカイGCが走るとパフォーマンスに影響 
• リクエストとリクエストの間に GC を走らせる、 
Out-of-Band GCを利用する 
• refs: http://www.sawanoboly.net/ 
contribution/2014/3/13/ruby-21-out-of-band- 
gc
設定ファイル 
• Gemfile 
require ‘gctools/oobgc' 
• config.ru 
require 'gctools/oobgc' 
if defined?(Unicorn::HttpRequest) 
use GC::OOB::UnicornMiddleware 
end
Fastly(CDNサービス)の利用 
• JS, CSS, 画像など静的ファイルを 
外部CDNサービスからアクセス 
• 高速に静的ファイルをクライアントへ 
• アプリケーションサーバへのアクセスを低減 
• 結果、アプリサーバのパフォーマンスアップ
普通のLinuxサーバの場合 
• Fastly CDNの利用する場合アカウントを作って 
クレジットカードを登録して、設定して・・・ 
• 月々の決済も他と別 
• 煩雑・面倒くさい
Herokuの場合 
• FastlyをHerokuの画面からボタン一発で追加す 
るだけ
CORSに注意 
• Cross-Origin Resource Sharing 
• WebFontやAjaxをしようとすると、セキュリティエラーでブ 
ラウザに怒られる 
• レスポンスヘッダーに以下を付加して回避 
• Access-Control-Allow-Origin:http://www.best-teacher-inc. 
com 
• IE8,9以下だとAjax 通信の際に罠があるのでxhr.jsなどで検索 
• http://qiita.com/edo_m18/items/d3329fb251abd7a481c7
ホットデプロイ 
• 特に一日何度もデプロイする場合、 
サービス停止、レスポンス遅延は、ユーザにとっ 
ては心地よくない 
• サービスを止めることなく、 
デプロイしたものが立ち上がったら古いサービ 
スと切り替わるようにする
普通のLinuxサーバの場合 
• Gem: capistrano-unicorn 
• ref: http://kray.jp/blog/troubleshooting-rails- 
unicorn/ 
! 
• 他にも色々方法があります
Herokuの場合 
• Preloadでダウンタイムなし 
• 設定方法 
> heroku features:enable -a myapp preboot 
• コマンド一発超簡単
gzip圧縮して配信する 
• HTML、CSS、JS テキストデータを 
圧縮して送信 
-> レスポンスタイムを削減 
• CDNサービスやCloudFront使用している場合 
データ転送量が少ないほうが財布にやさしい
普通のLinuxの場合 
• nginxで設定するとConfファイルに 
gzip on; 
gzip_http_version 1.1; 
gzip_types text/plain 
text/xml 
text/css 
application/xml 
application/xhtml+xml 
application/rss+xml 
application/javascript 
application/x-javascript; 
gzip_buffers 4 8k; 
gzip_min_length 1000; 
gzip_comp_level 1; 
gzip_proxied off; 
gzip_disable "MSIE [1-6]." "Mozilla/4"; 
gzip_vary off;
Heroku の場合 
• gem: heroku-deflater 
• gz圧縮したHTMLを返すようにする 
• Gemfileに追加してあげるだけでOK 
! 
! 
• 参考: http://qiita.com/Oakbow/items/ 
ec13c3a57327cc5f3197
SEO対策 
• LinuxだとWebサーバの設定するところだが、 
Herokuはそれが出来ないので工夫が必要 
• canonicalタグを使う場合もあるが 
今回は301でRedirectで説明します
rack rewrite 
• RailsはURLの最後尾に/がある場合、Railsは/の 
有り無しを吸収してくれるが、 
SEO的に/つきをIndexingされたくない場合リラ 
イト 
• ApacheとかNginxを設定できればそっちの設定 
ファイルに書けるところ
設定ファイルconfig.ru 
require 'rack/rewrite' 
use Rack::Rewrite do 
r301 %r{^/(.*)/$}, '/$1' 
end
xxx.herokuapp.com を 
リダイレクト 
• Herokuのアプリケーションは必ず 
xxx.herokuapp.comというURLを付与 
• テストで使う分には大変便利 
• ドメインを取得して本番で使うには、Googleが 
登録されてしまう憎いやつ
application_controller.rbに 
追記 
#要するにbefore_filterでxxx..herokuapp.comへアクセスが来たら正し 
いURLへリダイレクト 
before_filter :ensure_domain 
# redirect from herokuapp for SEO 
def ensure_domain 
return unless /.herokuapp.com/ =~ request.host 
port = ":#{request.port}" unless [80, 443].include?(request.port) 
redirect_to "#{request.protocol}#{FQDN}#{port} 
#{request.fullpath}", status: :moved_permanently 
end
httpとhttpsがある場合はhttp 
に統一してリダイレクト 
before_filter :deactivate_ssl 
#必要なメソッドに適用させる 
def deactivate_ssl 
if (Rails.env.production?) && !(request.ssl?) 
redirect_to :protocol => "http://", :status => 
:moved_permanently 
end 
end
最近お気に入りのGemの紹介 
• 開発、運用している上で便利で気に入っている 
Gemを少し紹介
本番環境でのうっかりを防ぐ 
• gem: rack-dev-mark 
• 検証環境だと思って操作したら実は本番環境 
ユーザ情報を誤って変更しそうになってヒヤリ 
こんなヒヤリハットを防ぐ 
!
設定 
• Gemfileに追記 gem ‘rack-dev-mark' 
• development.rbに追記 
config.rack_dev_mark.enable = true 
config.rack_dev_mark.theme = [:title, 
Rack::DevMark::Theme::GithubForkRibbon.new(positi 
on: 'right', fixed: true, color: ‘red')] 
• 参考:http://konyu.hatenablog.com/entry/ 
2014/11/12/225705
メール内容をキャプチャ 
• Gem: letter_opener_web 
• 開発環境で送信メールを一覧で内容確認
設定 
• Gemfileに追記 gem ‘letter_opener_web’ 
• routes.rbに追記 
if Rails.env.development? 
 mount LetterOpenerWeb::Engine, at: "/letter_opener" 
end 
• 参考:http://qiita.com/k-shogo/items/d85905535a64e82a3b2b
一番大事なお知らせ 
• ベストティーチャーではミドルからシニアレベ 
ルのエンジニアを募集しています 
• Herokuを本番環境で使っています 
• Wantedlyで「ベストティーチャー」で検索
ご清聴ありがとうございました 
べネチア・サンタルチア駅前のゴミ箱で 
MOディスクを探すギアッチョの真似をする筆者

HerokuでRailsアプリ運用の パフォーマンス、SEO対策