質問: 前書き: 知識不足な点が多く、見当違いなことや的外れなことを書いていたら申し訳ございません。 分からない事: サーバーアプリケーションでのマルチスレッド(マルチプロセス)を使用した最適な設計 作成したいプログラム: スマートフォンから受信したデータを保存するサーバー スマートフォンとの通信 :gRPC スマホから受信したデータの管理: MySQL 考えている動作の流れ 1. スマホからgRPCの送信 2. サーバーでgRPCの受信 3. 受信したデータ内のユーザートークンを検証 4. トークンが正しいものであれば、DBへ書き込み。 5. スマホへgRPCのレスポンス送信(DBへ書き込めたらTreu, トークンが誤っているなどDBへ書き込めなかったらFalse) これを実装するために、以下の2通りの構成を考えました。 1スマートフォンとの通信で生成されるgRPCの通信スレッドを親として、そこに子スレッドとしてユーザートークンの認証スレッド、SQLへのデータ保存スレッドを生成する。各スレッド間はPipeで通信し、gRPC受信データ、ユーザー認証結果、SQL書き込み結果をやり取りする。 スマートフォンとの通信が終わると、gRPCの通信スレッドが終了し、子スレッドも終了する。 メリット: 常時展開するスレッド数が少なくて済む? デメリット: gRPCの通信が発生するたびに、新しくスレッドを生成するコストが発生する? ![画像の説明をここに入力](https://i.stack.imgur.com/kpbZl.jpg) 2gRPCスレッドはスマートフォンとの通信で生成される。ユーザートークンの認証スレッド、SQLへのデータ保存スレッドは一定数を事前に生成しておき、ループ文で待機させておく。 各スレッド間はPipeで通信し、gRPC受信データ、ユーザー認証結果、SQL書き込み結果をやり取りする。 メリット: ユーザー認証、SQLデータ保存の応答が早い? デメリット: 常に展開しているスレッドが多い。gRPCのスレッドが増えたときに、ユーザー認証スレッドとSQLデータ保存スレッドが不足する可能性がある? ![画像の説明をここに入力](https://i.stack.imgur.com/jaQ1Q.jpg) また1、2の共通する疑問として、スレッド数に合わせたPipeを生成してよいのか分かりません。 各モジュール間をつなぐPipeは1つだけにした方が良いのでしょうか? (Pipeに出し入れするデータにスレッドIDのような識別子をつけて、Pipeから得たデータはモジュールごとの共有メモリに入れ、各スレッドは共有メモリを参照するなど?) どちらの設計が良いか、またそもそもどちらも間違っていてるか、そして正しい設計があればご教授いただけると幸いです。 よろしくお願いいたします。 追記: クライアントの同時接続台数は最大で約5000台を想定しています。 少ない時で数十台です。 通信の頻度は一日一回2,3時間程度。その間は約500ms周期で数十KBのデータを受信します。 高いリアルタイム性は必要ありませんが、スマートフォンにレスポンスを返したいので数秒~10秒程度の遅延に抑えたいです。
回答: > > クライアントの同時接続台数は最大で約5000台を想定しています。 > > > その規模であれば個人的には非同期一択だと思います。質問文では非同期に言及されていないので抜本的な設計見直しが必要かもしれません。 非常にざっくりとした説明となりますが、非同期とはネットワークなどのIO処理をOSに任せ完了したら通知してもらうプログラミングモデルです。プログラム側からは指示を出すことがメインとなるため、多数のスレッドは必要としません。 > > スマートフォンにレスポンスを返したいので数秒~10秒程度の遅延に抑えたいです。 > > > 普段の利用でスマホの画面を10秒も待ち続けることはありますか? とりあえず再実行とか押したくなりませんか? その瞬間にリクエストが数倍に膨れ上がります。