私たちはマイクロサービスを構築するスクラムチームです。私たちのGitHubリポジトリは単一ブランチであり、私たち一人一人が1日数回、彼/彼女のコードをマスターに統合し、機能ブランチはありません。 Jenkinsパイプラインは、コードをコンパイルし、自動テストを実行し、静的コードスキャンのためにコードを他のサービスに提供し、さらにテストするためにCloudFoundryランドスケープ全体にソフトウェアをデプロイします。すべてのステップが成功すると、パイプラインが自動的にソフトウェアをAmazon Webサービスの本番スペースにデプロイします。私たちはボブおじさんのクリーンコードを実践し、90%以上のミューテーションカバレッジで信頼できるユニットテストを作成し、継続的デリバリーからのJez Humbleのアイデアを尊重します。私たちはすべてを正しく行っていると思います。
動かない。
ビルドの99%がパイプラインを通過する途中で失敗します。何週間もの間、速度はほぼ0です。
最初の衝動は、よりクリーンなコードの作成、より多くのテスト、赤いパイプラインへのプッシュの停止、より迅速なロールバック、根本原因の分析、事後分析などを行う必要があるということです。しかし、私たちはそこに行って、コード、実践、および文化を押しつぶして、それをすべて行ってきました。私たちは自分たちのチームを可能な限り能率化してスキルアップしました。
問題は、私たちのチームが制御できない理由でビルドが失敗することです:Jenkinsサーバー、Maven Nexus、npmレジストリ、コードスキャンサービス、Cloud Foundryランドスケープ、これらすべては社内の他のチームによって維持されています。個別に、関与する15のツールとチームはすべて素晴らしいものであり、パイプラインをブロックする可能性のある散発的な機能停止のみが数分から最大数日まで影響を受けます。しかし、組み合わせて、失敗の確率はランダムな失敗のほぼ不可解な壁になります。
この状況を改善するための戦略は何ですか?
いくつかの依存サービスの「散発的な停止」だけで99%のビルドが失敗するとは信じられません。おそらく、どのサービスが最悪の違反者であるかについての詳細な分析が必要であり、それらの所有者と通信してそれらの安定性を向上させるか、それらをより安定したオプションに置き換えます。
簡単な数学。各サービスがx%の確率で失敗し、ビルドでN個のサービスが順番に使用される場合、ランダムビルドが失敗する可能性は次のとおりです:1-(1-x)^N
。したがって、1%の失敗率と5つのサービスの場合、これは1-(1-0.01)^5 = 0.049
であり、約5%です。
別のアイデアは、「展開に必要」の依存関係を、有用な情報を提供するが展開を妨げない依存関係から分離することです。静的コード分析が思い浮かびます。展開には必要ありませんが、それは素晴らしい情報です。デプロイパイプラインの一部として実行する代わりに、別のパイプラインで非同期に実行して、開発者にレポートを提供します。
次に頭に浮かぶのは、単一のパイプラインの代わりに、「段階的」パイプラインを使用できるということです。このインスピレーションは、本 大規模なアジャイル開発への実用的なアプローチ から得られます Jez Hubleが参照することを好む 。そこでは、複数のフェーズを持つビルドパイプラインについて説明しています。それぞれが独自に実行でき、失敗した場合はそれより前に来たすべてを再起動する必要なく再起動できます。
技術的な回答
ここで必要な正確な概念はフォールトトレランスです。障害に強いパイプラインが必要です。もちろん、これはオープンエンドのエンジニアリング問題です。
最も明白なブルートフォースソリューションは冗長性です。つまり、パイプラインに冗長ノードがあり、何かが失敗した場合でも、引き継ぐことができる別のサーバーがあります。
考慮すべきもう1つの重要だが無視されがちな側面は、回復モードです。障害が発生した場合、パイプラインは中断したところから再開しますか、それとも常に最初から再開しますか?ビルドタスクはべき等であり、問題なく繰り返し実行できますか、それとも完全なロールバックをトリガーして毎回システムをクリーンアップする必要がありますか?これは、継続的な問題を抱えているプロセスに大きな違いをもたらす可能性があります。
ビジネスの答え
他のチームは、高品質で安定したパイプラインを利用できない原因となっている問題を可視化するのに役立つ必要があります。ダウンタイムのメトリックを収集し、ビジネスへの実際のコストを見積もることによって、それらを支援します。これは、ビジネスのニーズを満たすために追加のリソース(スタッフ、ハードウェア、トレーニング、またはサードパーティのサービス)を取得するために、彼ら自身の経営陣と訴訟を起こすのに役立ちます。また、内部のSLAを調整して同意し、それを満たす能力を追跡することにより、成功の測定を支援できます。
言うまでもなく、これは逆効果になることが多いので、敵対しないでください。
不安定なネットワークサービスを放棄し、ローカルで作業を行います。
自分のPCで単体テストを行うことができ、バグのあるコードをチェックインする前にそれを行うことができます。チームが制御できるリポジトリにサードパーティのコードがすべてある場合、Mavenリポジトリは必要ありません。ソースをビルドするのにJenkinsは必要ありません。代わりにIDEを起動して、クリーンとビルドを行います。 「クラウド内」である必要がない場合は、チーム内でローカルに実行し、管理を続けてください。
追加ボーナス:5年間で、顧客が戻ってきて、長い間使用されていなかったと思われる製品の更新を要求した場合、もはやそれを構築する方法がないことを知りたくありません。他の複数の人々によって管理されているサーバーの混乱に依存することは、問題を求めています。これらはすべて廃止されるか、古いプロジェクトと互換性のない新しいバージョンに移行されます。 すべて必要なものがローカルで構成されている場合は、はるかに優れています。そのため、すべてをチェックアウトして、文書化された手順に従って、最初からすべてを構築できます。