Blog株式会社マネーフォワード公式開発者向けブログです。技術や開発手法、イベント登壇などを発信します。サービスに関するご質問は、各サービス窓口までご連絡ください。2016-02-17マネーフォワードのビルド・リリース改善こんにちは。インフラエンジニアの村上です。サービスのインフラの中でも物理的なものからOS・ミドルウェア・アプリケーションのメンテナンス・ビルド・リリース・運用まで幅広く関与しています。その中で現在取り組んでいるビルド・リリースの改善をご紹介したいと思います。何をしたか?■ビルド・リリースのツールをshellからcapistranoへ乗せ換えをした。■ビルド・リリースフローを見直した。現状の問題点マネーフォワードの家計簿サービスがサービスインしてから、早3年程経っており、当時は小さかったサービスもお陰さまで大きくなってきました。サービスも複数になり、少しづつ機能を追加/改修されてきました。スクリプトも複雑になるにつれて以下の様な問題点が出てくる様になりました。5~10分程度)■サービスが増えた時に対応しずらい(改修しづらい)■リリース作業のステップ数が多い今回の改修においては、以下を重要点として進める事にしました。■スピード感のあるリリースが出来る事。■カスタマイズ性の向上/フレームワーク化を進める事。実現の為にやったことまずは、ビルド/リリースのフローを見直しました。今まではMergeしてから実際にリリース完了までが長く、開発が進むに連れてビルド時間も伸び、エンジニアがチェックを完了するまでの時間を長く拘束する事がありました。エンジニアは、MergeしてJenkinsを実行してから完了まで全てにおいてリリースを頭の隅においておく必要がありました。新リリースフローでは、Mergeした時点でビルドが自動で開始され、アーカイブファイルが各サーバーで展開される所まで勝手に行われます。エンジニアは、準備が完了した時点で通知を受けるので、それに対してSwitchの指示をする事で15秒程度でリリースが終わる様になります。この様にした理由は、ビルド/リリースの処理時間のチューニングの頭打ちが見えていた為です。処理時間が減らせないのであれば、フローを変える事でスピード感を維持する事にしました。Staging環境と同じアーカイブファイルを利用する様にすれば、ステージング確認中に本番での配置まで終わるので、Stagingでの動作確認完了と同時に本番もSwitchという様な事が出来る様になります。ここまでくればリリースの為に何かを待つという事はなくなり、スピード感があるリリースが出来る様になります。ツールの開発リリースツールに使う言語・ツールは数多ありますが、弊社の開発体制/使用言語を考慮しRubyベースのCapistranoを採用しました。installを行うので、NWコストが高くスケールしないのと、継続的Deploymentの鉄則であるテストと同じモジュールを使う。いう思想からはズレてしまうので今回はタスクを新規に実装しなおしています。InstallはJenkins上で担い、各サーバーにはリポジトリサーバーを経由して同じものを配布する様にしています。開発にあたってCapistranoの構成は以下の様にしました。Capfileは全アプリケーションで1つにしています。Gemfileを置いておくことでCapistranoの実行環境をどのサーバでも作れる様にしました。準備しますが、弊社の場合はアプリケーション毎に<#appname>_deploy.rbを作成しています。各アプリケーションのフォルダにdeploy.rbを配置する事で、lib/tasks配下のロジックを共通で使える様にしました。実行時のコマンドイメージは以下になります。ROLESはアプリケーション毎に配布先が違う場合に使います。<#environment>.rbでサーバーには<#appname>をroleとして設定しておく事で、実行時にROLES=を指定すれば自動的に配布先が確定します。引数チェック等をここでやっています。switch.rake<#appname>_deploy.rbで実装するタスクは以下の様にしています。呼び出す側がAPP毎の処理の違いを意識しない様にしています。ビルド処理を実行し、パッケージ(圧縮ファイル)を作成します。アプリケーションを各サーバーに配布し、パッケージを解凍します。アプリケーションを最新に切り替えます。アプリケーションをロールバックします。古いアプリケーションファイルを削除します。上記タスクを実行時の共通のコマンド体系とし、実際の処理はさらにそこから呼び出しをしています。個別の処理(例えばconfの差替とか)がある時は、invokeで呼び出している処理を取り除いたり、足したりします。フォルダやGitへの接続などを確認します。ソースをCloneしてきます。installを実行します。成果物をtar.gzにします。ストレージに送ります。(tar.gzとbundleフォルダを転送しています。フォルダやサーバーへの接続などを確認します。各サーバーにファイルをダウンロードして配置し、解凍します。bundleフォルダも同期します。installを実行します。(ここでは新規にDLされる事はありません。シンボリックリンクを切り替えます。シンボリックリンクを戻します。アーカイブを貯めるストレージを掃除します。配布先サーバー上の古いファイルを掃除します。endこうする事で、アプリケーション毎にやりたい処理/やりたくない処理を分ける事が出来、同じ処理は共通化する事が出来る様になりました。アプリケーション固有のロジック、環境固有のパラメーターを作りたくなった時は、このファイルに書く事で共通化せずに実装する事が出来ます。良かった所Capistranoのフレームワークを使用する事で、Shellに比べると非常に可読性高くかつ疎結合になりました。SSHの部分等、実装したくない所はCapistranoが担ってくれたのが大きかったと思います。不具合/カスタマイズも非常にやりやすくなりましたし、エンジニアの作業ステップ数も減りそうです。タスク毎にテストを書けば、本ツールのCIテストも実装出来そうです。悪かった所GUI実行を残す為、今回はJenkinsを採用しました。GithubWebhookも受けられるし、GUIも提供できる、Capistranoも呼び出せるので非常に便利ですが、Jenkins自体のメンテナンスや改修は相変わらずの手間で、そこからはぬけ出す事は叶っていません。今後このビルド・リリースのシステムは現在試験導入中であり、全てのサービス/全サーバーで導入できているわけではありません。MigrationやChatOpsの部分は実装中の所もありますが既存サービスに影響を与えない様にしながら、順次切替を行っていく予定です。非常に参考にさせていただきました。MavenはJavaのツールになりますが、ビルド・リリースのフローをフェーズ(ゴール)で分けるという考え方と実装を持ち込んだ偉大なツールです。今回もタスクの分割はMavenのフェーズを参考にいたしました。Deploymentsを参考にさせていただきました。エンジニアはSwitchの部分だけ担い、それ以外はバックグラウンドの時間で処理を終わらせるという視点は素晴らしいと思い、採用させていただきました。最後にマネーフォワードでは、新技術や新しい考え方を取り入れながら、最高のサービスを提供する為のプラットフォームを整備するインフラエンジニアを募集しています。ご応募お待ちしています。読者になるこのブログについてはてなブログをはじめよう!moneyforwardDevさんは、はてなブログを使っています。ブログを報告する引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。