herokuでrailsアプリ運用の パフォーマンス、seo対策
TRANSCRIPT
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のレッスンフロー
2. 講師が添削と音声録音!した『会話文』を復習
1. Writingレッスンで!自分の『会話文』を作る
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.rurequire '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_permanentlyend
httpとhttpsがある場合はhttpに統一してリダイレクト
before_filter :deactivate_ssl#必要なメソッドに適用させる
def deactivate_ssl if (Rails.env.production?) && !(request.ssl?) redirect_to :protocol => "http://", :status => :moved_permanently endend
最近お気に入りの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(position: '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ディスクを探すギアッチョの真似をする筆者