Repository navigation
fix(deploy): stop SSE streams from exhausting browser HTTP/1.1 connections - #836
Merged
Merged
Conversation
…tions Browsers cap HTTP/1.1 at ~6 concurrent connections per origin, and every SSE stream holds one for its lifetime, so a few open bot session tabs could stall all other requests behind the nginx entrypoint (#822). - server: send X-Accel-Buffering: no from every SSE endpoint via a shared setSSEHeaders helper, so nginx (and compatible proxies) never buffer event streams regardless of location-level config. - nginx: forward Connection: upgrade only for real protocol upgrades (map $http_upgrade), and give the long-lived SSE endpoints a dedicated location with proxy buffering off, gzip off, and 1h read timeout. - nginx: add an optional HTTPS + HTTP/2 entrypoint on 8443 that 15-memoh-https.sh auto-enables when TLS certs are mounted; h2 multiplexing carries all streams over one TCP connection, removing the per-origin connection limit for good. The shared server config moved to an include so both entrypoints stay identical; the upstream hop stays HTTP/1.1 so the Go backend needs no changes. Closes #822 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #822
问题
浏览器对同一 origin 的 HTTP/1.1 并发连接上限约 6 条,每条 SSE 流长期独占一条连接。多开标签页 / 多个 bot 会话页时连接配额被占满,后续 REST 请求排队等待,页面整体卡死。
修复内容
后端:所有 SSE 端点发送
X-Accel-Buffering: no抽出共享的
setSSEHeadershelper,统一覆盖全部 5 处 SSE 端点(session 消息流、bot 活动流、web/stream、bot 创建流、容器创建流、display prepare 流)。nginx 及兼容反代会按响应关闭缓冲,事件即时下发,无需依赖 location 级配置。nginx:SSE 反代优化
Connection: upgrade改为map $http_upgrade $connection_upgrade,仅在真正的协议升级请求上传递(原来对所有请求无条件设置,不规范);sessions/*/messages/events、sessions/events、web/stream)加专用 location:proxy_buffering off、gzip off、读超时拉长到 1h。nginx:可选 HTTPS + HTTP/2 入口(根治)
docker-entrypoint.d/15-memoh-https.sh在检测到证书(默认/etc/nginx/certs/server.crt|key,路径可用MEMOH_TLS_CERT/MEMOH_TLS_KEY覆盖)时自动启用,无证书时保持纯 HTTP,行为完全向后兼容;conf.d/includes/memoh-app.conf),HTTP 与 HTTPS 两个入口行为保持一致;docker-compose.yml中提供注释掉的8443端口映射与证书挂载示例(自签 / mkcert / Let's Encrypt 均可)。验证
TestBeginSSEResponseSetsProxyFriendlyHeaders守护 SSE 头契约(TDD:先红后绿);go test ./...全量通过,golangci-lint无告警;nginx:alpine实际渲染模板双模式验证:无证书 → 仅 HTTP、nginx -t通过;有证书 → HTTPS 入口启用、curl --http2实测返回HTTP/2 200;/api/bots/*/sessions/*/messages/events→ 去掉/api前缀、查询串保留,普通/api/*路由不受影响。未包含(issue 中的可选项)
前端 BroadcastChannel / SharedWorker 共享 SSE 流的兜底方案未包含在本 PR——启用 h2 后收益有限,如仍需要建议单开 issue 跟进。
🤖 Generated with Claude Code