ヘルスチェック。構造化ログ。ジッター付きのリトライポリシー。誰でも「.NET Coreサービス向けの本番環境対応チェックリスト」を書くときに同じリストを挙げますが、そのどれも間違ってはいません。しかし、サービスが共有ドメインモデルの中に存在している場合は、最初に挙げるべきリストではありません。
今月、私は誰もが挙げるチェックリストに載っていない作業に時間を費やしました。私たちのドメインプロジェクトをバージョン管理されたNuGetパッケージに変換し、それをプライベートなArtifactoryフィードにプッシュし、バージョン番号をバンプして、そのバンプをそのパッケージを参照しているすべてのマイクロサービスリポジトリに波及させることだけを仕事とするボットを構築したのです。
それは配管作業のように聞こえます。実際、配管作業です。しかし、それは「本番環境対応」が単一のサービスだけでなく、サービス群全体にとって意味を持つかどうかを決める配管作業なのです。
この作業が解決する問題は次のとおりです。共有ドメインロジック(エンティティ、値オブジェクト、複数のサービスが必要とするビジネスルール)をモノリスから切り出してライブラリにすると、以前にはなかった依存関係グラフが生まれます。パッケージを利用するすべてのサービスは、そのライブラリのどのバージョンを実行しているかについて、明示的または暗黙的に意見を持つことになります。私たちが適切にパッケージ化する前は、その意見はコピー&ペーストと暗黙知によって強制されていました。実際には、どのサービスがどのバージョンのどのルールを持っているかを知る者はいませんでした。
NuGetはその半分の問題を解決します。Artifactoryはパッケージが組織外に漏れないようにプライベートフィードを提供し、誰がいつ何をプルしたかの監査証跡を残します。これらの要素は単独では興味深いものではありません。興味深く、かつこのアプローチが役に立つのか、それとも静かに破綻をもたらすのかを実際に決めるのは、ボットの方です。
ボットはドメインパッケージリポジトリを監視します。新しいバージョンがリリースされると、下流のすべてのマイクロサービスリポジトリに対して参照をバンプするPRを開きます。それがボットの仕事のすべてです。賢い工夫はなく、かつては手作業で行われ、半分の確率で忘れられていた依存関係のバンプをスクリプト化したものです。
そしてここで、「マイクロサービスを正しく行う」という投稿の半分で見られる意見に私は異を唱えます。そのバンプを自動化するのは良いことですが、それはあなたが内部のDependabotを構築したことを認める場合に限ります。そして内部のDependabotには、外部のDependabotと同じ規律が必要です。「これは自分たちのコードだから、キャッチできる」という理由でほとんどのチームがスキップする規律です。
あなたはそれを確実にキャッチすることはできません。
ボットがPRを開き、誰かがドメインパッケージのバンプをロギングライブラリのパッチバンプと同じように機械的にマージしてしまうなら、あなたは誤ったsemverバンプが1ダース以上のサービスに同じ午後に破壊的変更をもたらす一歩手前にいます。共有ドメインライブラリは末端の依存関係ではありません。それは負荷を支えるものです。そこでメジャーバージョンをバンプすることは、スキーママイグレーションと同じ scrutiny(精査)に値します。なぜなら、機能的にはそれがスキーママイグレーションだからです。
したがって、本当に問うべき本番環境対応の質問は「バージョンをバンプするボットがあるか」ではなく、「パッケージを利用するすべてのサービスに、そのPRがマージ可能になる前に、新しいパッケージバージョンに対して独自の統合スイートを実行するCIゲートがあるか」です。私たちは初日からそのゲートを持っていませんでした。ボットがPRを開き、ビルドがグリーンであることは「コンパイルできる」ことを意味し、マージボタンがそこにありました。それは本番環境対応ではありません。それは本番環境対応という装いをしたスピードです。
ゲートを正しく設定するには、意図的にボットの速度を落とす必要がありました。ボットは今でもすぐにPRを開きますが、コンシューミングサービスの完全な統合スイートが新しいパッケージに対してパスするまで、マイナーバージョンバンプを超えて自動マージすることはなくなりました。ユニットテストだけでなく、誰も実行したがらない遅いテストを含むスイート全体がパスする必要があります。この1つの変更により、障害モードは本番環境でのサイレントブレイクから、誰かが確認しなければならない赤いCIチェックに変わりました。ワクワクするものではありません。正しいことです。
ここには本当のトレードオフがあり、私はそれを否定しません。ドメインの修正がすべてのサービスに到達する速度が遅くなります。古いコピー&ペーストの世界では、共有値オブジェクトのバグ修正は、誰かが更新を思い出したサービスに、思い出したときに到達していました。遅いですが、誰のビルドもそれが原因で夜間に壊れることはありませんでした。新しい世界では、修正はボットに接続されたすべてのサービスに素早く伝播し、ローカルの前提と修正が衝突するサービスは、3週間後の障害チャンネルではなく、CIで即座にそれを知ります。
私は後者の障害モードをいつでも選びます。速くて可視性がある方が、遅くて不可視であるよりも優れています。しかし、そのコストは現実のものであり、それを否定することは、これらのシステムが金曜日の午後5時にバンプがビルドを壊したときに、チームの信頼を失う原因となります。
もう一つ率直に言っておくべきことがあります。このどれも、通常のチェックリストに取って代わるものではありません。サービスには依然としてヘルスチェック、合理的なリトライポリシー、そしてリクエスト全体で実際に相関付けられるログが必要です。パッケージングとバージョンバンプの自動化がもたらすものは、たまたま注意深くテストした1つのサービスだけでなく、サービス群全体に真である本番環境対応チェックリストです。サービスは、そのリストのすべての項目を個別にパスしても、共有ライブラリが下から誰もフラグを立てなかった方法で変更された瞬間にダウンする可能性があります。
共有.NETドメインライブラリを構築していて、メジャーバージョンバンプを誰がレビューするのか、そのバンプがマージされる前にどのテストスイートがパスしなければならないのか、そしてボットのPRが2つ下流のサービスで何かを壊したときに誰が責任を負うのかを決めていないのであれば、あなたには本番環境対応のサービス群がありません。あなたには、一度だけ本番環境対応のサービスがあり、そしてそれがいつ真実でなくなるかを静かに決めているボットがいるだけです。
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.