目次
方法 A (application-toolkit-trace アノテーション方法)
モード B (アプリケーション ツールキット トレース ソース コード モード)
方法 C (カスタマイズ・エンハンス・トレース・プラグイン方法)
I. 概要
サービスの分割に伴い、サービスの数が増加し、通話リンクがますます複雑になります。したがって、分散トレースとアプリケーション監視 (APM) を完了するには特別なツールが必要です。
このツールは収集側とサーバー側に分かれています。
- コレクション終了。マイクロサービス アプリケーション側では、マイクロサービスのさまざまなデータ (呼び出しリンクを含む) を収集するために使用されます。
- サーバ。取得側からデータを受信し、保存、処理、グラフ表示します。
収集側とサーバー側の間には、ログの埋め込みやインターフェース通信など、さまざまな送信方法があります。
一般的な特定のソリューションには、Sleuth+Zipkin ソリューション、Skywalking、CAT などが含まれます。
Sleuth+Zipkin は Spring Cloud のデフォルト ソリューションとして広く使用されていますが、その監視 UI は比較的弱く、中国のスタイルに準拠していません。したがって、ここでは例として Skywalking ソリューションを使用することにします。なぜなら、各ソリューションは Sleuth+Zipkin の基本概念を採用し、そこから学ぶからです。例えば:
- トレース:これは完全なリンク呼び出しです。1 つの呼び出しプロセスには複数のサービスが関与しており、1 つの完全なリンク呼び出しプロセス内の複数のサービスの TraceID は同じです。(リンク全体は TraceID によって一度特定できます)
- スパン:サービス間の特定の呼び出しスパン。ネットワーク通信のホップ ジャンプに少し似ています。ここでのスパンはサービスではなく、サービス間の呼び出しです。つまり、Span は下図の楕円ノードではなく、コールラインです。同じフルリンク TraceID では、呼び出されるたびに SpanID が 1 ずつ増加します (フルリンク内のコールの数は SpanID によって特定できます)。
- 親:以下の図に示すように、Trace+Span だけでは、ノード B が C と D をそれぞれ呼び出す状況を説明するのに十分ではありません。したがって、この Span の上位の呼び出し元を記述するために ParentID を追加することも必要です。つまり、最初に C が呼び出され、次に D (異なる SpanID) が呼び出されますが、C と D は両方とも B によって呼び出され、C と D は呼び出しレベルで同じレベル (同じ ParentID) に属します。(リンク全体のコール レベル情報は、ParentID を通じて見つけることができます)
2. スカイウォーキングの紹介
SkyWalking は、サービスやクラウドネイティブ インフラストラクチャからデータを収集、分析、集約、視覚化するためのオープンソースの可観測性プラットフォームです。SkyWalking は、クラウド間であっても分散システムの明確なビューを維持する簡単な方法を提供します。これは、クラウドネイティブのコンテナベースの分散システム向けに設計された最新の APM です。
APM: アプリケーション パフォーマンス管理 (アプリケーション パフォーマンス管理) は、比較的新しいネットワーク管理の方向性であり、主に企業アプリケーションの信頼性と品質を向上させるために、企業の主要なビジネス アプリケーションの監視と最適化を指します。監視体制がわかりやすくなります。ハードウェア/CPU およびその他のリソースの監視に重点を置く場合や、ネットワークの監視に重点を置く場合など、監視の対象となるものは異なります。ここでのスカイウォーキングとは、サービス間リンクの呼び出しに焦点を当てた APM 監視です。
スカイウォーキングの基本コンセプト:
- サービス。受信リクエストに対して同じ動作を提供するワークロードのグループ/セットを表します。サービス名は、インストルメンテーション エージェントまたは SDK を使用するときに定義できます。つまり、マイクロサービスにおけるサービスです。
- サービスインスタンス。サービス グループ内の個々のワークロードはインスタンスと呼ばれます。つまり、同じマイクロサービスが複数のノードをデプロイでき、各ノード (プロセス) がインスタンスになります。
- エンドポイント。受信リクエストのサービス パス (HTTP URI パスや gRPC サービス クラス + メソッド シグネチャなど)。
公式の Skywalking アーキテクチャ図は次のとおりです。
- プローブのプローブ。データの収集とデータの送信、ソースでの展開、さまざまなデータ収集をサポートするためのさまざまなプローブ (図の左側を参照)
- プラットフォーム バックエンド バックエンド プラットフォーム。つまり、データの集約、加工、分析、ストリーム処理など(図の右側参照)
- ストレージは、 オープン/プラグイン可能なインターフェイスを介してSkyWalking データを保存します。ElasticSearch、H2、MySQL、TiDB、InfluxDB などの既存の実装を選択することも、独自の実装を実装することもできます。デフォルトは H2 で、メモリに保存され、再起動後に失われます。(図のストレージ オプションを参照)
- UI ヘルス グラフ Web インターフェイス。SkyWalking エンド ユーザーが SkyWalking データを視覚化および管理できるようにする、高度にカスタマイズ可能な Web ベースのインターフェイス。(図の GUI/CLI を参照)
公式 Web サイトは次のとおりです: https://skywalking.apache.org/
その公式ドキュメントは、以下の図に示すように、さまざまなモジュールに従って編成および分類されています。
3. Skywalking サーバーの導入
ここでのサーバーは CentOS を例に挙げています。サーバー側のデプロイは非常に簡単で、基本的には解凍して起動するだけです。
1.公式Webサイトからダウンロードページを見つけます。
2.公式サイトからダウンロードし、解凍します。
wget --no-check-certificate https://dlcdn.apache.org/skywalking/8.8.1/apache-skywalking-apm-8.8.1.tar.gz
tar xvfz apache-skywalking-apm-8.8.1.tar.gz
cd apache-skywalking-apm-bin
解凍後のディレクトリ構造は、Skywalking バックエンドと Web UI を含むディレクトリになります。
├── bin
├── config
├── config-examples
├── LICENSE
├── licenses
├── logs
├── NOTICE
├── oap-libs
├── README.txt
├── tools
└── webapp
3. Skywalking バックエンドで使用されるデフォルトのデータベースは H2 です。ここではデフォルトを変更しないでください
4. Skywalking バックエンドは、ソース データを収集するためのデフォルトのリスナーを受け取ります: 0.0.0.0/11800
gRPC API (Java、DotNetCore、Node.js、Istio エージェント/プローブの受信を含む) および 0.0.0.0/12800(
HTTP REST API)。Skywalking が収集されたデータを受信するポートを変更する必要がある場合は、config/application.yml ファイルを変更します。ここではデフォルトを変更しないでください
5. Skywalking の監視および表示 Web インターフェイスのポートは、デフォルトでは 8080 です。Skywalking が収集されたデータを受信するポートを変更する必要がある場合は、webapp/webapp.yml ファイルを変更します。 この環境では、ポート8080がすでに占有されているため、ポート38080に変更されます。
6. 開始します。Linux で bin/startup.sh を使用すると、Skywalking バックエンド (Web UI) が自動的に起動します。
7. アクセスします。http://39.100.80.168:38080/
4. スカイウォーキングクライアント
Skywalking クライアントは、データ収集ソースとしてマイクロサービスにプローブをデプロイします。
Java プログラムの場合、Skywalking のプローブは JVM エージェント テクノロジを使用して作成されており、プローブ対象のアプリケーションへの侵入はありません。
1.公式Webサイトからダウンロードページを見つけます。
2. ダウンロード後、解凍します。解凍後のディレクトリ構造は次のとおりです。
skywalking-agent
├─activations
├─bootstrap-plugins
├─config
├─licenses
├─logs
├─optional-plugins
├─optional-reporter-plugins
└─plugins
3. 検出されたアプリケーションを起動します。ここでは、前の記事で開発した支払いサービスと注文サービスを個別に開始する例として使用します。必要なのは、-javaagent オプションを追加することだけです。
#启动payment支付服务
java -javaagent:D:\skywalking-agent\skywalking-agent.jar -DSW_AGENT_COLLECTOR_BACKEND_SERVICES='39.100.80.168:11800' -DSW_AGENT_NAME='payment' -jar payment-0.2.2-SNAPSHOT.jar
#启动order订单服务
java -javaagent:D:\skywalking-agent\skywalking-agent.jar -DSW_AGENT_COLLECTOR_BACKEND_SERVICES='39.100.80.168:11800' -DSW_AGENT_NAME='order' -jar order-1.0-SNAPSHOT.jar
- 変数SW_AGENT_COLLECTOR_BACKEND_SERVICES : Skywalking バックエンド サービスの IP とポートを構成します
- 変数SW_AGENT_NAME : 収集されたアプリケーション名、つまり収集後に Skywalking Web インターフェイスに表示されるサービス名を設定します。
起動コマンドで -D オプション構成方法を使用するほかに、skywalking-agent/config/agent.config構成ファイルでも構成できます。
4. ここまで。Skywalking サーバーとクライアントの両方がデプロイされています。curl を介していくつかのトランザクションを送信すると、Skywalking インターフェイスに次の内容が表示されます。トレース インターフェイスでは、デフォルトで Skywalking によって自動的に収集されたサービス間のリンクや時間のかかる呼び出しの追跡などの情報を確認できます。
Topology トポロジ インターフェイスでは、自動的に生成された呼び出し関係図を確認できます。
5. カスタマイズされたタグ
Skywalking によってデフォルトで収集される情報には、ビジネスのシリアル番号、顧客番号、および識別および位置特定が必要なその他の重要な情報など、アプリケーション システムのビジネス情報は含まれません。したがって、より多くの情報を収集し、Skywalking に提供する必要があります。
この情報は TAG と呼ばれ、キー=値のペアです。(Skywalkingがデフォルトで自動収集する情報もTAG形式です)
公式 Web サイトのドキュメントによると、実装メカニズムは次の 2 種類に分類できます。
- アプリケーションツールキットトレース。アノテーションやソースコードを含むソースコードの修正(簡易修正)が必要です。参照: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/application-toolkit-trace/
- カスタマイズ-強化-トレース 。プラグインを使用することで、ソースコードはまったく変更されません。参照: https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/customize-enhance-trace/
方法 A (application-toolkit-trace アノテーション方法)
1. 収集したアプリケーションに依存関係を追加します。pom.xml は次のとおりです。
<!-- 前面省略 -->
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-trace</artifactId>
<version>8.8.0</version>
</dependency>
<!-- 后面省略 -->
2. 決済サービスのソース コードで、@Trace、@Tags、@Tagアノテーションを使用して、収集する情報をカスタマイズします。次のように
@Trace(operationName = "pay入口") // operationName属性指定Span的名字,若不指定,会使用方法名
@Tags({@Tag(key = "orderid", value = "arg[0]"), @Tag(key = "return", value = "returnedObj")})
@GetMapping("/dopay/{orderid}")
public ResponseEntity<String> paylogic(@PathVariable("orderid") Long orderid) {
logger.info("全局事务XID=[{}], 事务BranchType=[{}] ", RootContext.getXID(), RootContext.getBranchType());
int insert_rows = jdbcTemplate.update("insert into T_PAY (order_id, amount) values (" + orderid +", 999)");
logger.info("支付服务successful! orderid=" + orderid + ", 支付成功。 支付服务的端口为port=" + myport);
return ResponseEntity.ok("支付服务successful! orderid=" + orderid + ", 支付成功。 支付服务的端口为port=" + myport);
}
3. 同じ注文サービスのソース コードで、@Trace、@Tags、@Tagアノテーションを使用して、収集する情報をカスタマイズします。次のように
@Trace(operationName = "consumer总入口") // operationName属性指定Span的名字,若不指定,会使用方法名
@Tags({@Tag(key = "orderid", value = "arg[0]"), @Tag(key = "return", value = "returnedObj")})
@GetMapping("/consumer/{orderid}")
@GlobalTransactional(timeoutMills = 28000, name = "gts-seata-example")
public ResponseEntity<String> consumerFeign(@PathVariable("orderid") Long orderid) {
logger.info("全局事务XID=[{}], 事务BranchType=[{}] ", RootContext.getXID(), RootContext.getBranchType());
String result = paymentServiceClient.dodopay(orderid).getBody(); // 调用支付服务进行支付
logger.info("[paymentService result]: {}", result);
jdbcTemplate.update("insert T_Order(order_id, address, remark) values (" + orderid + ", 'dizhi', '"+result+"')");
//模拟在支付完成后,本订单事务后续处理过程中发生异常后,全局回滚功能
if (forcefail) {
throw new RuntimeException("模拟在支付完成后,本订单事务后续处理过程中发生异常!");
}
return ResponseEntity.ok ("调用订单服务完成。 订单orderid:" + orderid + ", 调用支付返回的Body:" + result);
}
4. Skywalking サーバー インターフェイスでタグ検索を使用するには、以下の図に示すように、 Skywalking サーバーの config/application.yml ファイルの searchableTracesTags で構成されたタグ リストに上記のカスタム タグ名を追加する必要があります。次に、Skywalking サーバーを再起動します。
5. その後、再パッケージ化します。支払いおよび注文サービスを再開します。
6.curl を介していくつかのトランザクションを送信すると、Skywalking インターフェイスに次の内容が表示されます。これは、Trace インターフェイスで確認できます (タグで検索できます)。
上記のアノテーション方法の欠点: @Trace アノテーションは効果を実現できますが、呼び出しリンクにレイヤーが 1 つ多くなります。テスト済み: @Trace アノテーションが付加されていない場合は無効です。@Traceアノテーションを付けると上の図のようになり、Span Type=Localがまた一つ増えてレベルが一段深くなって非常に厄介です。
モード B (アプリケーション ツールキット トレース ソース コード モード)
では、ソースコードから現在のSpanを取得し、現在のSpanにタグ情報を追加できれば問題は解決するのではないでしょうか?
1. 決済サービスのソース コードで、@Trace、@Tags、@Tagアノテーションを削除し、ActiveSpan を使用して現在の Span を取得します。コードは以下のように表示されます。
@GetMapping("/dopay/{orderid}")
public ResponseEntity<String> paylogic(@PathVariable("orderid") Long orderid) {
ActiveSpan.tag("orderid", orderid.toString());
logger.info("Skywalking TraceID=[{}]", TraceContext.traceId());
logger.info("全局事务XID=[{}], 事务BranchType=[{}] ", RootContext.getXID(), RootContext.getBranchType());
int insert_rows = jdbcTemplate.update("insert into T_PAY (order_id, amount) values (" + orderid +", 999)");
logger.info("支付服务successful! orderid=" + orderid + ", 支付成功。 支付服务的端口为port=" + myport);
return ResponseEntity.ok("支付服务successful! orderid=" + orderid + ", 支付成功。 支付服务的端口为port=" + myport);
}
2. 同じ注文サービスのソース コードで、@Trace、@Tags、@Tagアノテーションを削除し、ActiveSpan を使用して現在の Span を取得します。コードは以下のように表示されます
@GetMapping("/consumer/{orderid}")
@GlobalTransactional(timeoutMills = 28000, name = "gts-seata-example")
public ResponseEntity<String> consumerFeign(@PathVariable("orderid") Long orderid) {
ActiveSpan.tag("orderid", orderid.toString());
logger.info("Skywalking TraceID=[{}]", TraceContext.traceId());
logger.info("全局事务XID=[{}], 事务BranchType=[{}] ", RootContext.getXID(), RootContext.getBranchType());
String result = paymentServiceClient.dodopay(orderid).getBody(); // 调用支付服务进行支付
logger.info("[paymentService result]: {}", result);
jdbcTemplate.update("insert T_Order(order_id, address, remark) values (" + orderid + ", 'dizhi', '"+result+"')");
//模拟在支付完成后,本订单事务后续处理过程中发生异常后,全局回滚功能
if (forcefail) {
throw new RuntimeException("模拟在支付完成后,本订单事务后续处理过程中发生异常!");
}
return ResponseEntity.ok ("调用订单服务完成。 订单orderid:" + orderid + ", 调用支付返回的Body:" + result);
}
3. その後、再パッケージ化します。支払いおよび注文サービスを再開します。
4.curl を介していくつかのトランザクションを送信すると、Skywalking インターフェイスに次の内容が表示されます。カスタムタグは導入されましたが、コールレベル情報は追加されていません。
方法 C (カスタマイズ・エンハンス・トレース・プラグイン方法)
上記 2 つの方法ではソース コードを変更する必要があり、煩雑です。プラグイン + 構成により、完全な侵入ゼロを実現することもできます。
1. クライアントの skywalking-agent ディレクトリにプラグインをインストールしますapm-customize-enhance-plugin.jar和apm-spring-annotation-plugin-8.8.0.jar,从目录
optional-plugins/拷贝至
plugin/目录。
2、指定该插件的配置文件。在
skywalking-agent ディレクトリで、プラグイン構成ファイルの絶対パスを指すplugin.customize.enhance_file属性を config/agent.config ファイルに追加します。
3. 新しいプラグイン構成ファイル Customize_enhance_trace.xml を作成します (パスは前の手順と一致し、文字エンコーディングは XML ヘッダー行で宣言されたものと一致する必要があります)。内容は以下の通りです。
<?xml version="1.0" encoding="UTF-8"?>
<enhanced>
<class class_name="com.example.payment.contronller.PaymentController">
<method method="paylogic(java.lang.Lang)" operation_name="pay调用入口" static="false">
<tag key="orderid">arg[0]</tag>
<tag key="test">测试PPP</tag>
</method>
</class>
<class class_name="com.example.order.contronller.OrderController">
<method method="consumerFeign(java.lang.Lang)" operation_name="consumer调用入口" static="false">
<tag key="orderid">arg[0]</tag>
<tag key="test">测试CCC</tag>
</method>
</class>
</enhanced>
XML コンテンツの構成定義の詳細については、https: //skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/customize-enhance-trace/を参照してください。
メソッドの書き方には特に注意が必要です。
- 基本型: 基本 type.class、例: int.class
- 非プリミティブ型: クラスの完全修飾名 (例: java.lang.String)
- 配列: 配列を作成して印刷すると、形式を知ることができます。例: [Ljava.lang.String;
4. (存在する場合) Java ソース コードから上記の Skywalking によって追加されたコードを削除し、再コンパイルしてパッケージ化して元の状態に戻します。
5. 支払いおよび注文サービスを再開します。
6.curl を介していくつかのトランザクションを送信すると、Skywalking インターフェイスに次の内容が表示されます。カスタムタグは導入されましたが、コールレベル情報は追加されていません。(テストしたところ、Skywalkingインターフェースにカスタムタグが表示されず、効果が出ませんでした。原因は不明、今後調査中です......)