ネットワーク系サーバーアプリケーションはどう作るべきか?
大量のクライアントから接続されても問題なく動いてほしい。
できる限り応答を早くしたい。
マルチCPU、マルチコアならば同時に複数のプロセス・スレッドを動かせるようにしたい。
何らかの不具合が起こったときには、安全にその通信を終了して、他に影響が出ないようにしたい。
できる限り軽量になっていてほしい。(リソースを使わない)
設定変更時には安全に切り替わってほしい。(いちいち終了せずに、変更部分だけを取り込んでほしい)
アプリケーション側の実装では通信の詳細を知らなくてもいいようにしてほしい。
要はデータの送受信とクローズ(切断)だけが分かる仕掛けになっていてほしい。
認証と認可は別に切り出しておいてほしい。
DoS に対する耐性を持っていてほしい。(本質的に難しいか?)
DDoS になると、アドレスがその都度変わってしまうのでブロックが困難になる。
同期処理
要求を出してから応答(結果)があるまで待つ。
受信するまで待ち。
CPUを占有し、送信が終わるまで、他の処理を行わない。
(正確にはマルチプロセスによるタスクディスパッチが別途発生する)
設計が容易。
非同期処理
先に要求を出す。応答(結果)は後から返ってくる。
受信イベントが発生するたびに処理する。
送信中、何らかの待ちが発生する場合には、CPUを明け渡す。
設計が難しい。
シングルプロセス
シングルプロセス、シングルスレッド(疑似マルチスレッド)
他の応答が待たされる。
マルチCPU、マルチコアが活用されない。(他の処理との多重化はされるから構わないという考え方もできるが)
シングルプロセス、マルチスレッド
何らかの不具合でスレッドが壊れた時には、他のスレッドも巻き添えになる。
マルチプロセス
Unix 系なら accept の度に fork する。
何らかの不具合でプロセスが壊れた時にはプロセス再起動でよい。
1セッションしか認めず、シングルプロセスで着信(accept)して、同期処理。
1クライアントしか存在しないことが確定している場合のみ選択可能。
シングルプロセスで非同期処理
シングルプロセス、マルチスレッドで同期処理
マルチプロセスで同期処理
システムコールの違い
select
いにしえから存在する基本的な待ち受けAPI
poll
epoll
IOCP (Input/Output Completion Port)
https://learn.microsoft.com/ja-jp/windows/win32/fileio/i-o-completion-ports
I/Oの完了時にスレッドプールからスレッドを起動するための仕組み
メモ
Ruby: fork(2)がみんなに嫌われる理由(翻訳) - TechRacho
https://techracho.bpsinc.jp/hachi8833/2025_03_14/148633
TCPサーバーの非同期処理はけっきょくどの手法がいいのか?
https://qiita.com/0xfffffff7/items/b846d8f6c0593fd73403
Windowsのソケット通信関連技術(Winsock、IOCP、スレッドプールI/O、RIO(Registered I/O)) ※膨大なため随時追記中
https://qiita.com/mayo00/items/6b88294664ce2883c67a
https://learn.microsoft.com/ja-jp/windows/win32/procthread/thread-pool-api