スキップしてメイン コンテンツに移動

LLMサービス開発における HTTPS / SSE / WebSocket の選び方

 ――ストリーミング、同時接続、スケールの現実を踏まえた “規模別ベストプラクティス”

LLMのAPIは一見「リクエストを投げてレスポンスを受け取る」だけですが、実運用では次の要件が重なります。

  • **体感速度(TTFT:Time To First Token)**を良くしたい

  • 生成が数秒〜数十秒に及び、レスポンスが長い

  • **キャンセル(中断)**が必要(コストにも直結)

  • tool-call / progress / usage / error など、イベントを流したい

  • 同時利用者が増えた時の接続維持コスト(FD/メモリ/LBのidle timeout/再接続嵐)

そこで候補に挙がるのが:

  • 通常のHTTPS(リクエスト/レスポンス)

  • SSE(Server-Sent Events:サーバ→クライアントの一方向ストリーム)

  • WebSocket(双方向の常時接続)

※厳密には SSE も HTTPS 上で動きます。ここでは実務上の比較として
(A) 通常HTTPS vs (B) HTTPS+SSE vs (C) wss(WebSocket) という意味で扱います。


1. まずは一言でまとめる

方式一言で言うとLLMで向いている用途
通常HTTPS「送って、終わったら一回で受け取る」短い応答 / 最大スループット / 運用が簡単
SSE「1回送る → サーバがイベント/トークンを流し続ける(片方向)」トークンストリーミング / 進捗や状態イベント
WebSocket「1本の接続で双方向にメッセージを継続送受信」セッション型エージェント / リアルタイム双方向

2. LLM通信で重要な評価軸

LLMは “RPS(秒間リクエスト数)” だけ見ても本質を外しやすいです。特に重要なのは:

  • 同時生成(アクティブな待ち) = 流入率 × 平均生成時間

  • 接続維持コスト = 同時接続数 ×(FD/メモリ/バッファ/keepalive)

  • 再接続嵐(障害・通信揺れ・モバイル切替)

  • キャンセルの実効性(UIキャンセルが推論停止に直結するか)


3. 機能・運用・性能の比較表

3-1. 機能(UX/プロトコル)観点

項目通常HTTPSSSEWebSocket
トークンストリーミング可能(chunk)だが環境差が出やすい非常に適合(event-stream標準)適合
イベント種別分離(token/tool/progress)アプリで自由定義event/dataフレームで整理しやすいメッセージ型で整理可能
クライアント→サーバのリアルタイム入力毎回HTTPで送る別HTTPが必要同じ接続で可能
キャンセルcancel API or 切断検知切断検知しやすい + cancel APIも簡単メッセージで即時キャンセル可
再接続/続きから再開アプリ実装が必要自動再接続 + Last-Event-ID設計がしやすいアプリ実装が必要

要点

  • SSEの固有の強みは「サーバ→クライアントのストリーミングが標準化されている」「再接続パターンが作りやすい」点です。

  • 「クライアント→サーバを高頻度で送り続ける」なら、SSEは別HTTPを併用するため WebSocketの方が自然になりがちです。


3-2. 運用(大規模で壊れやすいポイント)観点

項目通常HTTPSSSEWebSocket
LB/プロキシ親和性最上概ね良い(バッファリング/idleに注意)環境によっては難易度↑(upgrade/idle)
接続維持コスト低(短いリクエストなら)高(ロングリビング接続)高(ロングリビング接続)
障害時の影響限定的再接続嵐への備えが要る再接続 + セッション/状態管理が要る
実装難易度中〜高

4. 「SSEは別HTTPが必要なら、通常HTTPと大差ないのでは?」への回答

指摘は正しいです。クライアント→サーバ入力が高頻度(例えば音声のフレーム送信、タイピングごとの逐次送信等)が本質なら、SSEは「アップロードはHTTP、ダウンロードはSSE」の 2チャネルになり、同期(順序・重複・レース)管理が面倒になります。

それでもLLMでSSEが多用される理由は、LLMが典型的に 非対称 だからです。

  • アップロードは1回(プロンプト)

  • ダウンロードは長い(トークンが延々出る)

  • クライアント→サーバの追加通信は多くの場合 低頻度(cancel / regenerate / ちょっとしたcontrol)

この「下り(サーバ→クライアント)が本体」のワークロードで、SSEの価値が出ます。


5. 規模別おすすめ(1,000〜10,000,000同時ユーザ)

ここでの「同時ユーザ」は、実務に合わせて 同時にLLM結果を待っている(=アクティブ生成)ユーザ として考えます。
(単なるログイン同時数とは別です)

5-1. 規模別おすすめ一覧

同時ユーザおすすめ第1選択SSE/WSの使い方通信観点の理由
1,000通常HTTPS +(任意で)SSEストリーミング必要ならSSEを広く採用可運用が簡単、UX改善の負担も小さい
10,000HTTPS + SSEストリーミングUXが重要ならSSEを標準化ここまでならチューニングで十分回る
100,000非同期ジョブ(HTTPS受付)+ 状態/結果取得(HTTPS)+ SSEは選別“画面で待ってるユーザ”だけSSE10万ロング接続は可能でも運用難度が急上昇(再接続嵐、FD、メモリ、idle)
1,000,000非同期ジョブ中心 + pull(HTTPS) + pushは最小SSE/WSは極小(プレミアム/運用コンソール)接続だけで巨大システムになる。ストリーミングは贅沢
10,000,000非同期ジョブ + キャッシュ/再利用 + 強い制限SSE/WSはほぼ禁止(特例のみ)1千万同時ストリーミングは「配信基盤」を運用する規模

6. 実務で強い “混合パターン”(10万以上で特に効く)

大規模になるほど、「単一プロトコルで統一」より 役割分担 が強くなります。

6-1. 定番アーキテクチャ(通信だけの観点)

目的通信
受付(キューイング/レート制限)HTTPS POSTPOST /llm/jobsjob_id
状態/結果取得(低コスト)HTTPS GETGET /llm/jobs/{id}
ストリーミング(必要なユーザだけ)SSEGET /llm/stream/{id}
キャンセル/制御HTTPS POSTPOST /llm/jobs/{id}/cancel

これが強い理由

  • 大半のトラフィックは短いHTTPSで捌ける(高RPS・運用容易)

  • ストリーミングは “今見てるユーザ” に限定できる(同時接続爆発を抑制)

  • キャンセルは高頻度でなければHTTPで十分速い(実装も簡単)

6-2. WebSocketが本当に向くのはどこ?

WebSocketは「チャットだから必須」ではなく、次の条件で強いです。

  • 入力も出力も高頻度(双方向で常に動く)

  • 1セッション内に多種メッセージ(入力/トークン/ツール/状態/キャンセル)を 単一接続で制御したい

  • 運用複雑度より “セッション型プロダクト価値” が大きい


7. 大規模でよく死ぬポイント(チェックリスト)

7-1. SSE/WS共通

  • idle timeout(LB/プロキシが切断)→ keepalive / ping が必要

  • バッファリング(途中の機器が溜めて一気に送る)→ ストリーム配信設定の見直し

  • 再接続嵐 → exponential backoff + jitter + 制限(トークンバケット等)

7-2. LLM特有

  • キャンセルが推論停止に繋がっていない → コスト爆発

  • キューイング設計がない → 10万で崩壊しやすい(受付/待ち/完了を分離)


まとめ:規模が上がるほど「HTTPが土台、ストリーミングは選別」

  • 1,000〜10,000:HTTPS + SSE のストリーミングが最もバランス良い

  • 100,000:HTTPS(受付/取得)を基盤にして、SSEは “必要ユーザだけ” に絞るのが最適

  • 1,000,000〜10,000,000:非同期ジョブ、キャッシュ、制限が主役。ストリーミングは贅沢品

  • WebSocketは “セッション型の双方向リアルタイム” が本質のプロダクトでのみ積極採用

コメント

このブログの人気の投稿

コピペができないときチェックすべきこと! :: よく迷うUiPathのコツ

UiPath( https://uipath.com )はMicrosoft社のWWFを改良した製品なのでVisual Studioより初心者向けに使いやすくなっている。 しかし、初心者がそのまま使うにはかなりのハドルがある。 理由は基本開発者向けの開発ツールを無理やり便利に作ってみたとしても開発の概念と考え方がないと結構躓くことが多い。 そのなかで私もよく迷ったりしていることの一つを整理しとく。 基本Activityはすぐコピぺができるので多数のUiPath Studioを開いて開発してたりする。 ここでコピペをしても反応ないときがよくある。 この場合はこれをチェックすること! 1.Sequenceがなく一つのActivityしかないところにはペーストできないのが多い。 例えば、ifの処理ボックスにはSequenceが最初はない。 そのボックスに一つのActivityはペーストできるのに2個目からはなぜか反応ない。 それで分からないまま新しいActivityを追加してたりしたが、 あそこにSequenceを入れたら解決ができるのだ! 2.正常にペーストできるはずのところに反応ない。 この場合はPackageが合わなくペーストが効かないケースが多い。 DESIGN>Manage Packagesをクリックしてコピー元のパッケージにインストールされているのにコピー先にインストールされてないパッケージを探す! パッケージを一々見るのが難しい!と思ったら メモ帳からファイルがあるフォルダにあるproject.jsonファイルを開いてみる! あそこにJSONの形式でインストールされたパッケージが見えるので比較しやすくなる! ちなみにコピペをすると変数の宣言が大変だと思うが、 そこでもコツがあるのだ! 変数の宣言はなるべく細かくしてSequence単位で管理できるようにする。 全てに影響がある変数はしょうがないから一番広く宣言するけど。 初心者向けの説明だと、 Variablesというところをクリックして変数を開いたらScopeという範囲が見える! 大体Sequenceボックスの名前を変えてないのでSequenceがすらりと表示されてるはずが、Sequenceボックスの名前を付けてたら見やすくなる。 あ...

面倒くさいORACLEの文字化け状況

ORACLEはそもそもUTF-8をサポートしてほかの言語はサポートはしているって書いてますが親切ではないようです。 現在サーバー側は昔からUS7ASCIIに設定して日本語を入れてしまい、データは7ビットASCIIモードで読み取りながら日本語のコートがOS側とクライアント側で変換しない必要があります。 クライアント側で文字化けの解決にはNLS_LANGの設定が効くクライアントが必要ですが、一部の有料クライアントにはサポートするようです。 接続構造は参考に https://www.oracle.com/technetwork/jp/content/charcterset-250314-ja.pdf の19スライドのように クライアントからNLS_LANGをUS7ASCIIに設定しても その設定した言語にもらったUTF-8のデータをクライアントが変換すると NLS_LANGを設定しても意味がないようです。 ORACLE SQL Developerがこの様です。 ODBCと直接接続は必ずUTF-8に変換してしまうのでUS7ASCIIになっているDBからはクライアントをいくら変換しても文字化けのままです。 必ずOCI接続を通じてクライアント側から読み取らないとUS7ASCIIは勝手に変換されますね。 この全ての条件が満たした無料クライアントはA5mk2の2.9.1バージョンだけですね。 A5MK2 ver.2.9.1 : https://a5m2.mmatsubara.com/download/a5m2_2.9.1_x64.zip 2.9.1 バージョンでサーバーを設定する場合Uicode変換を強制に無視するオプションがあります。 多分このバージョンの時点ではUTF-8をメインにして設計したDBが少なかったから文字化け対応のためできたオプションでしょう。 しかし、A5mk2の新しいバージョンにもまた結果の変換をしないオプションがなくなって文字化けしてしまいます。開発者はもうUTF-8ではないDBはないと思ってるでしょう。まだまだ残ってますよ~。 クライアント側からの変換などに参考になればと思います! まだ直接お仕事になさってますか? もう遅いです!ソフトウェアロボットにお仕事を任せてどの位自分の作業分量が減ってるかをご確認ください! https://talklowy-jp.b...

UiPath - Excelのシート名が存在した場合の処理

UiPath.Excel Activityは活用方法によってかなり強力ですが、隠れて探せない項目が多すぎて困ったりします。 公式ドキュメントもいまいちだし…。 Excelを自動化するには協力なUiPathの機能の中でSheetの判断処理を残します。 今まではシートがあったら何とかしようとしたら見つける方法が分からなく、ErrorのExceptionで判断したりしましたが、 workbook.GetSheets.Contains("<sheet name>") があったのをいまさら見つけました; 早速試してみましたが、 messageboxにworkbookとか書いてみても出てこない…。 これはExcel Application Scopeを利用しなければなりませんでした! まずExcel Application ScopeにExcelファイルを登録! Excel Application Scope Activityの属性にOutputにwbを入力して変数に入れます。 変数に入れてからMessageBoxに wb.GetSheet.Contains("Sheet1") を入力してみると成功! 「wb.」をおした時点でいっぱい出てきましたね。 ググってみても詳しく出て着なかったのでここにまず記録 giip - Free UiPath and Rpa Integrated Orchestration Service https://giipasp.azurewebsites.net