マイクロサービスはシンプルな分散ログ追跡を実装します

マイクロサービスはシンプルな分散ログ追跡を実装します

最近、プロジェクトに簡単な分散リクエスト追跡機能を追加したいと考えています。フロントエンドからゲートウェイへのリクエストを開始し、ゲートウェイから Spring Cloud マイクロサービスを呼び出します。これらのプロセス中に、ログから分散 ID リンクが表示されることを期待します。問題のトラブルシューティングを容易にするために、リクエスト ID を通じてリンク全体を追跡できます。

[[378163]]

既存のソリューションとしては、当然ながら SkyWalking、Spring Cloud Sleuth、Zipkin などのコンポーネントを使用することになります。ただし、ログクエリを容易にするために、さまざまなサービスで常に実行できる ID を記録することが主な目的であるため、複雑なコンポーネントをあまり導入したくありません。最終的に、MDC を介してログに追跡 ID を出力し、Feign と RestTemplate のマイクロサービスにリクエスト ID を渡すことにしました。

主にいくつかのステップが含まれます:

  • フロントエンドからリクエストIDを生成し、それをリクエストヘッダーに追加してゲートウェイに持ち込む
  • ゲートウェイは WebFilter を通じてメッセージを傍受し、MDC に参加してログに出力します。
  • FeignとRequestTemplateでは、リクエストIDをHTTPヘッダー内のマイクロサービスに渡します。
  • 各マイクロサービスもWebFilterによってインターセプトされ、MDCに追加され、ログに出力されます。

MDCC

MDC (Mapped Diagnostic Context) は、マルチスレッド条件下でのログ記録を容易にするために Log4j と Logback によって提供される機能です。 MDC は、キーと値のペアを追加できる、現在のスレッドにバインドされたハッシュ テーブルとして考えることができます。

MDCの主な業務:

  • 値を MDC に設定します: MDC.put(key, value);
  • MDC から値を取得します: MDC.get(key);
  • MDC の内容をログに出力します: %X{key}

TraceIdツールクラスを追加しました

まず、TRACE_ID の定数値と TRACE_ID の設定および生成方法を定義する TraceIdUtils ツール クラスを追加します。以降のコードはこの推定クラスを通じて操作されます。

  1. org.apache.commons.lang.RandomStringUtils をインポートします。
  2. org.apache.commons.lang.StringUtils をインポートします。
  3. org.slf4j.MDC をインポートします。
  4.  
  5. パブリッククラスTraceIdUtils {
  6. 公共 静的最終文字列 TRACE_ID = "traceId" ;
  7. プライベート静的最終int MAX_ID_LENGTH = 10;
  8.  
  9. /**
  10. * トレースIDを生成する
  11. */
  12. プライベート静的文字列genTraceId() {
  13. RandomStringUtils.randomAlphanumeric(MAX_ID_LENGTH)を返します
  14. }
  15.  
  16. /**
  17. * トレースIDを設定する
  18. */
  19. 公共 静的void setTraceId(文字列traceId) {
  20. // パラメータが空の場合は新しいIDを生成する
  21. トレース ID = StringUtils.isBlank(traceId) ? genTraceId(): トレースID;
  22. //MDCにtraceIdを入れる
  23. MDC.put(TRACE_ID、 StringUtils.substring (traceId、-MAX_ID_LENGTH));
  24. }
  25.  
  26. /**
  27. * トレースIDを取得
  28. */
  29. 公共 静的文字列 getTraceId() {
  30. // 得る
  31. 文字列traceId = MDC.get(TRACE_ID);
  32. // traceIdが空の場合は新しいIDを生成する
  33. StringUtils.isBlank(traceId)を返しますか? genTraceId(): トレースID;
  34. }
  35. }

WebFilter経由でTraceIdフィルターを追加する

リクエスト ヘッダーから TraceIdUtils.TRACE_ID に対応する値を取得するために、GenericFilterBean を追加します。この値は、フロントエンドがリクエストを開始するとき、またはマイクロサービス間で渡されるときに伝達されます。値がない場合、TraceIdUtils.setTraceId によって値が生成されます。

  1. org.springframework.core.annotation.Orderをインポートします
  2. org.springframework.web.filter.GenericFilterBean をインポートします。
  3.  
  4. @WebFilter(urlPatterns = "/*" , filterName = "traceIdFilter" )
  5. @注文(1)
  6. パブリッククラスTraceIdFilterはGenericFilterBeanを拡張します{
  7. @オーバーライド
  8. public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) は IOException、ServletException をスローします {
  9. //traceIdの初期化
  10. HttpServletRequest 要求 = (HttpServletRequest) リクエスト;
  11. 文字列 traceId = req.getHeader(TraceIdUtils.TRACE_ID);
  12. TraceIdUtils.setTraceId(traceId);
  13. // 後続のフィルターを実行する
  14. フィルターチェーン.doFilter(リクエスト、レスポンス);
  15. }
  16. }

SpringBoot スタートアップ クラスに @ServletComponentScan アノテーションを追加することを忘れないでください。そうしないと、カスタム フィルターは有効になりません。 「com.yourtion.trace.filter」は、TraceIdFilter が配置されているパッケージ名です。

  1. @ServletComponentScan(basePackages = "com.yourtion.trace.filter" )
  2. @SpringBootアプリケーション
  3. パブリッククラスMyApplication {
  4.  
  5. 公共 静的void main(String[] args) {
  6. SpringApplication.run(MyApplication.class、引数);
  7. }
  8. }

FeignにTraceIdを追加する

@FeignClient プロキシ クラスは実行時に Spring コンテキストの RequestInterceptor を使用するため、独自のインターセプターをカスタマイズして Spring コンテキストに挿入し、リクエスト コンテキストにカスタム リクエスト ヘッダーを追加できるようにします。

  1. feign.RequestInterceptor をインポートします。
  2. feign.RequestTemplate をインポートします。
  3. org.springframework.stereotype.Service をインポートします。
  4.  
  5. @サービス
  6. パブリッククラスFeignInterceptorはRequestInterceptorを実装します{
  7. @オーバーライド
  8. パブリックvoid 適用(リクエストテンプレート テンプレート) {
  9. template.header(TraceIdUtils.TRACE_ID, TraceIdUtils.getTraceId());
  10. }
  11. }

RestTemplate に TraceId を追加する

一部のリクエストは RestTemplate を通じて開始されます。以前は、RestTemplateConfig 構成クラスを独自に実装していました。今回は、関連する構成に以下を追加しました。

  1. RestTemplate restTemplate = builder.additionalInterceptors((リクエスト、本文、実行) -> {
  2. リクエスト.getHeaders()。 add (TraceIdUtils.TRACE_ID, TraceIdUtils.getTraceId());
  3. 実行を返します。execute (リクエスト、本文) ;
  4. })。建てる();

この時点で、リンクへの TraceId の追加は完了しており、残っているのはそれをログに印刷することだけです。

Log4j2のレイアウト形式を変更する

MDC に traceId を出力するために、ログのレイアウト形式を変更します。

  1. <! -- 元の形式 -->  
  2. <PatternLayout パターン = "%5p %c:%L - %m %throwable{セパレーター( --> )}%n" />
  3.  
  4. <! -- traceId フォーマットを追加 -->  
  5. <PatternLayout パターン = "%5p traceId:%X{traceId} %c:%L - %m %throwable{separator( --> )}%n" />

この時点で変更は完了です。

<<:  2021 年に組織が完璧なクラウド コンピューティング戦略を作成するための 3 つの柱

>>:  IBMはまたもや戦いに敗れた。クラウド コンピューティングは Big Blue に悪影響を及ぼしていますか?

推薦する

粘り強さが報われます。Flarum が最初の RC1 安定候補バージョンをリリースしました。

Flarum は、エレガントで軽量 (100K 以下) な PHP フォーラム プログラムとして、私...

アリババクラウド:理論コンピューティングの最高賞を受賞したマリオがDAMOアカデミーに入学

Alibaba Cloudの公式ニュースによると、ハンガリー系アメリカ人のコンピューター科学者であり...

Google Urchin の設定: イベント トラッキングの設定方法

イベント トラッキング (TrackEvent) を使用すると、Flash Web サイトの要素、埋...

WeChatアカウントMeifuhuiの偽のPRと実際のマーケティングパズルを見る

少し前に、WeChatのユーザー数がすでに2億7000万人に達していると報じられました。WeChat...

glideservers-4 USD/2 GB RAM/100 GB HDD/20 TB トラフィック/DDoS 高度保護

glideservers.com は、カナダのデータセンターに特別価格の OpenVZ ベースの V...

現在の検索エンジンの状況では、学生はウェブサイトの最適化を行う際に禁止されている領域を避ける必要がある。

ウェブサイトの継続的な発展に伴い、多くの学生がウェブサイト最適化の業界に魅了されてきました。しかし、...

予算vm-$92/E3-1230v3/16gメモリ/120gSSD/20Tトラフィック/最適化されたライン

budgetvm の最新割引コードが 2 つあります。budgetvm の特別価格のサーバーのみ対象...

Emlogウェブサイト構築プログラムは突然現れ、その機能的な利点は欠点を上回り、それが鍵となる

現在、特に独立系ブログサイト向けの無料ウェブサイト構築プログラムが数多くあります。WP、zblogな...

AWS、深圳に大中華圏で2番目のIoTラボを開設

AWS は本日、大中華圏で 2 番目となる IoT 研究所を深圳に設立すると発表した。このラボは、A...

工業情報化省:電子商取引の発展を加速

5月23日から25日まで、工業情報化部は「全国電子商取引・物流情報化推進会議及び全国中小企業情報化・...

「3つの数字」で200万元を稼ぐ、厦門のドメイン名投資家が儲ける秘密を明かす

東南網-海峡報は8月3日(記者張順、インターン荘文沙)に、当初60元で登録されたドメイン名が現在5万...

Baiduのウェブサイトの包含とKステーションのルールに関する深い理解

Baiduのウェブサイトの包含とKステーションのルールに関する深い理解はじめに:ネットユーザーから、...

【事例】Meituan.comのキャンパスチャネル構造の機能開発と分析を理解するための17枚の写真!

Meituan.comのキャンパスチャネル構造の機能の開発と分析を理解するための17枚の写真 --&...

ライブ放送ベースダブル11:アンカーはトラフィックを競うことを望まない

「私たちにとって、ダブル11は背景を変えるだけの問題です。根本的な変化は特に大きくはありません。」ダ...