イベント登録数4,929

第6回テックヒルズ:Let's study Jenkins~さまざまなケーススタディ~

Jenkins導入を図るなら読んどかないとヤバい、サイバーエージェント、ミクシィ、クルーズ、楽天、Aimingの活用事例まとめ~第6回テックヒルズレポート
吉村哲樹 2013/7/16  2013年6月18日、六本木ヒルズ(東京・六本木)のイベントスペース「アカデミーヒルズ49」で、クルーズ株式会社(以下、クルーズ)主催の技術勉強会「第6回テックヒルズ」が開催された。毎回、旬の技術トピックを取り上げながら回を重ねてきたテックヒルズも、今回で6回目を数える。その規模も回を追うごとに拡大し、今回は何と参加者数は700人を超え、会場も2つのホールに分けられて全部で8つのセッションが行われた。  ちなみに、今回のテーマは「Let's study Jenkins ~さまざまなケーススタディ~」。「Jenkins」はいわずと知れた、オープンソースの継続的インテグレーション(CI)ツール。Jenkinsは巷に数あるCIツールの中でも極めて多くの機能と高い柔軟性を持つことで知られ、近年多くの開発プロジェクトで採用例が増えている。  しかしその一方で、その機能の多さや柔軟性故に、いざ導入しようと思っても、どの機能をどう使えばいいのか、なかなか見当が付かないという声も多く聞く。  そこで今回のテックヒルズでは、すでにJenkinsを導入して成果を挙げているプロジェクトの現場担当者が登壇し、実際にJenkinsを導入・活用するうえでのノウハウや注意点などについてプレゼンテーションが行われた。本稿ではその中から5つのセッションを取り上げ、その概要を紹介する。 “地獄”の開発時にAimingがJenkinsを使った対策とは 検索サービスの結合テストの自動化にJenkinsを使う楽天 コーディング規約チェックにもJenkinsを使うクルーズ テスト高速化にはJKS48が最も効果的、ミクシィ Jenkinsでアメーバピグは、いかほど品質向上できたのか “地獄”の開発時にAimingがJenkinsを使った対策とは Aiming 黒木慎介氏  Aiming(エイミング)の黒木慎介氏は、「進行中の開発プロジェクトで増えていくテストを自動で回し続けるために行った幾つかのこと」と題したプレゼンテーションで、実際に同社のとある開発プロジェクトでJenkinsを導入した際に直面した課題と、その解決方法について紹介した。  そのプロジェクトとは、主にRuby on RailsとCoffeeScript、Backbone.jsを使ってPC向けブラウザゲームを開発するというものだった。テスト実行環境としては、Ruby on RailsのコードはRspec、JavaScriptはJasmineを使用し、その実行結果を「ci_reporter」でJenkinsに読み込んで管理していた。 7000件を超えるテスト地獄にJenkinsの各種機能を活用  ところが、開発の進行に伴いテスト件数が増えていき、ついに7000件を超えた辺りからテストの実行時間が1時間を越えてしまい、開発効率の足を引っ張るようになってきた。黒木氏によれば、まさに「テスト地獄」とも呼べる状況だったそうで、これを改善するためにとった対策が「テストを分割して並列実行する」というものだった。  その際に役立ったのが、Jenkinsの「ラベル付け」機能や「Join Plugin」「Build Pipeline Plugin」などだった。これらを駆使してテストを複数に分割し、さらにスレーブノードの数を増やして、それらを並列実行させることによって、膨大な数に膨れ上がったテストを短期間の内に完了できるようになったという。 Build Pipeline Pluginの画面(黒木氏の講演資料より) 開発のペースに追い付けなくなったJenkinsは柔軟な“中断”で対応  しかしながら、続いて新たな“地獄”が待っていた。プロジェクトがいよいよ佳境を迎え、開発者の人数が増えて開発ペースが上がってくると、Jenkinsによる自動テスト実行のペースが、開発のペースに追い付かなくなってきたのだ。あるコードに対して施された修正のテストが終わらない内に、もう別のコード修正のテストがキューに積まれ、そしてどんどん積み上がっていく。こうした状況を改善するには、無駄なテストの実行を極力省く必要があった。  そのためにとられた方法が、すでにマージされているコード変更のテストや、修正再提出されている変更元のテストを、Jenkinsのジョブを中断することで省略するというものだった。当初は、ジョブをプログラムから中断させる方法が分からずに苦労したものの、Web画面の「中断ボタン」をユーザーが押した際と同じURLをcurlから叩くことで、ジョブを任意のタイミングで中断させ、無駄なテストの実行時間を削ることが可能になった。 ビルドやデプロイ、サーバ再起動などの自動化にも活用  こうして、このプロジェクトではJenkinsの使い方を自分たちの都合に合わせてさまざま工夫することで、より実践的な自動テストの運用を実現した。Aimingでは現在このほかにも、ビルドやデプロイ、サーバ再起動などの自動化のためにJenkinsをフル活用しているという。また、テスト結果の通知にチャットを用いたり、あるいはアラートの発生を警報ランプでを周知させるなど、ユニークな試みを取り入れている点が印象的だった。 結果の通知(黒木氏の講演資料より) 検索サービスの結合テストの自動化にJenkinsを使う楽天  楽天の荻野恒太郎氏は「検索基盤開発のための結合テスト環境の自動化」というプレゼンテーションの中で、検索サービスの開発プロジェクトで結合テストの自動化を進めるためにJenkinsを活用している事例を紹介した。 楽天 荻野恒太郎氏 3000件以上もの結合テスト項目  楽天では、自社の検索サービスの検索精度を向上させるために、3000件以上もの結合テスト項目を用意しており、しかもその数は日々増え続けている。そんな中、これらを1つ1つ手動で実行していては、テストケースが増えるに従いテスト実行の時間とコストも膨れ上がるばかりだ。  そこで同社では、結合テストの自動化を進めることでこうした時間やコストを抑えるとともに、毎日大規模なテストケースを実行できる環境を整えることで、ユーザーに高い付加価値を提供できるサービスの実現を目指した。  ただしその取り組みの過程では、いくつかの問題に直面したという。その1つが、テストの複雑化に伴い自動化も困難になってしまうという課題だ。 自社製結合テストフレームワークなどで対策  この問題については、結合テストに含まれる各コンポーネントの複雑な内部状態に依存するようなテストは、あらかじめ単体テストできちんとカバーしておき、結合テストは原則としてブラックボックステストだけに限定するというルールを徹底することで対応した。  また、自動化の仕組み導入に伴うコスト増の懸念に対しては、自社で「Ngauto」という結合テストフレームワークを開発することで解決した。  加えて、テスト結果の再現性を担保し、開発とテスト作業の手戻りを減らすために、結合テストを実行するたびにコンポーネントのデプロイとデータ投入を一からやり直し、環境を必ずクリーンアップしてから結合テストを始めることを周知徹底した。 スモークテストの管理にJenkinsを導入  さらには、結合テストの実行に時間がかかりすぎる点も、決して無視できない問題だった。すべてのコンポーネントを結合してテストをシーケンシャルに流すと、テスト完了まで約15時間もかかってしまうのだ。そこで、あらかじめスモークテストをパスしたものだけを結合テストの対象とし、さらにはテストジョブを1時間で実行できることを目安に複数に分割することで時間短縮を図った。 テストジョブを複数に分割(荻野氏の講演資料より)  このスモークテストの管理においてJenkinsが活用されている。単体テストをパスしたコンポーネントは、Jenkinsによって自動的にビルドされ、続いてスモークテストが実行される。このスモークテストをパスしたコンポーネントはバージョンが自動的に記録されて、さらに結合テストへと自動的に回される。  このように、スモークテスト周りを中心とした結合テストの自動化とCIに取り組んだところ、それまでプロジェクト全体の作業時間の約3分の1を占めていた結合テスト時間をほぼゼロにし、その分多くの時間を開発作業に回せるようになった。  また、結合バグを開発の初期段階で発見できるようになったことで、QAフェイズではサービスの付加価値部分のテストに集中できるようになったという。 コーディング規約チェックにもJenkinsを使うクルーズ  クルーズの鈴木優一氏からは、コーディング規約違反のチェックや、本番環境にデプロイするファイルの管理といった用途でJenkinsを活用している事例の紹介が行われた。 クルーズ 鈴木優一氏 コーディング規約の徹底が課題  クルーズでは、本番リリース直前までサービス品質向上のためのトライ&エラーを繰り返すという開発スタイルをとっており、そのため開発者をプロジェクトに短期的にアサインするケースが極めて多い。このような開発スタイルをスムーズに回すためには、あらかじめ全社的にコーディング規約を徹底させておく必要があるが、実際には属人的なコーディングスタイルがかなり横行していたのが実態だったという。 「PHP_Code Sniffer」や自社製スクリプト「VenusBase」と組み合わせてJenkinsでコーディング規約チェックを自動化  そこで同社はJenkinsを使って、開発者が記述したコードがコーディング規約に沿っているかどうかを自動的にチェックする仕組みを独自に構築した。実際のチェック処理は、「PHP_Code Sniffer」と呼ばれるツールと、自社フレームワーク「Venus」専用のコーディング規約定義スクリプト「VenusBase」を組み合わせることで実行し、それらの自動化と管理にJenkinsを活用している。  PHP_Code SnifferはEclipseと組み合わせて利用され、そこで見つかったコーディング規約違反項目はVenusBaseのGitリポジトリに収集される。Jenkinsは、このリポジトリを定期的にポーリングし、コーディング規約違反の状況をレポートにまとめて表示するとともに、違反があったことを開発者に通知する。また併せて、潜在バグの可能性があるコードについても集計・レポーティングを行う。 規約チェックの自動化(鈴木氏の講演資料より)  こうした仕組みを一部のプロジェクトに導入したことで、コーディング規約違反の件数が5分の1に減ったとともに、コーディングスタイルの共通化にメンバーが自然と取り組むようになってきた。今後は、同様の仕組みを徐々に全プロジェクトに対して展開していく予定だという。 「除外ファイル」の更新漏れを防ぐためにJenkins  また同社では、「除外ファイル」の更新漏れを防ぐ目的でもJenkinsを活用している。  除外ファイルとは、ステージング環境から本番環境へデプロイする際に更新したくないファイルを記述したリストのこと。この除外リストの更新差分をgitリポジトリで管理し、その内容を自動的に開発者にメール通知する仕組みをJenkinsで実装している。本番環境へのデプロイミスを事前に防止することが、その狙いだ。その効果はてきめんで、実際に除外ファイルの更新漏れの件数は激変、直近の1カ月では0件にまでなったという。 「除外ファイル」更新漏れの自動通知(鈴木氏の講演資料より)  クルーズでは現在、上記2つ以外にもさまざまな用途でJenkinsを活用しているが、最終的にはCIツールを核とした「開発のオートメーション化」にまで取り組みを高度化していきたいとしている。 テスト高速化にはJKS48が最も効果的、ミクシィ  ミクシィの五嶋壮晃氏は、「僕とJenkinsおじさんの360日戦争」と題したプレゼンテーションで、ミクシィにおいて行ったJenkins運用のさまざまな改善アプローチについて紹介した。 ミクシィ 五嶋壮晃氏 「Prove」でテストの並列実行  ミクシィでは、サービスを本番環境にデプロイする前には必ずJenkinsを用いたフルテストを実行している。このフルテストの規模は、テスト対象のPerlファイルが1万8000以上、テスト項目数25万以上という膨大なもので、テスト全体を実行するのに45分間を要していた。  同社では、このフルテストの時間をいかに短縮し、迅速なリリースを実現するかが長年の課題となっていた。これを解決するために、これまでもさまざまな施策が試みられてきたが、その1つがテストの並列実行だった。  Perlのテストの実行と、その結果を収集するために、同社では「Prove」を利用している。Proveにはオプションとしてテスト並列実行の機能がサポートされており、ミクシィではこれを使ってテストを並列実行し、テスト時間の短縮を図っている。 Jenkins×Perl(五嶋氏の講演資料より) テストの並列実行のためにFixtureを使うなど試行錯誤  しかし同時に、テストの並列実行には、並列実行されている各プログラムが共通データベースを同時アクセスした際のデータ不整合という問題がある。  この問題を解決するために、同社ではテストごとに個別のテスト用データベースをFixtureで生成・破棄するという方法をとった。これにより、テスト並列実行時のデータ不整合問題は解決する。 並列実行の問題とFixture(五嶋氏の講演資料より)  しかしその半面、テストのたびにデータベースを生成・破棄していては、処理オーバーヘッドが大きくなってしまう。これを解消するために同社では現在、Fixtureで生成したデータベースをキャッシュする機構の実装を検討している。  ただし、現時点ではまだ技術的なハードルが高く、実装コストと効果が釣り合うかどうかも不明確だという。  さらには、テストごとに多数の巨大モジュールを読み込む処理のオーバーヘッドも決して小さくないという。このオーバーヘッドを解消するために、親プロセスでモジュールをロードし、テストの並列実行をその子プロセスとして実行することで、テストプロセスでのモジュール読み込みを不要にするという方式が検討されている。  ただし、この方法も、モジュールを先読みしておくことでさまざまな不整合が生じる危険性があるという。 Jenkinsのスレーブを増やすのが最も効果的だった  そこで最終的に同社がとった方法が、単純にJenkinsのスレーブを増やし、より多くのノード上でテストを実行させるというものだった。最終的にはこの方法が最も効果が高く、48のノードを使ってフルテストを実行させたところ(五嶋氏は、これを「JKS48」と呼んでいた)、45分の実行時間が一気に8分にまで短縮された。  結果として、テスト実行におけるリソースの重要性をあらためて認識させられたという。 Jenkinsでアメーバピグは、いかほど品質向上できたのか  サイバーエージェントの丸山隆司氏からは、同社の看板サービスの1つ「アメーバピグ」におけるJenkins活用ケーススタディの紹介が行われた。 サイバーエージェント 丸山隆司氏  丸山氏がアメーバピグの開発プロジェクトに加わった2011年当時は、CI環境はおろか、テストコードもほとんど存在せず、デプロイはすべて手動。品質担保のための取り組みも「レビューのみ」という惨憺たる状態だったという。 Jenkinsを導入したが、増え続ける“警告”  こうした状況を改善するためにJenkinsを導入してみたものの、何と全プロジェクトで合わせて数千個もの警告が発生し、しかもその数がどんどん増え続けるという結果が出てしまった。  そこでまずは、本格的なCI環境を整備するとともに、もし危ないバグが見つかった場合には開発者を総動員してでも、とにかくその場ですぐに修正してしまうというルールを設け、その順守を社内で徹底させた。さらには、不要と思われる警告通知を除外し、より実践的な運用が可能になるよう、Jenkinsにさまざまな設定を施した。こうした取り組みにより、現在のコード品質管理体制はかつてと比べ大幅に強化されたという。 アメーバピグのコード品質管理におけるJenkins活用例(丸山氏の講演資料より) バッチ処理の制御にJenkins  加えて、同社ではバッチ処理の制御にもJenkinsを活用している。アメーバピグのサービスの裏側では57本のバッチが稼働しているが、かつてはcron起動とSpringBatchが混在していたり、あるいはバッチサーバを刷新したにもかかわらず古いサーバ上で動いているバッチが残っており、しかもそれが失敗しても通知が上がらないなど、バッチ実行環境の運用に多くの課題を抱えていた。  そこで同社は、すべてのバッチジョブをJenkinsで集中的に制御する仕組みに移行することで、こうした課題の解決を図った。その結果、バッチを安全・確実に実行できる環境が整備されたとともに、バッチジョブの稼働状況やアラート発生状況を一元的に管理できるようになったという。 アメーバピグのバッチ処理におけるJenkins活用例(丸山氏の講演資料より) 運用オペレーションをJenkinsで自動化  さらには、これまで多くを人手に頼ってきたサービス運用オペレーションをJenkinsで自動化することにより、サービス運用の人為ミスを減らす取り組みも進めている。具体的には、サーバ間や本番系/待機系間でのリソース差分のチェック作業をJenkinsで自動化したり、あるいは運用スケジュールのリマインダメールを自動送信するといった仕組みをすでに実現している。  今後は、リリースやデプロイ、本番系/待機系の切り替えなどといったタスクも順次Jenkinsによって自動化していき、サービス運用の品質をさらに高めていく予定だという。 参考資料  本イベントで使われた講演資料は、「第6回テックヒルズ:Let's study Jenkins~さまざまなケーススタディ~:資料まとめ」から一覧できるので、参照してほしい。 関連リンク 検索技術を使うなら知ってないと損する6つのこと~クックパッド、グリー、ぐるなび、CROOZは検索技術をどう使っているのか―テックヒルズ(モーショノロジー)2012 #1レポート スマホアプリ開発はHTML5/jQuery Mobileとネイティブどっちがいいの?~第2回テックヒルズまとめレポート FlasherはスマホやHTML5の世界にも踏み出せ~「第3回テックヒルズ」まとめレポート ユーザーを魅了するUIはまぐれでは生まれない~第4回テックヒルズレポート グリー・ドリコム・クルーズ・モバイルファクトリー・KLabの事例に見るGit移行のメリットと問題点まとめ~第5回テックヒルズ「Go to Git!~さらばSVN~」レポート 「イベントカレンダー+ログ」レポート投稿募集中! このレポート記事が掲載されている本サービス「イベントカレンダー+ログ」では、イベント登録者がレポートを投稿したり、資料を一覧できるまとめページを作成できます。新着レポートは一覧に表示され、こちらのRSSにも配信されるので、ぜひご活用ください。