AWS DevOps - AWS X-Rayによる分散トレーシング その1 (概要編)

# はじめに
DevOpsの重要な要素である俊敏性 (Agility) を実現するためには、CI / CDプロセス以外に目を向けることも重要です。例えば、アプリケーションアーキテクチャの分野では、マイクロサービスアーキテクチャが注目されています。

マイクロサービスアーキテクチャとは、簡単に言うと「単機能のサービスを組み合わせて、1つのアプリケーションを構成するアーキテクチャ」です。マイクロサービスアーキテクチャを採用すると、1つ1つのサービスのサイズが小さくなり、改修が容易となるため、新機能を迅速にリリースできるようになります。

一方で、マイクロサービスアーキテクチャは各サービスが連動して動作する分散システムのため、可観測性 (Observability) を実現すること重要になってきます。可観測性とは、簡単に言うと「システムの状態を観測できる能力」で、マイクロサービスアーキテクチャでは、主に、ログ、メトリクス、分散トレーシングの3つで構成されます。

本連載では、可観測性の中でも分散トレーシングに着目し、AWS上で分散トレーシングを実現するAWS X-Rayの使用方法を紹介します。

# 記事の構成
本連載は以下の3部で構成されています。

1. **AWS X-Rayによる分散トレーシング その1 (概要編) ← 今回**
1. AWS X-Rayによる分散トレーシング その2 (Java編)
1. AWS X-Rayによる分散トレーシング その3 (Node.js編)

今回は概要編ということで、AWS X-Rayの概念や機能を紹介します。次回以降の記事では、実際にアプリケーションを構築する手順を紹介します。

# AWS X-Rayの概要
## AWS X-Rayでできること
AWS X-Rayを使用することで、以下の3点を実現できます。

* システム全体におけるサービス間の呼出関係の可視化
* 特定リクエストにおけるサービス間の呼出関係の可視化 (特定リクエストの処理経路の可視化)
* 特定リクエストで出力された一連のログの検索

操作手順等は次回以降の記事に記載するため、本記事ではそれぞれの機能のみを紹介します。

### システム全体におけるサービス間の呼出関係の可視化
まず、「システム全体におけるサービス間の呼出関係の可視化」です。これは、システム内の各サービスの応答時間と呼出頻度、エラー率を見ることができます。これにより、応答が遅くなっているサービスや障害が発生しているサービスの有無など、システム全体の概況を把握できます。

例えば、以下の図では Service-C の一部のリクエストでエラーが発生していることが分かります。
![X-ray_witherror.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2196471/ab31f92f-30ce-7c76-42b8-30e56175cc04.png)

### 特定リクエストにおけるサービス間の呼出関係の可視化
次に、「特定リクエストにおけるサービス間の呼出関係の可視化」です。これは、X-Rayに連携されたトレースを1つ選択し、そのトレースにおけるサービスの呼出順序やそれぞれの処理時間を見ることができます。これにより、特定リクエストで応答が遅延した場合やエラーが発生した場合に、その原因箇所を知るための一助とすることができます。

例えば、以下の図では Service-A から Service-B、Service-C の順で呼び出しており、Service-C でエラーが発生したことが確認できます。
![trace_witherror.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2196471/bb0b6585-83c1-f09f-3c31-980ca86f7a5c.png)

### 特定リクエストで出力された一連のログの検索
最後は、「特定リクエストで出力された一連のログの検索」です。マイクロサービスアーキテクチャでは各サービスは独立してログを出力するため、特定のリクエストで出力されたログを紐づけて出力するには、リクエストごとに割り当てられる一意のキーが必要となります。X-RayではリクエストごとにトレースIDを付与するため、このIDをログに出力すると、当該リクエストで出力されたログを紐づけることができます。 (一連のログをまとめて検索するには、各サービスが出力したログを集約して検索するための仕組みが必要となります。)

例えば、AWSではCloudWatch Logs Insightsを使用して、以下のように Service-A、B、C の3つのログをまとめて表示することができます。これにより、特定リクエストで応答が遅延した場合やエラーが発生した場合に、その原因調査をスムーズに行うことができます。
![4-5-2_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2196471/e6951d26-5667-026f-8699-2f0547a9c49f.png)

## トレース情報
X-Rayではトレース情報を以下の単位で管理します。

| No | 単位 | 説明 |
|-:|:-|:-|
|1|トレース|1つのリクエストから生成された全てのセグメントの集合。1つのリクエストで複数サービスを呼び出す場合、それらのセグメントは同じトレースに含まれます。|
|2|セグメント|1つのアプリケーションでのトレース情報。例えば、REST APIやLambda関数の1回の実行が1つのセグメントとなります。|
|3|サブセグメント|セグメントの一部を任意のタイミングで区切った区間。処理時間を注視したい特定処理をサブセグメントとして切り出すことができます。|

また、X-Rayのトレースは一意なトレースIDを持ちます。このトレースIDをサービス間で引き渡すことで、一連のセグメントを1つのトレースとして管理できます。なお、トレース情報の保存期間は30日間です。

## X-Rayが収集するトレース情報
X-Rayが収集するトレース情報には主に2つのパターンが存在します。1つはX-Rayと統合されているAWSサービスが収集するトレース情報で、これらは簡単な設定を行うだけでトレースを取得できます。もう1つは、任意のアプリケーションが収集するトレース情報で、これらはX-Ray SDKを使用してアプリケーション内に作りこむ必要があります。

* X-Rayと統合されているAWSサービス：
  - Lambda
  - APIGateway
  - Elastic Beanstalk
  - ELB(ALB)
  - EventBridge
  - SNS
  - SQS
* X-Ray SDKを使用してアプリケーションで収集するトレース情報：
  - Incoming HTTP(S) (TomcatやSpring、Express、Django、Flask等の各言語の代表的なWebフレームワークをサポート)
  - Outgoing HTTP(S) (Apache HttpComponentsやNode.jsのhttp/httpsモジュールをサポート)
  - SQL呼出 (PostgreSQLかMySQLのクライアントからのSQL実行)
  - AWS SDKによるAWSサービス呼出 (DynamoDB、S3、SQS。これら以外は汎用ノードとして表示される)
  - その他カスタムセグメント (X-Ray SDKでカスタムセグメントを作成することにより任意の処理データを収集可能)

## アプリケーションのトレースに必要な機能
X-Rayを使用して、アプリケーションの分散トレーシングを実現するためには、前述のトレース情報の取得だけでなく、以下の機能が必要となります。

|No|機能|説明|
|-:|:-|:-|
|1|トレース情報の取得|X-Ray SDKを使用してアプリケーションで実現します。例えば、Incoming HTTP(S)のトレース情報を取得する場合、X-Ray SDKがセグメントを作成し、トレースIDが採番されていない場合には、併せて採番します。また、Outgoing HTTP(S)やSQL呼出はSDKが提供するクライアントモジュールを使用することで、トレースIDが連携され、一連のトレースとして記録できます。|
|2|トレース情報の送信|X-Ray SDKを使用したアプリケーションとX-Ray Daemonで実現します。X-Ray SDKは記録したセグメントをX-Ray Daemonに送信し、X-Ray DaemonがAWS X-Ray APIに送信します。|
|3|ログへのトレースIDの出力|AWS X-Ray SDKを使用してアプリケーションで実現します。SDKが提供するセグメントリスナーを使用することで、トレースIDをログのMDCに設定できます。|

#まとめ
本記事では、AWS X-Rayによる分散トレーシングの概要を紹介しました。次回以降の記事では実際にアプリケーションを作成する手順を紹介します。

---
* Amazon Web Services、および、その他のAWS 商標は、米国およびその他の諸国におけるAmazon.com, Inc.またはその関連会社の商標です。
* Javaは、Oracle Corporation、および、その子会社、関連会社の米国及びその他の国における登録商標です。
* その他、本資料に記述してある会社名、製品名は、各社の登録商品または商標です。