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

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

[[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 が急速に普及する中、企業はどのようにして「クラウド移行」を実現できるのでしょうか?

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

推薦する

第9回ソフトコピーライティング&ソフトコピーマーケティング研修の申込受付を開始しました

企業向けでもウェブサイトマーケティング向けでも、ソフトテキストマーケティングは欠かせないマーケティン...

2014 年にウェブサイトを最適化する方法はどこにあるのでしょうか?

SEO が始まったばかりの頃は、時間の問題でした。どんなウェブサイトでも、一定の時間を投資し (時間...

伝統的なビジネスとインターネットの融合:海鮮屋台によるO2Oの試み

ビジネスの究極の目的は取引です。しかし、現実の世界では、多くの実際的な要因の制約により、「プロセス」...

テンセントと百度の戦い、「ミニプログラム」が勝敗を分けるか?

わずか1年余りで、to Bは中国のインターネットで人気のトレンドになりました。 3月末、馬化騰氏はI...

Huawei Cloud FusionInsightが第1位にランクイン、顧客のデジタル変革のための強固なデータ基盤を提供

最近、工業情報化部は返答書を発表し、次のステップは「ビッグデータ産業発展第14次5カ年計画」の公布を...

モバイルO2O: 地域社会はBATの競争を恐れない

地域社会は常に、地域住民にとって最もシンプルな生活のアシスタントでした。従来の PC 時代の初めには...

Dreamweaver のドキュメント アンカー テキスト リンクの数に対する解決策

Dedecms ドキュメントのキーワードメンテナンスにおける頻度とは何を意味しますか? インターネッ...

OracleとIDCが共同でSaaS市場の業界動向レポートを発表

ビッグデータ、クラウドコンピューティング、ソーシャルエンジンを中心とした革新的なテクノロジーは、企業...

高速米国 VPS ホスティング - (高速米国クラウド サーバー)

アメリカの VPS ホストの中で、国内でアクセス速度が速いのはどれですか?最も速度が速い米国の VP...

国家著作権局:著作権侵害や海賊版などの違法ウェブサイトを報告すると、最大1万元の報奨金が支給される

国家著作権局と他の4つの部門は、オンライン上の著作権侵害や海賊版と戦うために、2012年に4か月間の...

アリババはモバイルインターネットに不安、ジャック・マーは社内でライワンを強力に推進

テンセントテクノロジーは10月21日、「ワイヤレス分野で実績がなければ、株式公開は考えないほうがいい...

B2B 業界のウェブサイトコンテンツは諸刃の剣です (パート 1)

B2Bは企業間のコミュニケーションプラットフォームモデルであり、業界情報配信センターとして理解できま...

raksmart: アメリカのクラスターサーバー、4Cセグメント、258IP、100M無制限、本土最適化ネットワーク

米国の老舗データセンターであるRaksmartは、独自の米国クラスターサーバー、マルチIPサーバー、...

分散コンセンサスアルゴリズム EPaxos について 1 つの記事で学ぶ

分散システムにおける中心的な問題はデータの一貫性です。 Paxos アルゴリズムは分散一貫性における...