3年前に作られたサービスをフルリニューアルする運びとなりました。
リファクタの文化がなければ、テストコードもない。インデントはタブなのスペースなの?そのCakePHPは本当にCakePHPなの?PHPは5.3。丁寧に ssh
& git pull
してデプロイ。gulp入ってるのに .css
を git 管理。。。。
1年かけて徐々に耕してきましたが、念願のリニューアル!!
やりたいこと大爆発したので、個人的な趣味/独断/偏見/マイブームもりもりの構成を書きなぐります。
新卒2年目なので至らないところがあったらツッコミしていただけると幸いです。
あと前述の通り、普段の業務での開発は CakePHP なので Rails 周りの知識はおぼろげなのでご容赦ください
前提
- メディアサイト
- CVポイントはフォーム入力
- 脱社内ガラパゴス
インフラ編
実現したいこと
- 負荷対策
- サーバ監視
- アクセス解析
- アクセス高速化
アプリケーションサーバ
- EC2
- nginx
- unicorn
- fluentd (for アクセス解析)
画像リサイズ&キャッシュサーバ
nginx の画像リサイズモジュールを使って画像のリサイズを行う
rails で paperclip などで行っても良いが、形式が書きられてしまうのがネック・・・
記事のサムネイルや後述の AMP のために使う
特に、 AMP は画像のサイズを事前に知らないといけないので重宝する予感
Cloudfront や最近教えてもらった Cloudinary などのサービスを使うのもありかなぁとも思います
thoughtbot/paperclip: Easy file attachment management for ActiveRecord
nginxの画像キャッシュサーバにリサイズ機能を付けた - Qiita
Cloudinary - Cloud image and video service, upload, storage & CDN
【AWS の CDN】Amazon CloudFront(高速コンテンツ配信ネットワーク) | AWS
サーバ監視
- mackerel
- newrelic
外部監視は mackerel が社内スタンダード&今使ってるので続投です
newrelic も今使っていて、スロークエリなど見やすいので続投します
特長と機能 - 特長 - Mackerel(マカレル): 新世代のサーバ管理・監視サービス
Digital Performance Monitoring and Management | New Relic
アクセス解析
- Amazon kinesis data stream
- AWS Lambda
- ClickHouse on EC2
- Redash on EC2
アプリケーションサーバの fluentd で Webサーバ(ミドルウェア)のログを kinesis, lambda を経由して ClickHouse に溜め込む
主に計測するものはレスポンスにかかった時間やページの容量など、 Google Analytics で計測できないものを主に扱い、速度改善などのインフラ改善に役立てる狙い
単純な PV 数の計測は Google Analytics で行う
ClickHouse も最近教えてもらったデータウェアハウスです
select がクッソ早くてディスク圧迫も少ないけど、 update, delete ができない特徴があります
Amazon Kinesis Data Streams
ClickHouse — open source distributed column-oriented DBMS
ClickHouseとMySQLのベンチマークをとってみた。 - Qiita
Make Your Company Data Driven | Redash
httpサーバの選択
パラレルでリクエストを扱えるとか server push とか良さげ
他 rails サービスが nginx なので、それに揃えて nginx を使いたいところ
ただ、オープンソース版の nginx は server push が使えないです
なので、それができる、かつ nginx より高速と噂の H2O を使いたい気持ちもあります
ただ、 server push がどれだけ良いのか、設定が大変そうな雰囲気があるので nginx かなぁというところです
H2O - the optimized HTTP/2 server
バックエンド編
- ruby 2.4 系
- ruby on rails 5.1 系
- sidekiq(非同期メール配信用)
社内は rails がスタンダードなのでそれに揃える形での構成です
バージョンは思考停止で最新版を使います
ただ、 rails に関しては Vue.js を使いたいので5.1系です
sidekiq か resque か、ですが、 CTO が sidekiq の方がいいって言ってるので思考停止でそうします
Railsで非同期処理:キュー。Sidekiq(+ActiveJob)がResqueよりも、とても簡単便利。 - Qiita
フロントエンド編
- モダンな技術を取り入れる
- AMP
- PWA
- Vue.js
- 構造化マークアップ
AMP
メディアサイトなので、記事ページは AMP で構成しておきたい
ページロード高速化と、検索結果で上部にカルーセルで表示されることを狙って
ネックなのはサービス内で画像サイズのレギュレーションがなかったり複数の画像サイズを用意しないといけないこと
その辺を前述の画像リサイズサーバでカバーしたい
あと CSS を View に直書きしないといけないのがネックっぽい
必然的に1ファイルサイズが大きくなるのでコード書く時に辛そう
でも AMP の制限でそんなに凝ったこと出来ないからそんなに大きくはならないのかなぁ
パーシャルで切り出す案ももらったのでそれで解決できそう感
Accelerated Mobile Pages Project – AMP
Learn AMP by Example
PWA
service worker で記事のオフライン表示や、おすすめ記事を push 通知したりしたい
検索ページとかを切り出してアプリっぽく提供してもいいかもしれない
あとはアプリとしてインストールできるようにしたい
スマホではホーム画面からアプリにアクセスする動きが前提なので
"ホーム画面 → ブラウザ → Google 検索 → サービス" で2クッション入るのはだるい
"ホーム画面 → サービス" でダイレクトに来てもらえる方がいいはず
Google I/O:プログレッシブウェブアプリ (PWA) の機能と成果 | Growth Hack Journal
いまさら聞けないPWAとAMP - Qiita
やばい、iOSにネイティブアプリ要らなくなるかも。SafariもPWAに対応する可能性 - Qiita
Progressive Web Apps | Web | Google Developers
Vue.js
jQuery でゴリゴリ実装は辛いので js フレームワークを使います
React, Angular などありますが、あくまでメディアなのでそこまでがっつりしたものは不要です
なので小回りの効く Vue.js 採用です
Vue.js
他のフレームワークとの比較 — Vue.js
【2016年冬】最新CSSフレームワークまとめ - Qiita
構造化マークアップ
検索エンジンに情報を伝えるために使います
AMP でも必須になります
実装方法は json-ld と microdata があります
どっちを使おうか、という話ですが、microdata は html を直接変更して構造を表します
json-ld は要は json をページ内で読み込ませる方法です
microdata は html と構造が密な関係になるので管理がダルそう、ということで json-ld を採用します
rails で実装するなら、いい感じの記事があったのでこれを参考にしようかな、と思います
JSON-LD - JSON for Linking Data
Microdata - HTML | MDN
JSON-LDとRails - Qiita
開発周り編
- test
- RSpec
- linter
- eslint
- rubocop
- csscomb
- alt lang
- sass
- babel
- pug
- styleguide
- aigis
- chatops
test
単体テストは RSpec で。
minitest の方がいい説もあるのでちょっと調べてみましたが、僕は RSpec の方がいいかなぁという結論に
ネックは、minitest は Fixture/plugin の管理、RSpec は DLS の学習コスト。
他プロジェクトでは RSpec を使っているので DLS 憶えないといけないのは必然、ということでネック以前の問題
minitest はシンプルで魅力的だけど、 Fixture 管理は PHPUnit で辛かったのと、 plugin 管理に時間取られるなら本末転倒感が辛い
ということで RSpec かな
RSpecとMinitest、使うならどっち? / #kanrk06 // Speaker Deck
rspecとminitestの比較 〜そうして僕は返事がない屍となった。〜 - Qiita
linter
コードの体裁をチェックするのは人間がやることじゃないのでコードにやらせます
javascript → eslint
ruby → rubocop
css → csscomb
ESLint - Pluggable JavaScript linter
bbatsov/rubocop: A Ruby static code analyzer, based on the community Ruby style guide.
CSScomb: Makes your code beautiful
alt lang
sass(scss), babel は今使ってるので続投。
babel-preset-env という ES5 への変換度合いをよしなに決めてくれるものが出てきてたので使います
html は rails なら slim が使えますが、 pug がいい感じって CTO が言ってたのでそうします
babel/packages/babel-preset-env at master · babel/babel
Getting Started – Pug
styleguide
スタイルガイドでパーツスタイルの統一と、ページ作成時にディレクターがそれを見て考えられるように用意します
今 aigis を使ってるので続投
ruby なので ruby系のスタイルガイドジェネレータがいいですが、Rails5.1系なら node.js 必須なのでまぁいいでしょう
aigis - CSS Styleguide Generator
chatops
デプロイ時のオペレーションが複雑になってきた
- (STG環境の時は) STG を使っていないか確認
- PR作る(コメントに該当 issue のリンクを貼る)
- 開発メンバーに共有
- ディレクターに共有
- マージ
- デプロイ
手動でやるのはだるくなってきたのでまとめてやっちゃいたい感
あと chatops ってなんかいいやん?
bot といえば hubot ですが、 coffee script 使わないし ruby で rails なので ruboty が相性良さげ
r7kamura/ruboty: Ruby + Bot = Ruboty
その他考察
http/2 について
パラレルにリクエストを扱う、 server push でクライアントサーバ間の通信コストを減らすことでハヤイ!
インフラ周りはフルリニューアルでもなければ入れ替えが大変なのでこのタイミングで対応しておきたい気持ち
ちょっと疑問で残るのは、 ALB 挟んだら webサーバで HTTP/2 対応しなくていい説。
client <-> ALB <-> server
の現状で chrome developer tools の Network で見た時にプロトコルが "h2 (HTTP/2 over TLS)" で表示されてる
まぁでも、Webサーバは HTTP/2 には対応していないので、きっと ALB が HTTP/2 に対応しているのでそう表示されてるだけだと思う
なので実質的に HTTP/2 の利益は得られてないんだよね、きっと
普通に考えて Webサーバで HTTP/2 対応しないとだよね、普通に
HTTP/2 の概要 | Web | Google Developers
普及が進む「HTTP/2」の仕組みとメリットとは | さくらのナレッジ
turbolinks と Vue.js 相性悪い件
turbolinks を使うと Vue.js の動作が不安定になる
Vue.js がマウントする時に悪さをする様子・・・
加えて、 Google Analytics とも相性が悪いとの噂が他チームから聞こえてきたり・・・
turbolinks のロード高速化は魅力的ですが、開発効率を考えると個人的には削除したい気持ち
まだ検証していませんが、代替策として InstantClick が使えそうな雰囲気
しかも turbolinks よりも高速に動作するとの評判もあるのでより良さそう
ただ、 Google Analytics を使う時には turbolinks の様に専用の処理を加えないといけないので、一手間は必要になるよう
InstantClick — JS library to make your website instant
2行追加するだけでWebサイトを高速化するInstantClick.io - atskimura-memo
js が webpacker と sprockets でダブる件
sprockets は css, js を1ファイルにまとめることでブラウザキャッシュに持たせて表示の高速化を図るものです
webpacker は Vue.js や React など js フレームワークを webpack でコンパイルします
モダンフレームワークを使えるのと、 js をモジュール化できるので管理コストを削減できます
それぞれで管理する js ファイルは配置場所がそれぞれ指定されています
- sprockets →
app/assets/javascripts/
以下 - webpacker →
app/javascript/
以下
これにより js ファイルの置き場所が複数になるので管理がダルいのと、どんな時にどっちに置くのか、を気にしないといけないです
なので、どちらかにまとめておきたいところ
気持ち的には js モジュールを使って管理コストを抑えることを最優先にしたいので、 webpacker でまとめて管理するようにしたい
watcher がいろいろ生まれる件
以上の構成だと、開発時にいろいろな watcher が必要になる
- linter
- webpacker
- styleguide
foreman でプロセスをまとめて管理するのが楽かな
ddollar/foreman: Manage Procfile-based applications
管理画面不要説
Redash を使えば、管理画面で数字を見れるようにする必要はないので、実装する手間を省けそう
ただ、CMSは必要なので0にはできなさげ
まとめ
やりたいことを詰め込んでみました
他にも面白げなやつあったら突っ込んでみたいです