まず押さえておきたいポイント
Webアプリで「リアルタイムにAIの推論結果を届けたい」とき、HTTPのリクエスト/レスポンスだけだと遅く感じることがあります。そこで効くのが gRPCのServer‑Streaming と DjangoでのJWT認証、さらに EnvoyによるgRPC‑Web対応 です。組み合わせると「届いた瞬間に結果を描画する」体験が作れます。
ポイントまとめ
- Djangoは認証役:短い有効期限のJWTを発行し、セキュリティを保ちながらgRPCに渡す
- gRPCはServer‑Streaming:結果を小分けにしてすぐ返すことで、待ち時間を減らす
- EnvoyでgRPC‑Web化:ブラウザ対応のためにCORSとHTTP/2を必ず有効にする
- DataChannelは補助線:軽い進捗通知や小イベントをリアルタイムに返すのに最適
ありがちなつまずき
- EnvoyのupstreamをHTTP/1.1にしてしまい → ストリームが勝手に切断
- CORSヘッダに
grpc-timeout
やx-grpc-web
を入れ忘れ → ブラウザからの接続に失敗 - 結果を一括でまとめて返してしまい → 描画が固まる(小さく刻んでyieldが吉)
実用コード断片
Djangoで短命JWTを発行する例
from datetime import datetime, timedelta, timezone
import jwt
def issue_token(request):
now = datetime.now(timezone.utc)
payload = {"sub": str(request.user.id),
"exp": int((now + timedelta(minutes=5)).timestamp())}
return JsonResponse({"token": jwt.encode(payload, SECRET, "HS256")})
gRPCのServer‑Streaming実装例
class InferService(InferServicer):
async def Stream(self, request, context):
for chunk in run_model_iter(request.prompt):
yield InferReply(delta=chunk) # 小分けして即返す
Envoyの基本設定(抜粋)
http_filters:
- name: envoy.filters.http.grpc_web
- name: envoy.filters.http.cors
- name: envoy.filters.http.router
http2_protocol_options: {}
cors:
allow_headers: "content-type,x-grpc-web,x-user-agent,authorization,grpc-timeout"
運用で見たい指標
- p95 首バイト時間(最初のchunkが届くまでの速さ)
- エラー率:
UNAVAILABLE
やDEADLINE_EXCEEDED
が増えていないか - Envoyのhttp2エラー(
rx_messaging_error
など)で通信異常を把握
まとめ
「すぐ届く」を体感させるには、
- Djangoで短命JWTを発行しセキュアに、
- gRPCはServer‑Streamingで小さく速く返す、
- EnvoyでgRPC‑Web対応、
- 必要に応じてDataChannelで軽量通知。
この流れを押さえれば、ユーザーに「遅延ゼロ感」を届けられます。