web-dev-qa-db-ja.com

リアルタイムWebソケットアーキテクチャ

REST APIを介してシステムにデータが挿入されたときに、リアルタイム分析がWebソケットでどのように実行されるかについて、ここで混乱しています。Webソケットについての(認められた未熟)理解では、多くのクライアントがいますソケットサーバーに接続され、ソケットサーバーは接続されたクライアントにイベントを発行します。そのソケットサーバーとそれらのクライアントの間の唯一の通信はわかりません。データベースの何かが更新されたことをWebソケットが「検出」する方法はわかりません、そのデータベースが次の場所で更新された場合:

https://mydomain.com/api/v1/path/here/

ソケットサーバーはここにあります:

https://mydomain.com/socket:9999

私は本当にこれが機能する2つの方法のうちの1つだけを思いつくことができますそして私は両方が間違っていることを知っています:

  1. すべてのAPIエンドポイントがhttps://mydomain.com/socket:9999に変更され、クライアントが情報で更新された後、ソケットサーバーは正しい場所で正しい情報を使用してAPI呼び出しを行います。
  2. APIがhttps://mydomain.com/api/v1/path/here/で処理を行った後、https://mydomain.com/socket:9999への短期間の呼び出しを行い、必要に応じてクライアントデータを更新して、接続を閉じます。

再び、私はこれらの両方のソリューションが悪い、悪いソリューションであることを知っています(それらはまったくクリーンではありません、それらは悪いコードを書くのに役立ちます、それらは信じられないほど壊れやすく、フォールトトレラントではなく、パフォーマンスが悪いなどです...)、しかし別の解決策がわかりません。

データベースでデータが変更されたときにWebソケットサーバーがクライアントを更新できるようにするために、ここで何が欠けていますか?

REST API on PHP and the web socket server on Node.JSを実行しています。

1
Adam McGurk

2番目のソリューションは実現可能だと思いますが、いずれにしても、接続されているすべてのクライアントにメッセージをブロードキャストするWSサーバーにeventを送信する必要があります。理想的な世界では、WSサーバーとAPIの間のストリーム/メッセージキューは、これらのサービス間のイベントの受け渡しを処理するための良い方法であると思います。そのようなもの。したがって、アーキテクチャは次のようなものになります。

(API SERVER)---->(メッセージキュー/ストリーミングプラットフォーム)--->(WS SERVER)---->(nクライアント)

APIサーバーがリクエストを受信し、データベースにデータを追加し、ストリーミングプラットフォーム/キューにメッセージを配置します。 WSサーバーはストリーミングプラットフォームからメッセージをプルし(それがpull-based Kafkaのようなプラットフォームである場合)、各メッセージ(イベント)で、WebSocket通信を介してすべてのクライアントにメッセージを送信します。

これを処理する理想的な方法は本当にありませんが、現在使用しているアーキテクチャは、メッセージ駆動型のマイクロサービスアーキテクチャの作成には問題がないようです。理想的には、本格的なReactiveアーキテクチャに拡張することもできます。

could技術的には、データベースに変更がないか(CHECKSUMを介して)または何かをチェックし、クライアントにブロードキャストするようにWSサーバーに通知するサービスもありますが、あなたはすでにREST APIを持っています、私は与えられたアプローチで行くと思います。

編集:カフカをより明確にするために、私は Robert's の回答で十分だと言いますが、詳しく説明すると、Kafkaは私の好みに過ぎないので、私はそれを選択しました答えを含めると、追加のリソースを提供しなければならないというオーバーヘッドが発生します(そしてZookeper)。しかし、これはこのような場合に最適です。 Kafkaサービスをそれに編み込み、トピックを通じてサービス間のデータのフローを確立できるので(永続的かつ分散した方法で!)とにかく、私たちは元の質問から分岐しているように感じます、あなたは彼らの公式の サイト でそれについて読むことができます。

3
Milan Velebit

ここから一歩下がって、目標と要件を明確にする必要があると思います。大きな問題は、各クライアントを更新することがどれほど重要かということです。すべてのクライアントに通知されなくても、トランザクションを完了できますか?答えが「いいえ」の場合、WebSocketがうまく機能するとは思いません。実際には、まったく異なる種類のアーキテクチャが必要になります。これは簡単に解決できる問題ではありません。 CAP定理 を参照してください。

これが問題でない場合、質問は次のようになります。すべてのクライアントにすべての変更を通知する必要があるか最終的に、またはクライアントがメッセージを見逃しても問題ないか彼らがオフラインである場合や、何かしゃっくりがある場合。後者の場合は、WebSocketで十分です。私はそうではないと感じています。

クライアントが確実に各メッセージを受け取るようにしたい場合は、Kafkaのようなpub-subモデルがおそらく良い解決策です。配信システムとしてWebSocketを使用するかどうかは、あなたはおそらく、クライアントが見逃したメッセージに追いつくことを可能にする追加のGET AP​​Iを提供したいと思うでしょう。Websocket接続はひどく信頼できず、サブスクリプションのようなモデルを(それ自体では)サポートしていません。

1
JimmyJames