質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
GlassFish

GlassFishは、Java EE準拠のアプリケーションサーバの名称です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

WebSocket

WebSocketとは双方向・全二重コミュニケーションのためのAPIでありプロトコルのことを指します。WebSocketはHTML5に密接に結びついており、多くのウェブブラウザの最新版に導入されています。

Q&A

1回答

5006閲覧

WebSocketの複数サーバー環境にて全クライアントにプッシュ通知を行いたい

sheltie

総合スコア0

GlassFish

GlassFishは、Java EE準拠のアプリケーションサーバの名称です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

WebSocket

WebSocketとは双方向・全二重コミュニケーションのためのAPIでありプロトコルのことを指します。WebSocketはHTML5に密接に結びついており、多くのウェブブラウザの最新版に導入されています。

0グッド

0クリップ

投稿2021/09/28 02:40

編集2021/09/28 22:50

前提・実現したいこと

WebSocketにてアプリケーションサーバーと常時接続しており、
随時リクエストとレスポンスの送受信を行うアプリを開発しています。
アプリケーションのイメージとしては、チャットや掲示板のようなもので、
リアルタイムに書き込み内容が他のクライアントへ反映されます。

クライアントからの書き込みに応じて他のクライアントへのプッシュ通知を行うのですが、
複数サーバー時にすべてのクライアントへプッシュ通知を行うことが実現できていません。

WebSocketにてプッシュ通知を行うアプリにおいて、複数サーバー時にすべてのクライアントへ通知を送信するには、どうすればよいでしょうか。

『接続形態』
・AP Server と Client は WebSocket にて常時接続している。
・AP Server は1台の場合もあれば、複数存在する場合もある。(クライアント数に応じて増設している)
・Client-A1, Client-A2 は AP Server-A に接続している。
・Client-B1, Client-B2 は AP Server-B に接続している。

text

1 +-------------+ 2+-----------+ | AP Server-A | 3| Client-A1 | <- WS -> | | 4+-----------+ | WebSockApp | 5 | | 6+-----------+ | | 7| Client-A2 | <- WS -> | | +-------------+ 8+-----------+ | | <- JDBC -> | DB Server | 9 +-------------+ | | 10 | | 11 +-------------+ | | 12+-----------+ | AP Server-B | <- JDBC -> | | 13| Client-B1 | <- WS -> | | +-------------+ 14+-----------+ | WebSockApp | 15 | | 16+-----------+ | | 17| Client-B2 | <- WS -> | | 18+-----------+ | | 19 +-------------+

実現できていること

・Client-A1 からの情報更新をトリガーにして、AP Server-A に接続している全クライアントへプッシュ通知を行う。
(この場合の通知対象は Client-A1, Client-A2)

・Client-B1 からの情報更新をトリガーにして、AP Server-B に接続している全クライアントへプッシュ通知を行う。
(この場合の通知対象は Client-B1, Client-B2)

発生している問題

・クライアントからの情報更新に応じて、すべての クライアントへプッシュ通知を行いたいが、実現できてない。
(この場合の通知対象は Client-A1, Client-A2, Client-B1, Client-B2)

考察

・AP Server-A からプッシュ通知が送信できるのは、自サーバーに接続しているクライアントのみ。

 『理由』
他サーバーに接続しているクライアントにはTCPコネクションが無いし、WebSocketのセッション情報も保持していないため。

試したこと・代替案

・すべてのクライアントが定期的にサーバーへリクエストを発行し、更新されていないかチェックする
→ この方法では無駄にサーバーの負荷が増大する。また、WebSocketを使用している意味が無いため、採用したくない。

・自サーバーに接続していないクライアントへのプッシュ通知要求が発生したときは、
APサーバーから他のAPサーバーへHTTP POST(Servlet等で中継)にてプッシュ通知の送信要求を連携する。
→ この方法ではサーバー数が増えるに従い無駄なPOSTリクエストが発生するため、採用したくない。

・自サーバーに接続していないクライアントへのプッシュ通知要求が発生したときの連携を、他のサーバーへHTTP POST(Servlet等で中継)ではなく
メッセージキューのPub/Subにて実施する。
→ 現在 ActiveMQ + リソースアダプタ + Message-driven Bean にて検証を実施中だが、安定して動作するかが不明。

補足情報(FW/ツールのバージョンなど)

・サーバーのOSは CentOS 8.2
・クライアントのOSは Windows10
・APサーバーのJavaバージョンは OpenJDK 1.8.0_252
・AP Server は GlassFish4系, Payara5系 (WebSocket実装はTyrus)
・Client は C#で自作 (WebSocket実装はwebsocket-sharp)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dodox86

2021/09/28 02:45

> → この方法ではサーバー数が増えるに従い無駄なPOSTリクエストが発生するため、採用したくない。 HTTPのPOSTメソッドに限らず、他サーバーへ通知するには何らかの通信が必要になる訳で、そういった経路は用意したくないということなのでしょうか。
jimbe

2021/09/28 03:35

プログラミング以前の問題で、SEらの「お仕事」のお話ではないでしょうか。
sheltie

2021/09/28 22:50

dodox86さん、質問ありがとうございます。 別の通信経路を用意するのは問題ありません。 ただ、連携時のサーバー負荷をできるだけ減らしたいです。 例えば、サーバーが3つで、下記のようにクライアントの接続数が偏っていて  サーバー1 <--> クライアント100台  サーバー2 <--> クライアントなし  サーバー3 <--> クライアント10台 (1) HTTP POSTで受け付けた連携処理に時間がかかってしまった (2) 多数のクライアントで同時期に更新がありプッシュ通知の連携要求が多発した のような場合、サーバー2にとっては(関係のないリクエストにより)DoSのような状態になってしまいます。 ※もちろん、このような場合はLB等で接続を分散させて平坦化するべきですが  クライアント数が偏ってしまう場合もありますので...
dodox86

2021/09/28 23:50

HTTPのように基本、リクエスト~レスポンスで回線をopen/closeするものでは負荷はまぁ少しは上がるでしょうけど、それが嫌なのであれば せっかくWebSocketを使っているのであれば、サーバー1~サーバーN間もWebSocketで繋げておけば良いんじゃないでしょうか。まとめられるメッセージはなるべくまとめるように工夫すればより負荷は下がります。同じマシン内ならプロセス間通信でもいいんじゃないでしょうか。どうしたってサーバー間で何らかの通信は発生します。
dodox86

2021/09/28 23:58

低評価はしていませんが、確かにまぁ、現状ちょっと漠然としていて質問と言うよりは設計や問題点の検討の依頼に読めなくはないですね。
sheltie

2021/09/29 16:32

別に「検討をしてくれ」「設計をしてくれ」という思いは全くありません。 個人で掲示板アプリを作成していくなかで、スケールアウトしてサーバー数が増えた場合に 実現したい機能をどのように実装すればよいか疑問が出てきたため、質問をした次第です。 ・世の一般的な(サーバー数が増減するような)WebSocketアプリでは、全クライアントへの同報ほどのように実現しているのか ・こういった方向で考えてみてはどうか?こういうアプローチではどうか?といった、考え方やおおよその方向性についての意見 といったような感じで、何か知見がありましたらご教示頂きたいと思っています。 それとも、ここ(teratail)では狭義の「プログラミング」に関することしか質問してはならず、 「どのように実現すればよいか」といった考え方についての質問はNGなのでしょうか?
jimbe

2021/09/29 18:11

> ここ(teratail)では狭義の「プログラミング」に関することしか質問してはならず ~ 私も単なる利用者ですので、それらを判断する権限はありません。 単なる個人の感想とご理解頂けると助かります。 また『「検討をしてくれ」「設計をしてくれ」』と仰っているとは捕らえておりません。というよりも逆に、マルチサーバ・負荷等も考慮しての「設計」は法人レベルでの経験やノウハウの現れる範囲ですので、それなりの所に依頼等をしたほうが "確実" なのでは…というのが私の考えです。 言ってみれば「〇〇に歩いていくにはどの道が良いでしょうか」とのご質問に「タクシー拾って行き先言ったほうが確実ではありませんか」と提案しているだけですので「いや、歩きますので」と言われれば「分かりました」と引き下がります。 大変失礼して申し訳ありませんでした。
guest

回答1

0

ここでの回答を待つ間にstackoverflow.comの過去Q&Aを精査してみました。
WebSocketサーバーのスケールに関して、関係のありそうなものを下記に挙げます。

Tomcat Websockets Across Multiple Servers

Multiple websockets onto multiple servers: how do they communicate?

Multi server tchat with Nginx and Nodejs Socket IO

How to effectively scale Websocket servers?

How to run WebSockets with multiple server instances?

Scaling WebSockets with a Message Queue

Websockets and scalability

回答は概ね下記のようになっていました。

回答1)APサーバー群の背後にデータをやり取りするバスのようなもの(たとえばRedisやMQなど)を用意し、それでサーバー間の連携を行う。
→ これが一番妥当そうです。

回答2)WebSocketコネクションを中継するサーバーを建て、クライアントはそのサーバーに接続してすべてのセッションがそのサーバーに存在するようにする。
→ SPoF的にそれはどうなの?また、コネクション数の上限が中継サーバーのスペックにより制限されるのでは?

回答3)すべての接続を処理できるデカいインスタンスを用意する(!)
→ 力技すぎる(笑)それにスケールしないので問題が解決できていないのでは?

投稿2021/10/26 01:10

sheltie

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問