開発 |マイクロサービス監視のための分散トレースの理解

開発 |マイクロサービス監視のための分散トレースの理解

[[272944]]

現在、ますます多くのアプリケーションがマイクロサービスに基づくクラウドネイティブ アーキテクチャに移行しています。マイクロサービス アーキテクチャは非常に強力ですが、特にアプリケーションのデバッグ方法や複数のサービス間の呼び出し関係とステータスの監視方法など、多くの課題も伴います。マイクロサービス アーキテクチャを効果的に監視する方法は、マイクロサービス アーキテクチャの運用と保守を成功させる鍵となります。ソフトウェア アーキテクチャの用語では、マイクロサービス アーキテクチャの可観測性を強化することを意味します。


マイクロサービスの監視には、主に次の 3 つの側面が含まれます。

  • ログを収集してシステムや各サービスの稼働状況を監視する
  • メトリクスを収集してシステムと各サービスのパフォーマンスを監視する
  • 分散トレースを使用すると、さまざまな分散コンポーネントでサービス要求がどのように処理されるかを詳細に追跡できます。

ログとメトリックの収集と監視について、誰もがより詳しく知ることができます。一般的なログ収集アーキテクチャには、Fluentd を使用してシステム ログを収集し、ELK または Splunk を使用してログを分析することが含まれます。パフォーマンス監視の場合、Prometheus が一般的で人気のある選択肢です。

分散トレースはますます多くのアプリケーションに採用されています。分散トレースは、マイクロサービスの呼び出しチェーンを追跡することで、サービス要求からマイクロサービス間のやり取りまでの呼び出しプロセス全体のビューを構築できます。ユーザーは、アプリケーション呼び出しの待ち時間、ネットワーク呼び出し (HTTP、RPC) のライフ サイクル、システム パフォーマンスのボトルネックなどの情報を知ることができます。では、分散トレースはどのように実装されるのでしょうか?

1. 分散トレースの概念

2010 年 4 月、Google は「Dapper、大規模分散システム トレース インフラストラクチャ」(http://1t.click/6EB) というタイトルの論文を公開し、分散トレースの概念を紹介しました。


分散トレースには、主に次の概念があります。

  • トレース: 分散マイクロサービスコラボレーションによってサポートされるトランザクションです。トランザクションを処理した各サービス要求を含むトレース。
  • Span: Span はトランザクション内のワークフローです。 Span には、タイムスタンプ、ログ、タグの情報が含まれます。スパンは親子関係、またはマスターとスレーブ (フォローアップ) 関係を含みます。
  • Span コンテキスト: Span コンテキストは、分散トレースをサポートするための鍵です。呼び出されたサービス間で渡すことができます。コンテキストの内容には、あるサービスから別のサービスまでの時間、トレース ID、スパン ID、および上流サービスから下流サービスに渡す必要があるその他の情報が含まれます。

2. OpenTracing 標準の概念

OpenTracing (http://1t.click/6tC) は、Google が提案したオープンな分散トレース標準を定義する概念です。

スパンは分散トレースの基本的な構成要素であり、分散システムにおける単一の作業単位を表します。各 Span には他の Span への参照を含めることができます。複数のスパンが一緒になってトレースを形成します。


OpenTracing 仕様では、各 Span には次の内容が含まれると定義されています。

  • 操作名。操作の内容を示します。
  • タグ: タグは名前と値のペアです。ユーザーは追跡に意味のあるあらゆる情報を追加できます。
  • ログ、ログも名前と値のペアとして定義されます。デバッグ情報や関連スパンの関連情報をキャプチャするために使用されます
  • スパンコンテキスト (SpanContext) はどうでしょうか? SpanContext は、サブマイクロサービス システムの境界を越えてデータを転送する役割を担います。主に 2 つの部分から構成されます。
  1. トレースIDやスパンIDなど、実装に関係のないステータス情報
  2. 手荷物。マイクロサービスの呼び出しをある都市から別の都市へのフライトに例えると、SpanContext は飛行機で運ばれるコンテンツと考えることができます。 Trace ID と Span ID はフライト番号のようなもので、手荷物項目は発送される荷物のようなものです。各サービスコールごとに、ユーザーは異なる手荷物を送ることを決めることができます。

以下は Span の例です。

  1. t=0 操作: db_query t=x
  2. + --------------------------------------------------------+  
  3. | · · · · · · · · · · · スパン · · · · · · · · · · · · |
  4. + --------------------------------------------------------+  
  5. タグ:
  6. - db.instance:"jdbc:mysql://127.0.0.1:3306/customers
  7. - db.statement: "SELECT * FROM mytable WHERE foo='bar';"  
  8. ログ:
  9. - メッセージ: 「'127.0.0.1'(10061) の MySQL サーバーに接続できません」  
  10. スパンコンテキスト:
  11. - トレースID: "abc123"  
  12. - スパンID: "xyz789"  
  13. - 手荷物:
  14. - 特別ID: "vsid1738"  

分散トレースを実現するには、SpanContext をどのように渡すかが鍵となります。 OpenTracing は、SpanContext を挿入および抽出するための Inject と Extract という 2 つのメソッドを定義します。


疑似コードを挿入する

  1. span_context = ...
  2. アウトバウンドリクエスト = ...
  3. # (組み込みの) HTTP_HEADERS キャリア形式を使用します。私たちは
  4. #キャリア事前分布として空のマップを使用し開始します 
  5. # `tracer.inject`呼び出します
  6. キャリア = {}
  7. tracer.inject(span_context、opentracing.Format.HTTP_HEADERS、キャリア)
  8. # `carrier` には、渡す(不透明な)キー:値のペアが含まれるようになりました
  9. # すでに使用しているワイヤ プロトコルを介して通信します。
  10. のために キャリア内のキー、値:
  11. outbound_request.headers[キー] =エスケープ(値)

ここでの注入プロセスは、すべてのコンテキスト情報を Carrier と呼ばれる辞書に書き込み、辞書内のすべての名前と値のペアを HTTP ヘッダーに書き込むことです。

擬似コードを抽出する

  1. 受信リクエスト = ...
  2. # ここでも (組み込みの) HTTP_HEADERS キャリア形式を使用します。によると
  3. # HTTP_HEADERSドキュメントでは、余分なデータを含むマップを使用できます
  4. #そこOpenTracing実装がサブセットを探すようます
  5.  必要なキー:値のペア。
  6. #
  7. #そのためキー:値`inbound_request.headers`を直接使用します
  8. #キャリアとしてマップします。
  9. キャリア = inbound_request.headers
  10. span_context = tracer.extract(opentracing.Format.HTTP_HEADERS、キャリア)
  11. # span_context を指定してトレースを続行します例えば、
  12. span = tracer.start_span( "..." 、child_of=span_context )
  13. # (`carrier` がトレースデータを保持している場合は、`span` が使用できるようになります。)

抽出プロセスは、注入の逆のプロセスであり、キャリア、つまり HTTP ヘッダーから SpanContext を構築します。

全体のプロセスは、クライアントとサーバー間で送信されるデータのシリアル化および逆シリアル化のプロセスに似ています。ここでのキャリア辞書は、文字列型のキーと文字列またはバイナリ形式 (バイト) の値をサポートします。

3. エネルギーをどのように使うのか?

さて、私は多くの概念について話しました。プログラマーとして、あなたはすでにせっかちです。関係のないことについて話さないでください。コードを見てみましょう。心配しないでください。Tracing の使い方を見てみましょう。

OpenTracing の仕組みを説明するために、プログラマーの間で人気のある「hello world」を出力する Python アプリケーションを使用します。

クライアントコード

  1. 輸入リクエスト
  2. インポートシステム
  3. インポート時間 
  4. lib.tracingからinit_tracerをインポートする
  5. opentracing.extからタグをインポート
  6. opentracing.propagationからのインポート形式
  7. def say_hello(hello_to):
  8. tracer.start_active_span( 'say-hello' )スコープとして設定:
  9. スコープ.span.set_tag( 'hello-to' , hello_to)
  10. hello_str = フォーマット文字列(hello_to)
  11. print_hello(hello_str)
  12. def format_string(hello_to):
  13. tracer.start_active_span( 'format' )スコープとして設定:
  14. hello_str = http_get(8081, 'フォーマット' , 'helloTo' , hello_to)
  15. scope.span.log_kv({ 'イベント' : '文字列形式' , '値' : hello_str})
  16. hello_strを返す
  17. def print_hello(hello_str):
  18. tracer.start_active_span( 'println' )スコープとして:
  19. http_get(8082, 'publish' , 'helloStr' , hello_str) を実行します。
  20. スコープ.span.log_kv({ 'イベント' : 'println' } )
  21. def http_get(ポート、パス、パラメータ、値):
  22. url = 'http://localhost:%s/%s' % (ポート、パス)
  23. スパン = トレーサー.active_span
  24. span.set_tag(tags.HTTP_METHOD, 'GET' )を設定します。
  25. span.set_tag(タグ.HTTP_URL, url)
  26. span.set_tag(タグ.SPAN_KIND、タグ.SPAN_KIND_RPC_CLIENT)
  27. ヘッダー = {}
  28. tracer.inject(span, Format.HTTP_HEADERS, ヘッダー)
  29. r = リクエスト.get(url, パラメータ = {パラメータ: 値}, ヘッダー = ヘッダー)
  30. r.status_code == 200 をアサートする
  31. r.textを返す
  32. #主要
  33. len(sys.argv) == 2をアサートする
  34. トレーサー = init_tracer( 'hello-world' )
  35. hello_to = sys.argv[1]
  36. こんにちはと言う(hello_to)
  37. #スパンのフラッシュにはIOLoop使用します
  38. 時間.sleep(2)
  39. トレーサーを閉じる()

クライアントは次のタスクを完了します。

  • トレーサーを初期化します。トレース名は「hello-world」です。
  • クライアント操作say_helloを作成し、その操作を「say-hello」という名前のSpanに関連付け、span.set_tagを呼び出してタグを追加します。
  • say_hello 操作では、最初の HTTP サービス A (format_string) が呼び出されます。この操作は、「format」という名前の別の Span を関連付け、span.log_kv を呼び出してログを追加します。
  • 次に別のHTTPサービスB、print_helloを呼び出します。この操作は「println」という名前の別のSpanに関連付けられており、span.log_kvを呼び出してログを追加します。
  • 各 HTTP リクエストに対して、http メソッド、http URL、および span の種類を示すタグが Span に追加されます。そして、tracer.inject を呼び出して、SpanContext を http ヘッダーに挿入します。

サービスAコード

  1. FlaskからFlaskをインポート
  2. フラスコのインポートリクエストから
  3. lib.tracingからinit_tracerをインポートする
  4. opentracing.extからタグをインポート
  5. opentracing.propagationからのインポート形式
  6. アプリ = Flask(__name__)
  7. トレーサー = init_tracer( 'フォーマッタ' )   
  8. @app.route( "/format" )
  9. デフフォーマット():
  10. span_ctx = tracer.extract(Format.HTTP_HEADERS、リクエスト.headers)
  11. span_tags = {tags.SPAN_KIND: tags.SPAN_KIND_RPC_SERVER}
  12. tracer.start_active_span( 'format' , child_of=span_ctx, tags=span_tagsの場合):
  13. hello_to = request.args.get( 'helloTo' )リクエストの引数を取得します。
  14. 戻る  「こんにちは、%s!」 % こんにちは
  15. __name__ == "__main__"の場合:
  16. app.run(ポート=8081)

サービス A はフォーマット要求に応答し、tracer.extract を呼び出して http ヘッダーから情報を抽出し、spanContext を構築します。

サービスBコード

  1. FlaskからFlaskをインポート
  2. フラスコのインポートリクエストから
  3. lib.tracingからinit_tracerをインポートする
  4. opentracing.extからタグをインポート
  5. opentracing.propagationからのインポート形式 
  6. アプリ = Flask(__name__)
  7. トレーサー = init_tracer( 'パブリッシャー' )
  8. @app.route( "/publish" )
  9. デフパブリッシュ():
  10. span_ctx = tracer.extract(Format.HTTP_HEADERS、リクエスト.headers)
  11. span_tags = {tags.SPAN_KIND: tags.SPAN_KIND_RPC_SERVER}
  12. tracer.start_active_span( 'publish' , child_of=span_ctx, tags=span_tagsの場合):
  13. hello_str = リクエスト.args.get( 'helloStr' )
  14. 印刷(hello_str)
  15. 戻る  「公開」  
  16. __name__ == "__main__"の場合:
  17. app.run(ポート=8082)

サービス B はサービス A と似ています。

すると、分散トレースをサポートするソフトウェア UI (次の図は Jaeger UI) 上で、次の図のようなトレース情報が表示されます。サービス hello-word と 3 つの操作 say-hello/format/println の詳細なトレース情報を確認できます。


現在、Jaeger、LightStep、Instanna、Apache SkyWalking、inspectIT、stagemonitor、Datadog、Wavefront、Elastic APM など、多くの分散トレース ソフトウェアが OpenTracing をサポートしています。その中でも、オープン ソース ソフトウェアである Zipkin (http://1t.click/6Ec) と Jaeger (http://1t.click/6DY) が最も人気があります。

ジプキン

Zipkin (http://1t.click/6Ec) は、Dapper をベースに Twitter が開発した分散トレース システムです。設計アーキテクチャは次のとおりです。


  • 青いエンティティは Zipkin がトレースするターゲット コンポーネントであり、非インストルメント サーバーはトレース API を直接呼び出さないマイクロサービスを表します。インストルメントされたクライアントを介して非インストルメント サーバーから情報を収集し、Zipkin コレクターに送信します。 Instrumented Server は Tracing API を直接呼び出し、データを Zipkin コレクターに送信します。
  • トランスポートは、HTTP 経由またはメッセージ/イベント キューを介して Zipkin に直接送信できる転送チャネルです。
  • Zipkin 自体は Java アプリケーションであり、次のものが含まれます。Collector はデータ収集を担当し、外部へのデータ インターフェイスを提供します。ストレージ; API と UI。

Zipkin のユーザー インターフェイスは次のようになります。



Zipkin は、C#、Go、Java、JavaScript、Ruby、Scala、PHP の言語のクライアントを公式にサポートしています。オープンソース コミュニティでは他の言語もサポートされています。

Zipkin は 4 年近く開発されており、比較的成熟したプロジェクトです。

イェーガー

Jaeger (http://1t.click/6DY) はもともと Uber によって分散トレース システムとして開発され、Dapper の設計コンセプトに基づいています。 Jaeger は現在、CNCF (Cloud Native Computing Foundation) のプロジェクトです。 CNCF 組織について少しでも知っていれば、このプロジェクトは Kubernetes と非常に緊密に統合されるはずだと推測できます。

Jaeger は分散アーキテクチャ設計に基づいており、主に次のコンポーネントが含まれています。

  1. Jaeger クライアントは、クライアント側でトレース情報を収集する役割を担います。
  2. Jaeger エージェントは、クライアントとのコミュニケーションと収集した追跡情報の Jaeger コレクターへの報告を担当します。
  3. Jaeger Colletorは収集したデータをデータベースまたはその他のストレージに保存します
  4. Jaeger Queryは追跡データのクエリを担当します
  5. Jaeger UIはユーザーインタラクションを担当します

このアーキテクチャは ELK と非常によく似ています。 Collector は Logstash に似ており、データの収集を担当します。Query は Elastic に似ており、検索を担当します。UI は Kibana に似ており、ユーザー インターフェイスとインタラクションを担当します。この分散アーキテクチャにより、Jaeger のスケーラビリティが向上し、必要に応じてさまざまなデプロイメントを構築できるようになります。

分散トレースの新星として、Jaeger はクラウド ネイティブと K8s の普及によりますます人気が高まっています。公式の K8s デプロイメント テンプレート (http://1t.click/6DU) を使用すると、ユーザーは独自の k8s クラスターに Jaeger を迅速にデプロイできます。

4. 分散追跡システム - 製品比較

もちろん、OpenTracing 標準をサポートする製品以外にも、分散トレース製品があります。参考までに、他のブロガーの分析をいくつか紹介します。

  • コールチェーンの選択: Zipkin、Pinpoint、SkyWalking、CAT (http://1t.click/6tY)
  • 分散呼び出しチェーンの調査 (pinpoint、skywalking、jaeger、zipkin など) (http://1t.click/6DK)
  • 分散トレースシステム - 製品比較 (http://1t.click/6ug)

5. まとめ

マイクロサービスが普及し、クラウドネイティブがアーキテクチャ設計の主流になるにつれて、ログ、メトリック、トレースなどのマイクロサービス システムの監視がシステム エンジニアリングにおける最優先事項になりました。 OpenTracing は Dapper の分散トレース設計コンセプトに基づいており、分散トレースの実装標準を定義します。オープンソース プロジェクトの中では、Zipkin と Jaeger が比較的優れた選択肢です。特に、Jaeger はクラウド ネイティブ フレームワークとの優れた統合により、マイクロサービス トレース システムを構築するための不可欠なツールです。

<<:  SaaS が急速に普及する中、企業はどのようにして「クラウド移行」を実現できるのでしょうか?

>>:  ハイブリッドクラウド: パブリッククラウドとプライベートクラウドのバランスをとる方法

推薦する

マイクロソフトの第4四半期の売上高は561億8900万ドル、クラウドサービス事業は冷え込んだ

マイクロソフトの業績は、先ほど終了した四半期で予想を上回った。マイクロソフトの2023年度第4四半期...

中国最大のリンクプラットフォーム「アリウェイ」が数日間連続DDos攻撃を受けた

中国最大のリンク交換プラットフォーム「AliVV」の公式サイトが数日連続で開けない状態が続いており、...

SEOデータ分析はあなたの仕事を定量化することです

SEO はデータ分析から切り離すことはできません。データの裏付けがあって初めて説得力を持つことができ...

事例分析:ミニゲーム「皇帝になりたい」はどのようにしてWeChatで爆発的な成長を遂げたのか?

最近とても忙しいので、自分を楽しませるために頭を使わずにできるユニークなゲームを見つけなければなりま...

SEO を通じてウェブサイトのトラフィックを増やす方法

SEO を通じてウェブサイトのトラフィックを増やすにはどうすればよいでしょうか? 周知のとおり、イン...

記事ページが多すぎるとSEOにどのような影響が出るかについて簡単に説明します

多くの有名なポータルサイトの影響を受けているのかもしれませんが、多くのウェブマスターが短い記事を無理...

Alibaba Cloud がクラウドベースの「スーパーコンピューティング センター」E-HPC を開始

9月12日、アリババクラウドのエラスティック高性能コンピューティングプラットフォームE-HPCが招待...

インターネットマーケティングではユーザーの前で「下品」であることが求められる

時間はすべてのものを成長させ、同時にすべてのものを変化させます。現在インターネットに携わっている私た...

ウェブサイトデザインの楽しさを徹底解説:ユーザーを惹きつけ、ウェブサイトの定着率を高める

Web デザイナー兼開発者として、私たちが設計するすべてのプロジェクトには特定の目標と要件があります...

クラウドネイティブ ストレージ システムはどのような条件を満たす必要がありますか?

2019年にテクノロジー業界では「クラウドネイティブ」という言葉が広く使われていましたが、この言葉に...

プライベートクラウドについて知るにはこの記事で十分です

1. プライベートクラウドの開発背景と動向新しいインフラストラクチャなどの政策や企業のデジタル変革に...

2コア8Gクラウドホストから、4大クラウドベンダーのオープニングプロモーションのうちどれが一番お手頃か見てみましょう!

2021年2月25日、JD Cloudが先陣を切って「新年ショッピングシーズン」プロモーションを開始...

SEO初心者向けチュートリアル: タイトルの書き方

以下は、最近構築した新しい Web サイトの TITLE の書き方の例です。 <title&g...

Webmaster.comからの毎日の報告:多くの政府ウェブサイトがハッキングされ、Tianyaやその他のウェブサイトは修正を命じられた

1. 偽造証明書のギャングがハッカーと共謀して多くの場所で政府のウェブサイトをハッキングし、数億元が...

hostinginside-Xen/256m メモリ/5g SSD/250g トラフィック/年間支払い $35.28

Hostinginsideは台湾の中国人が設立した会社です。2004年からホスティング業界関連の事業...