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

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

最近、プロジェクトに簡単な分散リクエスト追跡機能を追加したいと考えています。フロントエンドからゲートウェイへのリクエストを開始し、ゲートウェイから 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 に悪影響を及ぼしていますか?

推薦する

電子商取引ミニプログラムはどのようにマーケティング作業を実行するのでしょうか?

月収10万元の起業の夢を実現するミニプログラム起業支援プラン近年、伝統的な小売業界と伝統的な電子商取...

iwebfusion: 旧米国データセンター、219 ドル、2*e5-2699v4 (44 コア)/384G メモリ/1T NVMe/25T トラフィック、オプションのデータセンター 5 つ

2001年に創業した超老舗のアメリカのサーバー業者iwebfusionが、2017年に自社のサーバー...

クラウドファンディングを解読する: 初期段階のウェブサイトは変革に忙しく、収益モデルはまだ模索中

【概要】クラウドファンディングというレッテルを剥がす時期は過ぎ去り、本来のエクイティ型クラウドファン...

ブラック 5: Hostgator - 25% オフ / ホスティングは月額 1.24 ドルから

11月28日午前0時(米国中部時間、北京時間11月28日午後2時)から24時間、仮想ホスティングが2...

2022年雲奇会議開幕、アリババの張勇氏:より先進的な技術でより大きな責任を担う

11月3日に開幕した2022年雲奇カンファレンスで、アリババの張勇会長兼CEOは、テクノロジーは過去...

CNドメイン名が個人登録を再開、市場の可能性はまだあるが、まだ長い道のり

Admin5 Webmaster Networkは6月6日、CNNICが5月28日に新しいドメイン名...

ウェブサイト分析: 60 秒間滞在するとコンバージョンの機会が増える

最近、いくつかのデータを調べて、さまざまな業界の Web サイトを比較しました。ほとんどの Web ...

国内のクラウドコンピューティング製品の中で最高のものはどれですか?比較のための5つの次元

この記事は製品に関する記事であり、対象顧客はクラウド コンピューティング製品マネージャーと標準的なク...

AppleがiOS 9を正式にリリース

Appleは今朝早く、iOS 9の正式版を世界中のユーザーに公開し、長い間待ち望んでいた多くのユーザ...

Baidu はオープン プラットフォームを知っている: 外部リンクの楽園

まずはじめに自己紹介をさせていただきます。私は医療業界で働いており、病院のウェブサイトの最適化を担当...

reprisehosting: シアトルの格安サーバー、月額 37.38 ドル、2*E5-2650L/32G メモリ/240gSSD+12T HDD/10T トラフィック/1Gbps 帯域幅/4 IPv4

reprisehosting は現在、シアトルのデータセンターにある自社専用サーバーの特別プロモーシ...

SwiftVM 128 RAM 6 USD/半年/5g SSD

swiftvm は、優れたサーバー ハードウェア、優れたデータ センター、優れた価格といった特徴を備...

ウェブサイトの最適化はユーザーの視点から始める必要がある

実際、リンク、ドメイン名、URL など、Web サイトの最適化に関連する要素は多数あります。成功する...