
10年動き続けているブログサービスのエンドツーエンドを書いた記録
ペパボ技術部
http://www..shu-cream.com
- 電車で携帯忘れたときの知見と共有
- プロダクトオーナーシップに関する社内勉強会をはじめました
なぜテストを書くに至ったか
- NyAh
- プレイベーとクラウド基盤へ移設する
- JUGEM移設のPO的なポジション
- JUGEMU
- 10周年
- PHP/MySQL/Ruby/Perl
- 15個のリポジトリ
- サーバのロールは18ロール
- porral
- JGセット(ユーザ毎のブログでWEBとDBの組み合わせ。39セット)
- バッチ
- 外部、内部連携用API
- 顧客管理、etc
- JGセットの移設
- 数が多い
- ユーザ影響が大きい
- カスタマーサポートも巻き込む必要が
エンドツーエンドでテストやってしまおう
- 新規構築のリリース前にしようするチェックリスト
手動、目視の350
Trnip(Ruby/自然言語)
Capybara(バックエンド)
poltergeist(PhantomJS)
どうやってテストを書いたのか
キューカンバーをイメージすると良い
自然言語でテストで書く事に意味があると感じている
識別可能な名前をユーザ目線でつけれる、共通のワード
複数の処理にまとめて日本語で名前をつけれる
実例とテクニック
- ステージング、リリース前の本番環境に実行する
- DBに直接接続しない
- debug用のステップを作る(よくおちる時の切り分け)
- ステップを再利用できるようにする
- 無料ユーザで1日の投稿上限数が決まっている場合
- DBを直接触れないのでリセットできない
- 普段は実行せずタグで制御
- データのリセットは削除操作を繰り替えす
- evaluate_scriptでjavascript経由でデータを受け取れる
取り組みのまとめ
- よかった点
- アプリケーションの動作をよく理解できる
- stepをうまく作れるとシナリオをどんどん足せるので気持ちいい
つらかった点
- javascriptを多用した記事エディタの難しさ
- phantomJS or capybara-webkit
全部テストいける?
- どうしようもない部分は手で実行する必要があるとわかった
- flashができない
日本語で書けるというので外側がキレイになる
MogileFSをバックエンドとしたPrivate S3の作り方
インフラ編
private Cloud(openstack)に移行中
主に画像、容量が大きい、各サービスが個別にもっている
- 例えば30days alubum 2008年リリース / 750TB / 22億
- 横断的なオブジェクトストレージが必要
計画メンテを除いたサービス断はなし
大規模運用で安定運用するのは甘くない。swiftは見送った
MogileFSは既存で使っていた
S3はコスト面で見送った。従量だけで月数百万
Baytと名付けた
ストレージサーバとフロントエンド
- nginx + ngx_mruby
- インターネット、インターナルからリクエストを受ける
- apiにproxy
- apiだけでは出来ないあれこれ
api
rails, unicorn
その前に既存システムの安定稼働(負荷が増える/パターンも変わる)を
メトリクスの充実化、可視化(munin/kibana/big query)
storageサーバの高集積化(47でバイス, 170TB, dev/starまである)
DB(MySQL)サーバのリプレース
- 2台から3台
- 5.1->5.5
- MHA #### mogilefsdクラスタの強化
- スペックアップと台数強化
mogilefsdがスケールしない
- マスタープロセスとワーカを増やすpreforkモデル
- 子がすくないうちは大丈夫
- 増やすと全体的に不全状態に
- renice -20 -p 親(プロセスの優先度を最大に)
- 改善!
- ただし、副作用が
- 子が-20になる・・・
- cronで親子のnice値の面倒をみることで解決
- DBが刺さる問題
- 5.5以降デッドロックが
- 負荷がじりじり上がる
- MHAマネージャからの
- 元々使われてなかったindexが使われるようになった
- drop
既存の画像配信の品質向上
- 30%ほど高速化(資料参照)
gateway
- 実URLへのreproxy処理
- x-reproxyヘッダに実態のURLを2つ入れて返す
- Gatewayが実態のあるURLに取りに行く
- apiへproxy / ヘッダみて再プロキシ(re-proxy)
- APIが返したヘッダとクライアントに返すようにしないといけない
APIに届かなかった場合のエラードキュメント(bodyだけでなくstatus codeも)
ngnx + mruby
- server: bayt
- リクエストUUIDの発行
- HMAC認証をskipさせるヘッダを付与
- ngx_mrubyのオーバーヘッドはほぼ無い
- 太らない。活発な開発。劇的改善。
既存データのインポート方法
- S3互換なのでクライアントの実装はそのまま使える
- ETag(md5値)保存用のカラム追加
- path(object key)カラムのサイズを255->512へ
- 約9億レコードのテーブルへのALTERで最長25時間
今後の予定
- 全サービス移行
- マルチロケーション
- 動的画像リサイズ機能
API編
- オブジェクト->ストレージのデータ
MIMEだったりmysqlのデータ
GET/PUT/POST/DELETE
API設計
新しくAPIを設計する?
- 設計するのいやだな・・・(時間に耐えうる設計の重さ)
- サーバサイド+クライアントの実装。多種多様な言語
S3互換APIにしよう
- aws-sdk等OSSクライアントを利用可能
- HMAC認証等、再実装が煩雑なものが揃っている
API実装もいろいろ
- とはいえ、mogilefsをバックエンドとして流用できるものはさすがに
S3互換の制約
- S3 APIができる事だけ提供
- API自体の拡張は難しそう。SDKをいじるのはきつい
S3はREST APIのドキュメントが公開されている
さくらのオブジェクトストレージのリファレンスを先に読むとS3互換でよい
MogileFSクライアント、MySQLクライアント
- HTTPのハンドリング
XMLのパース、HMAC認証
perl-catalyst APIの稼働実績がある
ペパボでperlの継続的開発ができるか
MogileFSクライアント
- perlが本家、rubyはunicornの作者製
- ラウンドロビン機能、高速に動く工夫の観点でrubyで
S3をリファレンス実装とするとバグレポートのやり取りが楽
- HMAC認証はrubyに落とす
- HTTPルーティングも作る。501 Not Imprementでちゃんと返すように。
- metaテーブルを扱うのは1テーブルのみ
- オブジェクトのCRUD
- CRUDを1コントローラ、1トランザクションとして作る
- S3仕様のレブポンスボディ(XML)
S3にディレクトリは無い。common prefixesです
- list objectはLIKE検索とNOT LIKEと ">"で
- rails-apiでダイエット
- APIチューニング。XMLの生成がちと遅い
- builder, nokogiri, oxで比較
oxが早い
GETはmogilefsのオーバーヘッドが乗るので遅い(100ms)程度
H2OとPHPの話
- H2O
- HTTPを早速サポートしている
- デフォルトで高速 − まだ情報が少ない
高速でメモする余裕がなかった資料参照(?)
歴史あるwebサービスに携わって2年半の間に起きた事やった事
- カラミーショップのエンジニア − 10年続くサービス − 対部分はPHP、railsでAPI、AngularJS
入社当時(2年半前)
- Trac使ってた − レビューなし − SVN+git-svn
deployはwebistrano
素のSQL
テストは特になし
GitHub Enterpriseを使うようになった
− 全社的に導入
− SVN+git-svnからの脱却
− レビューするようになった
− 順番にレビュー当番。共通認識。
− PSRを意識するようになった
- PHP-CS-Fixer
- githubで?w=つけるとレビュー便利だよ
- javascriptの else if -> elseif
テストの導入
− E2Eテストが作られた
− RSpec + capybara
- ユニットテスト
- PHPUnit
composerが導入さられた
− ライブラリを探してバージョン管理
− deploy時にcomposerインストールする
ローカル環境が構築された
- vagrant + puppet
- 今まではMaglica上でそれぞれ作ってた
Wheneverでcronの変更を自動化
- crontabを管理してくれるGem
- コードにcrontabの設定を落とし込む。もちろんレビューも。
MySQLバージョンアップ
- 4.0->5.1->5.6
- Eloquent ORM(Larvelについてくる)
- もう昔の素のSQLには戻れない
画像サーバをFTPからBaytへ
− BaytとはS3互換のストレージサーバ
尋常じゃない速度でドッグフードを食べる方法
- sqaleというサービスの話
- ruby on railsのアプリケーションを利用するためのプラットフォーム − ドッグフーディングとは − 自社の製品を自分たちで使ってより良くしていいくこと
− 良い所・便利なところが見えてくる
− 新機能が出たらすぐに自分の小さなアプリをデプロイ
ネットが切れたので途中・・・
今夜、インターネットの片隅で。 〜ウェブサービス開発ちょっといい話〜
- カラミーショップ − ショッピングカートを全部作り直す − エンジニアが4人 − いい話一覧を話す
ショッピングカート
− 住所入力が2個あるとかも意味がある
− デジタルコンテンツだったらいらないのに
− その人に最適な情報入力を出せばいいじゃん
− 指針が大事。作る
− 哲学フロー開発
やぷしぃおもしろきかく!網羅パーソン総選挙
− 銅鑼で投票
− conoha(VPS)
- PHP/MySQL/KVSなし
− Nginx -> H2O
- PHPでできないことは実装をあきらめる(速度重視と実装コスパ) − 1200万投票 − PHP安定してるじゃん − DBが太ってストレージが溢れる − 自動化してAPI叩きまくる人
OS X アプリケーション 開発普及活動
− Cocoa Programing
- 経験は1年、teitenをリリース
− WWDC2014に参加
− NextSTEP
資料参照の方が良さそう
仮想通貨自動トレード記 Part1 〜 国内Bitcoin取引所で裁定取引したら儲かるの? 〜
− JUGEMの開発している人
− もっと世の中に仮想通貨のすばらしさを広めたい
− Hubotとslack
− 2つの国内取引上の板の差を判断し約定させる
- bugで損した
− 改修してみた。またBugが。
− promise/async
- hubotの開発はcloud9
- slackは絵文字でわかりやすくしよう
YAPC::Asia Tokyoでベストトークを取る方法
− 2014のベストスピーカー
− トーク「したら楽しい」「自分の特になる」人は是非やるべし
− タイトル大事。すべてをかけよ。
− 前振り、対象者の想定、実際に話すトピック、予習できる何か、意気込み
− 話題になった勝ち、ではない
− 何人にリーチするか?
- あなたブランド
資料参照
売り上げランキング: 111,502