コンテンツにスキップ
use-cases / inter-container-ipc-without-the-broker / hero
パイプ · コンテナ間通信

ブローカーなしのコンテナ間 IPC

サービス A が出力をパスにパイプします。サービス B が同じパスから受け取ります。パイプは 2 つのコンテナの間でリアルタイムにバイトをルーティング。Redis なし、コンシューマーグループなし、面倒を見るブローカーデーモンなし。

パイプドキュメントを読む
use-cases / inter-container-ipc-without-the-broker / mechanism

パイプがブローカーを置き換えるしくみ

2 つの HTTP 動詞と 1 つのパス。どちらの側が先に接続しても構いません。パイプは相手を最大 5 分待ち、その後バイトを通します。キューも、オフセットも、グループもありません。

01 · HANDSHAKE

どちらの側でも先に接続できる

プロデューサーがオフライン? コンシューマーが GET して待ちます。コンシューマーがオフライン? プロデューサーが PUT して待ちます。パイプは相手が現れるまで最大 5 分間接続を保持します。

02 · BACKPRESSURE

TCP 接続がキュー

コンシューマーが遅いとき、カーネルがプロデューサーのストリームを遅らせます。監視するキューの深さも、調整するハイウォーターマークもありません。ソケットがバッファです。

03 · STATELESS

配信後はメッセージを忘れる

正直なトレードオフ:何も永続化されません。永続的なキューイングが必要なら向いていません。コンテナ間の高速ファンアウトには、ブローカーがただ消えました。

producer.sh · consumer.sh
# Container A — producer streams jobs to the pipe
service-a | curl -T - https://api.hoody.com/api/v1/pipe/jobs

# Container B — consumer reads from the same path
curl https://api.hoody.com/api/v1/pipe/jobs | service-b

# Either side can connect first.
# The pipe holds the connection up to 5 minutes
# until the counterpart arrives, then streams through.

PUT (または POST) で送信。GET で受信。バイトはどこのディスクにも着地しません — プロデューサーからコンシューマーまでワイヤーを渡り、パイプが飛行中に転送します。

use-cases / inter-container-ipc-without-the-broker / fanout

3 番目のリーダーを追加。次は 4 番目。

ロガーやメトリクスコレクターが同じイベントを必要とする場合は、?n を上げて curl を 1 つ加えるだけです。ブローカー設定も、コンシューマーグループも、ローテーションする認証シークレットもありません。新しいリーダーは単に存在するだけです。

pipe/jobs · readers?n=4 · ALL FAN-OUT
  • + ADDED
    consumer-aloggermetricsaudit
    curl ?n=4 — ファンアウトに参加
  • = STABLE
    producer
    service-a | curl -T - ?n=4
  • − REMOVED
    redisconsumer-group.ymlbroker.conf
    ブローカーなし、設定なし

1 人の遅いリーダーはプロデューサーにバックプレッシャーをかけますが、他のリーダーはブロックしません。1 つのパスにつき最大 256 リーダーまで。

use-cases / inter-container-ipc-without-the-broker / advantages

ブローカーが奪っていたもの、URL が返してくれるもの

ブローカーは 2 つのコンテナが直接話せなかったから存在していました。パイプがあれば話せます。ブローカーが追加した認証、クライアント、運用 — そのすべてが消えます。

  • 運用するデーモンなし

    デプロイ、監視、アップグレードするものはありません。パイプがプラットフォームで、URL が唯一の API です。

  • ブローカー資格情報ではなく Bearer 認証

    Hoody トークン 1 つを、プロジェクトごとにスコープ。ブローカーごとのユーザー名、パスワード、ACL ファイルはありません。

  • 同じワイヤー、どんな言語でも

    HTTP を話すものなら何でもプロデュースまたはコンシュームできます — bash、Python、Go、スマホ、ブラウザ。クライアントライブラリ不要。

  • 永続化されたステートなし

    メッセージは飛行中に存在し、静止状態にはなりません。埋まるディスクも、保管ポリシーも、キューに入ったデータについての GDPR の問いもありません。

  • バックプレッシャーがプロトコル

    最も遅いコンシューマーが遅れると、TCP がプロデューサーを減速させます。遅延ダッシュボードがないのは遅延がないから — あるのはストリームレートだけです。

  • コンテナは結合しないまま

    プロデューサーとコンシューマーはお互いの IP を知りません。共有するのは URL だけ。配線を変えずにどちらかを別のホストに移せます。

use-cases / inter-container-ipc-without-the-broker / punchline

ブローカーが URL。URL がブローカー。

中間レイヤーが消えます。資格情報、クライアント、ランブック付きのステートフルデーモンだったものが、いまやパスです。アーキテクチャ図のボックスが 1 つ減ります。

WAS THERE
  • redis cluster認証、レプリカ、フェイルオーバー
  • consumer-group.ymlオフセット、パーティション
  • サービスごとのブローカー SDK言語ごとのクライアントライブラリ
IS THERE
/api/v1/pipe/jobs

1 つの URL、1 つの curl、1 つの HTTP 動詞

パイプドキュメントを読む
use-cases / inter-container-ipc-without-the-broker / replaces

これが置き換えるもの

1 つのコンテナが別のコンテナにバイトを渡す必要があるとき、チームが手を伸ばすインフラ群。どれもデーモン、設定、オンコールローテーションを足します。パイプはそのどれも要求しません。

  • Redis pub/subデーモン、認証、言語ごとのクライアント
  • RabbitMQ飛行中のバイトのために運用するクラスタ
  • NATSもう 1 つのプロトコル、もう 1 つのサイドカー
  • ZeroMQサービスごとのライブラリ、URL なし
  • カスタムルーティングデーモン生かし続けるべきカスタムサービス
  • gRPC ストリーミングサービススキーマ、コード生成、相互 TLS のオーバーヘッド
  • Apache Kafka ブローカー保持しないメッセージのためのストレージレイヤー
use-cases / inter-container-ipc-without-the-broker / cta

2 つのコンテナの間で会話するために Redis を立てますか? それとも URL を共有しますか。

パイプ API を見る
use-cases / inter-container-ipc-without-the-broker / related

他のユースケースを読む