大規模なモノリシック アプリケーションでは、明確な所有権がないため、エラーの追跡と監視が効果的でないことがよくあります。このガイドでは、ドメイン注釈を通じて責任を割り当てる構造化されたアプローチを提案することで、この問題に対処します。
複数のチームで構成された大規模なモノリシック システムの効果的な監視を設定するのは難しい場合があります。明確な所有権がないと、エラー追跡は一般的なものになり、無視されることがよくあります。1 つの解決策は、オンコール エンジニアに監視アラームに応答するチームを特定させることです。ただし、より効率的なアプローチは、各ログと Datadog スパンにドメインとチームの情報を含めることです。
ドメイン注釈を理解する
アプリケーションのさまざまな部分を担当するチームを追跡するために、ドメイン アノテーションと呼ばれるシステムを使用しています。ドメイン アノテーションは、アプリケーションのコードの各部分にラベルを付け、誰が何を担当しているかを明確に示します。これにより、責任の管理において明確な組織と説明責任が提供されます。
ドメインアノテーションを使用する利点
ドメイン アノテーションは、モノリシック アプリケーション内でチームの責任を追跡するための明確で体系的な方法を提供します。コードの一部にドメイン アノテーションをタグ付けすることで、次のことが可能になります。
- ログとトレースの管理を簡素化: チームの責任などの特定の基準に基づいてログとトレースをフィルタリングし、問題を迅速に特定して解決できるようにします。
- 正確な追跡を維持: 注釈はチーム名ではなくドメインに関連付けられているため、チームの責任の変更にシームレスに適応します。
- 説明責任の強化: 各ドメインを担当するチームを明確に定義し、組織と対象を絞った監視を改善します。
- 監視効率の向上: 正確な説明責任を提供し、全体的な効率を高めることで、より優れた監視プラクティスを促進します。
ドメイン注釈処理
効率的な監視と追跡可能性を確保するために、各 Web リクエストには適切なドメイン情報がタグ付けされます。これは、 DomainProvider
、 DomainSpanService
、 DomainMdcProvider
、 DomainHandlerInterceptor
などの複数のコンポーネントの連携によって実現されます。
次の図に、プロセスの概要を示します。
主要コンポーネントの説明
- DomainProvider : 特定のハンドラー メソッドまたは Bean に関連付けられたドメインを識別します。AOP (アスペクト指向プログラミング) および MVC (モデル ビュー コントローラー) 呼び出しでドメイン注釈を見つけるのに役立ちます。
- DomainSpanService : トレース システムの作業単位であるスパンにドメイン タグを追加します。このサービスは、各スパンに適切なドメイン情報がタグ付けされるようにします。
- DomainMdcProvider : ログエントリにコンテキスト情報をタグ付けできるログ記録フレームワークの機能である MDC (Mapped Diagnostic Context) 内のドメイン タグを管理します。
- DomainHandlerInterceptor : Web リクエストをインターセプトし、各リクエストに適切なドメイン情報がタグ付けされるようにして、監視と追跡可能性を向上させます。
これらのコンポーネントの詳細な実装は共有ライブラリにカプセル化され、大規模なモノリシック アプリケーションで Web リクエストをタグ付けおよび監視するための再利用可能なソリューションを提供します。
誰がどのコードを所有しているかを整理する
クラス レベルでの所有権の定義は、ドメイン アノテーションを使用すると簡単です。トップレベルのアノテーションをメイン クラスに適用すると、所有権はそれらのクラス内のすべての詳細リソースに伝播します。各チームは、所有するクラスに適切なドメイン アノテーションのラベルを付けることができるため、すべてのメソッドにマークを付ける必要がなく、明確さと説明責任を確保できます。
複数のチームが 1 つのクラスのコードを所有しており、すぐにリファクタリングすることが適切でない場合は、クラス レベルのアノテーションよりも優先される異なるドメイン アノテーションを使用して個々のメソッドをマークできます。これにより、特定のメソッドを異なるチームに割り当てることができ、全体的な構造を複雑にすることなく柔軟性が得られます。
注釈でサポートされていないケースの克服
ドメイン アノテーションは非常に便利ですが、まれに使用できない場合もあります。たとえば、Quartz の AOP ロジックとドメイン アノテーションに使用される AOP ロジックが衝突したため、Quartz ジョブの作成がドメイン アノテーションとシームレスに機能しないという問題が発生しました。
直接注釈を付けることができないジョブとプロセスについては、ジョブ実装で DomainTagsService を直接使用しました。このアプローチにより、ジョブの実行ロジック内でドメイン タグを手動で追加できるようになりました。
以下は、DomainTagsService を Quartz ジョブに統合した例です。
final override fun execute(context: JobExecutionContext) { domainTagsService.invoke(domain) { withLoggedExecutionDetails(context, ::doExecute) } }
人工サービスによる監視と可視性の向上
各チームに別々のサービスを用意すると、監視と所有権の面で大きな利点が得られますが、モノリスを分割するためのコストと労力が高く、追加の開発費用が発生する可能性があります。モノリスをモジュールに分割すると Gradle でビルド時間が短縮される可能性があることを考慮すると、多くの場合、モノレポを維持するのが最も効率的なソリューションになる可能性があります。
人工サービスの導入
Datadog で各チームのアクティビティの監視を簡素化するために、異なるチームの範囲に人工サービス名を割り当てることができます。このアプローチにより、Datadog の監視ツールで各チーム専用のセクションが確保されます。管理するサービスが多数ある場合、人工サービス名を使用すると混乱を招く可能性がありますが、バックエンド サービスの数を制限すれば管理しやすくなります。これらの人工サービス名にプレフィックスを追加すると、Datadog セットアップの整理と明確さが維持され、異なるチームとその責任を区別しやすくなります。
スクリーンショットの代わりに図を使用しますか?? ワーカー/Webアプリはここでは意味がありません
ログに人工的なサービスを使用しないのはなぜですか?
ログに人工的なサービス名を使用すると、同じログ エントリが異なるサービスに表示される可能性があるため、混乱が生じる可能性があります。
たとえば、同じ認証サービスを使用する 2 つのエンドポイントを考えてみましょう。これらのエンドポイントに異なるドメインが注釈付けされている場合、認証ロジックは異なる人工サービスの下にログを生成します。ログは複数のサービス名で表示されるため、ログを調査するときに混乱が生じる可能性があります。この問題を回避するには、トレースで集約されるスパンにのみ人工サービス名を適用して、混乱を減らすことをお勧めします。
それは意味があるのでしょうか?意味がないと思います
この問題を視覚的に表すと次のようになります。
監視とダッシュボードにおける人工サービスの使用
人工サービスを使用すると、APM トレースを操作できるだけでなく、長期間保存される Datadog Metrics でサービス別にフィルタリングできるため、長期間にわたる変更を追跡できます。
モニターの例
以下は、クエリで人工的なサービス名konsus-assets
を使用する Datadog のモニターのスクリーンショットです。
ダッシュボードの例
以下は、フィルターで人工的なサービス名konsus-assets
を使用する Datadog のダッシュボードのスクリーンショットです。
監視戦略で偽のサービスを活用することで、モノリシック アプリケーション内の各チームのアクティビティの可視性と説明責任を強化できます。このアプローチにより、チーム固有のモニターとダッシュボードの作成と維持のプロセスが簡素化され、Datadog での監視がより効果的かつ組織的になります。
まとめ
ドメイン アノテーションは、Datadog でのモノリシック アプリケーションの監視を簡素化する簡単な方法を提供します。この戦略を実装することで、ログ、スパン、メトリックの管理性が向上し、監視設定が特定のチームに合わせたツールに変わります。これにより、説明責任と組織が改善され、アプリケーション全体のトラブルシューティングとパフォーマンス分析がより効果的かつ効率的に行えます。
重要なポイント
- 所有権と説明責任の強化: コードの一部にドメイン注釈を付けることで、各ドメインを担当するチームを明確に定義できます。これにより、組織化と対象を絞った監視が容易になります。
- ログとトレースの管理の改善: ドメイン注釈を使用すると、チームの責任などの特定の基準に基づいてログとトレースの両方をフィルタリングできるため、問題を迅速に特定して解決できます。
- 人工サービスによる柔軟性: スパンに人工サービス名 (ログではない) を使用すると、ログが明確になり、実際の発生元まで追跡可能になり、混乱を回避できます。
- 統合の課題を克服する: Quartz などの特定のジョブ実行フレームワークなど、注釈を直接適用できない場合は、ジョブ実装で
DomainTagsService
などのサービスを直接使用することで、ドメイン固有の監視を維持できます。
ドメイン注釈を使用するためのステップバイステップのアプローチ:
ドメインとチームを定義する
それはlibで変わります!!!
アプリケーション内のさまざまなドメインとチームを表す列挙型を作成します。
-
@Domain
は、クラスまたは関数に適用して、特定のドメイン値でマークできるアノテーションです。 -
DomainValue
、それぞれがチームに関連付けられたさまざまなドメインを表す列挙型です。 -
Team
、アプリケーションで作業しているさまざまなチームを表す列挙型です。
@Retention(AnnotationRetention.RUNTIME) @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) annotation class Domain(val value: DomainValue) enum class DomainValue(val team: Team) { USER_MANAGEMENT(Team.TEAM_A), PAYMENT_PROCESSING(Team.TEAM_B), NOTIFICATIONS(Team.TEAM_C) } enum class Team { TEAM_A, TEAM_B, TEAM_C }
-
クラス(および必要に応じてメソッド)に注釈を付ける
@Domain(DomainValue.USER_MANAGEMENT) class UserService { @Domain(DomainValue.PAYMENT_PROCESSING) fun processPayment() { ... } }
サポートされていないケースの処理
直接注釈を付けることができない場合は、
DomainTagsService
直接使用してロジックをラップします。fun executeNotSupportedByAnnotationsLogic() { domainTagsService.invoke(domain) { executeLogic() } }
Datadogで監視
モニター、ダッシュボード、APMトレースのフィルタリングに人工的なサービスフィルターを使用する
これらの手順に従うことで、モノリシック アプリケーションにドメイン注釈を効果的に実装し、監視、説明責任、全体的な効率を向上させることができます。