> Source: https://www.ymotongpoo.com/works/oteps/trace/otep-0173/


# OTEP-0173: メッセージングのトレーシングセマンティック規約のシナリオ

本文書は、現在[実験的](../../specification/versioning-and-stability.md#development)な状態にある[既存のメッセージング向けセマンティック規約](https://github.com/open-telemetry/semantic-conventions/tree/main/docs/messaging)を[安定版に](../../specification/versioning-and-stability.md#stable)するための基盤となる、シナリオとロードマップを整理することを目的としています。
目標は、2021年末までにメッセージングセマンティック規約を安定版として宣言することです。

## 動機 {#motivation}

多くのオブザーバビリティのシナリオには、メッセージングシステム、イベントストリーミング、またはイベント駆動アーキテクチャが関わってきます。
分散トレーシングがシナリオ全体を通じて有用であるためには、メッセージングやイベント操作に対する優れたオブザーバビリティを持つことが極めて重要です。
これを実現するために、OpenTelemetryはこれらの操作を計装するための安定した規約とガイドラインを提供しなければなりません（MUST）。
サポートすべき代表的なメッセージングシステムには、Kafka、RabbitMQ、Apache RocketMQ、Azure Event HubsおよびService Bus、Amazon SQS、SNS、Kinesisが含まれます。

既存の実験的なメッセージング向けセマンティック規約を安定した状態にすることは、ユーザーと計装の作者にとって重要なステップです。
なぜなら、これによって[安定性の保証](../../specification/versioning-and-stability.md#semantic-conventions-stability)に頼ることができ、安定した計装を出荷し利用できるようになるからです。

## ロードマップ {#roadmap}

1. シナリオと提案されたロードマップからなる本OTEPが承認され、マージされます。
2. セマンティック規約に対する[安定性の保証](../../specification/versioning-and-stability.md#semantic-conventions-stability)が承認され、マージされます。
   これはメッセージング向けセマンティック規約に厳密には関係しませんが、あらゆるセマンティック規約を安定版にするための前提条件です。
3. メッセージングにも関連する一般的な計装上の課題に対するガイダンスを提案するOTEPが承認され、マージされます。
   これらの一般的な計装上の課題には、リトライや計装レイヤーが含まれます。
4. 本文書のシナリオを網羅する属性と規約のセットを提案するOTEPが承認され、マージされます。
5. 提案された仕様変更が、以下のシナリオと例に対するプロトタイプによって検証されます。
6. 上記のOTEPに従って[トレーシング向けメッセージングセマンティック規約の仕様](https://github.com/open-telemetry/semantic-conventions/tree/main/docs)が更新され、[安定版](../../specification/versioning-and-stability.md#stable)として宣言されます。

ロードマップの各ステップは必ずしもこの順序で進む必要はなく、いくつかのステップは並行して進めることができます。

## 用語 {#terminology}

本文書で使用する用語は、[CloudEvents仕様](https://github.com/cloudevents/spec/blob/v1.0.1/spec.md)に基づいています。
CloudEventsはCNCFによってホストされており、サービス、プラットフォーム、システム間の相互運用性を提供するために、共通のフォーマットでイベントデータを記述するための仕様を提供しています。

### メッセージ {#message}

「メッセージ」とは、情報を転送するためのトランスポートエンベロープです。
情報は、ペイロードとメタデータの組み合わせです。
メタデータは、コンシューマーやメッセージ経路上の仲介者に向けられることがあります。
メッセージは1つ以上の仲介者を経由して転送されます。
メッセージは一意に識別可能です。

厳密には、_メッセージ_ とは特定の宛先に送られるペイロードであるのに対し、_イベント_ とは特定の状態に到達したときにコンポーネントから発せられるシグナルです。
本文書はこの違いにこだわらず、両方の概念を包括する広い意味で「メッセージ」という用語を使用します。

### プロデューサー {#producer}

「プロデューサー」とは、メッセージを作成し発行する特定のインスタンス、プロセス、またはデバイスです。
「発行」とは、メッセージまたはバッチを仲介者またはコンシューマーに送信するプロセスです。

### コンシューマー {#consumer}

「コンシューマー」はメッセージを受信し、それに基づいて処理を行います。
コンシューマーはコンテキストとデータを使用して何らかのロジックを実行し、それが新しいイベントの発生につながることがあります。

コンシューマーはメッセージを受信、処理、決済します。
「受信」とは仲介者からメッセージを取得するプロセスであり、「処理」とはメッセージに含まれる情報に基づいて処理を行うプロセスであり、「決済」とはメッセージが正常に処理されたことを仲介者に通知するプロセスです。

### 仲介者 {#intermediary}

「仲介者」はメッセージを受信し、それを次の受信者（別の仲介者またはコンシューマー）に転送します。

## シナリオ {#scenarios}

メッセージの生成と消費には5つの段階が関わります。

```
PRODUCER

Create
  |                            CONSUMER
  v        +--------------+                   
Publish -> | INTERMEDIARY | -> Receive
           +--------------+       |
                  ^               v
                  .            Process
                  .               |
                  .               v
                  . . . . . .  Settle
```

1. プロデューサーがメッセージを作成します。
2. プロデューサーがメッセージを仲介者に発行します。
3. コンシューマーが仲介者からメッセージを受信します。
4. コンシューマーがメッセージを処理します。
5. コンシューマーは、メッセージが処理されたことを仲介者に通知することでメッセージを決済します。
   ケースによっては（fire-and-forgetの場合）、決済段階は存在しません。

メッセージング向けセマンティック規約は、これらの段階をトレースにおいてどのようにモデル化するか、コンテキストをどのように伝播するか、属性によってどのようにトレースを充実させるかを定義する必要があります。
障害とリトライは、仲介者とインターフェースするすべての段階（発行、受信、決済）で処理する必要があり、一般的な計装ガイダンスによってカバーされます。

このモデルに基づき、以下のシナリオは主要な要件を捉えており、プロトタイピング、例、テストケースとして利用できます。

### 個別決済 {#individual-settlement}

個別決済システムは、独立した論理的なメッセージフローを意味します。
単一のメッセージは同じコンテキスト内で作成・発行され、単一のエンティティとして配信、消費、決済されます。
各メッセージは個別に決済される必要があります。
通常、決済情報はコンシューマーではなく仲介者によって保存されます。

トランスポートバッチ処理は特殊なケースとして扱うことができます。
つまり、メッセージは最適化としてまとめて転送されることがありますが、個別に生成・消費されます。

以下の図が示すように、メッセージがストリームやキュー内のどの位置にあるかに関わらず、各メッセージは個別に決済できます。
チェックポイントベースの決済とは対照的に、決済情報は個々のメッセージに関連付けられ、メッセージストリーム全体には関連付けられません。

```
+---------+ +---------+ +---------+ +---------+ +---------+ +---------+
|Message A| |Message B| |Message C| |Message D| |Message E| |Message F|
+---------+ +---------+ +---------+ +---------+ +---------+ +---------+
 Settled                 Settled                             Settled 
```

#### 例 {#examples}

1. 以下の構成は、RabbitMQまたは類似のメッセージングシステムに対して計装し、テストするべきです（SHOULD）。

   * プロデューサー1、キュー1、コンシューマー2
   * プロデューサー1、fanoutエクスチェンジで2つのキューへ、コンシューマー2
   * プロデューサー2、fanoutエクスチェンジで2つのキューへ、コンシューマー2

   各プロデューサーは継続的にメッセージを生成します。

### チェックポイントベースの決済 {#checkpoint-based-settlement}

メッセージはストリームとして処理され、チェックポイントを進めることによって決済されます。
チェックポイントは、メッセージが処理・決済された位置までのストリーム上の位置を指し示します。
メッセージは個別に決済することができず、代わりにチェックポイントを進める必要があります。
通常、チェックポイント情報は仲介者ではなくコンシューマーが保存する責任を負います。

チェックポイントベースの決済システムは、メッセージのバッチを効率的に受信・決済するように設計されています。
しかし、ストリーム内の位置とは無関係にメッセージを決済することはできません（例えば、メッセージBがストリーム内でメッセージAより後の位置にある場合、メッセージBを決済するにはメッセージAも決済する必要があります）。

以下の図が示すように、メッセージを個別に決済することはできません。
代わりに、決済情報は順序付けられたメッセージストリーム全体に関連付けられます。

```
                               Checkpoint
                                   | 
                                   v                                
+---------+ +---------+ +---------+ +---------+ +---------+ +---------+
|Message A| |Message B| |Message C| |Message D| |Message E| |Message F|
+---------+ +---------+ +---------+ +---------+ +---------+ +---------+
                     <---  Settled
```

#### 例 {#examples-1}

1. 以下の構成は、Kafkaまたは類似のメッセージングシステムに対して計装し、テストするべきです（SHOULD）。

   * プロデューサー1、同じコンシューマーグループ内のコンシューマー2
   * プロデューサー1、異なるコンシューマーグループのコンシューマー2
   * プロデューサー2、同じコンシューマーグループ内のコンシューマー2

   各プロデューサーは継続的なメッセージストリームを生成します。

## 未解決の問題 {#open-questions}

以下の領域は、メッセージング向けセマンティック規約の最初の安定版リリースのスコープ外とみなされます。
最初の安定版リリースで明示的に考慮されないとはいえ、この最初の安定版リリースが、これらの領域における今後の改善のための確固たる基盤として機能できることを確保することが重要です。

### サンプリング {#sampling}

現在の実験的なセマンティック規約は、スパンを関連付ける手段としてスパンリンクに大きく依存しています。
システムを通過するメッセージの完全な経路をモデル化するには複数のトレースが必要になるため、これは必要なことです。
OpenTelemetryの現在利用可能なサンプリング機能では、リンクされた一連のトレースがサンプリングされることを保証することはできません。
その結果、メッセージがたどる完全な経路をカバーする一連のトレースがサンプリングされる可能性は低くなります。

この問題を解決するには、スパンリンクに基づくサンプリングのためのソリューションが必要ですが、これは本OTEPのスコープには含まれません。

しかし、単一のトレース内にあまりに多くのスパンリンクがあったり、あまりに多くのトレースが互いにリンクされていたりすると、トレースの可視化や分析が非効率になる可能性があります。
この問題はサンプリングとは関係がなく、セマンティック規約によって対処される必要があります。

### 仲介者の計装 {#instrumenting-intermediaries}

仲介者を計装することは、設定やパフォーマンスの問題をデバッグしたり、特定の仲介者の障害を検出したりするうえで有用な場合があります。

仲介者の計装に関する安定したセマンティック規約は将来的に提供される可能性がありますが、本OTEPのスコープには含まれません。
本文書が言及するメッセージング向けセマンティック規約は、仲介者が計装されていなくても十分に機能する計装を提供する必要があります。

### メトリクス {#metrics}

トレーシング向けとメトリクス向けのメッセージングセマンティック規約は重なる部分があり、できる限り一貫性を保つべきです（SHOULD）。
しかし、メトリクス向けのセマンティック規約は別途扱われるものであり、本OTEPのスコープには含まれません。

### より広い意味での非同期メッセージパッシング {#asynchronous-message-passing-in-the-wider-sense}

より広い意味での非同期メッセージパッシングとは、システムがメッセージをキューまたはチャネルに置き、処理を続けるために即座の応答を必要としない通信方法です。
これは、単純なキュー実装の利用から、本格的なメッセージングシステムまで幅広く含まれます。

メッセージング向けセマンティック規約は、[前節で示したシナリオ](#scenarios)のいずれかに当てはまるシステムを対象としており、これらのシナリオは非同期メッセージパッシングを行うアプリケーションの大部分をカバーしています。
しかし、これらのシナリオのいずれにも当てはまらない、非同期メッセージパッシングの低レベルなパターンも存在します。
例えば、Goのチャネルや、Erlangにおけるメッセージパッシングなどです。
これらは将来、別のセマンティック規約のセットによってカバーされる可能性があります。

また、キューイングやバックグラウンドジョブの実行のためのフレームワークもいくつか存在し、多くの場合、これらのフレームワークはジョブをキューイングするために非同期メッセージパッシングのパターンを利用しています。
これらのフレームワークは、[前節で示したシナリオ](#scenarios)のいずれかに当てはまる場合にはメッセージング向けセマンティック規約を利用するかもしれませんが、そうでない場合、これらの様々なフレームワークを対象とすることは本規約の明確な目標ではありません。
これらのフレームワークは、将来的には[「ジョブ」向けセマンティック規約](https://github.com/open-telemetry/opentelemetry-specification/pull/1582)によってカバーされる可能性があります。

## さらなる参考資料 {#further-reading}

* [CloudEvents](https://github.com/cloudevents/spec/blob/v1.0.1/spec.md)
* [Message-Driven（Event-Drivenとの対比）](https://www.reactivemanifesto.org/glossary#Message-Driven)
* [非同期メッセージパッシング](https://en.wikipedia.org/wiki/Message_passing#Asynchronous_message_passing)
* [既存のメッセージング向けセマンティック規約](https://github.com/open-telemetry/semantic-conventions/tree/main/docs/messaging)

