From 777eb23b60c0e1e05c24b2df16875c1586ba3ac8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E5=8B=A4=E6=B0=91?= Date: Wed, 20 May 2026 19:06:07 +0800 Subject: [PATCH] =?UTF-8?q?fix(update):=20restart=E2=86=92up=20-d=20?= =?UTF-8?q?=E7=A1=AE=E4=BF=9D=E6=96=B0=E9=95=9C=E5=83=8F=E7=94=9F=E6=95=88?= =?UTF-8?q?=EF=BC=9B=E6=96=B0=E5=A2=9E=20WebSocket=20=E8=BF=9E=E9=80=9A?= =?UTF-8?q?=E6=80=A7=E8=87=AA=E6=A3=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将 docker compose restart 改为 up -d --no-deps: restart 仅重启容器进程,不切换镜像;up -d 检测镜像变更后重建容器, 是拉取新镜像后使其生效的正确方式 - 新增 Step 9 WebSocket 自检: · 探测容器 nginx → im-service 本地握手(HTTP 101 = 正常) · 同时探测外部域名 WebSocket 握手,失败时输出上层代理配置指引 (覆盖云 SLB/CDN 开启 WebSocket、nginx 补充四行头的两种场景) Co-Authored-By: Claude Sonnet 4.6 --- VERSION | 2 +- scripts/update.sh | 64 +++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 57 insertions(+), 9 deletions(-) diff --git a/VERSION b/VERSION index 1f73eec..2ac736a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2026.05.20-private.5 +2026.05.20-private.6 diff --git a/scripts/update.sh b/scripts/update.sh index 7b422e8..28c6345 100755 --- a/scripts/update.sh +++ b/scripts/update.sh @@ -431,7 +431,7 @@ else fi # --------------------------------------------------------------------------- -# Step 6 — 重启受影响的容器 +# Step 6 — 重启受影响的容器(up -d 确保应用已拉取的新镜像) # --------------------------------------------------------------------------- log "重启受影响的容器" @@ -445,13 +445,15 @@ _COMPOSE="docker compose --env-file ${ROOT_DIR}/.env \ -f ${ROOT_DIR}/docker-compose.yml \ -f ${ROOT_DIR}/docker-compose.infra.yml" -info "重启 tenant-service ..." -$_COMPOSE restart tenant-service -ok "tenant-service 已重启" +# 使用 up -d 而非 restart:restart 只重启容器进程,不会切换到新拉取的镜像; +# up -d 会检测镜像变更并重建容器,是应用新版本的正确方式。 +info "应用新镜像并重启 tenant-service ..." +$_COMPOSE up -d --no-deps tenant-service +ok "tenant-service 已更新" -info "重启 nginx ..." -$_COMPOSE restart nginx -ok "nginx 已重启" +info "应用新镜像并重启 nginx ..." +$_COMPOSE up -d --no-deps nginx +ok "nginx 已更新" # --------------------------------------------------------------------------- # Step 7 — 等待 tenant-service 健康 @@ -497,7 +499,53 @@ else fi # --------------------------------------------------------------------------- -# Step 9 — 全量验证 +# Step 9 — WebSocket 连通性自检 +# --------------------------------------------------------------------------- +log "检查 WebSocket 连通性" + +# 从服务器本地探测容器 nginx 的 /ws/im 升级握手是否正常 +# 正常响应:HTTP 101 Switching Protocols;异常:400 / 连接拒绝等 +_ws_probe="$(curl -sk --noproxy '*' --max-time 5 \ + -o /dev/null -w '%{http_code}' \ + -H "Upgrade: websocket" \ + -H "Connection: Upgrade" \ + -H "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==" \ + -H "Sec-WebSocket-Version: 13" \ + "http://127.0.0.1:${_NGINX_PORT}/ws/im" 2>/dev/null || echo 000)" + +if [ "$_ws_probe" = "101" ]; then + ok "容器 nginx → im-service WebSocket 握手正常 (HTTP 101)" + # 进一步探测外部域名(需要上层 TLS 代理正确透传 Upgrade 头) + if [ -n "$_CONSOLE_DOMAIN" ]; then + _ext_ws_url="$(printf '%s' "$_SDK_IM_WS_URL" | sed 's|wss://|https://|; s|ws://|http://|')" + _ext_code="$(curl -sk --max-time 8 \ + -o /dev/null -w '%{http_code}' \ + -H "Upgrade: websocket" \ + -H "Connection: Upgrade" \ + -H "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==" \ + -H "Sec-WebSocket-Version: 13" \ + "${_ext_ws_url}" 2>/dev/null || echo 000)" + if [ "$_ext_code" = "101" ]; then + ok "外部域名 WebSocket 握手正常 (HTTP 101) → ${_SDK_IM_WS_URL}" + else + warn "外部域名 WebSocket 握手失败 (HTTP ${_ext_code}) → ${_SDK_IM_WS_URL}" + printf '\n' + printf ' 上层代理(云 SLB / CDN / 其他服务器 nginx)需在转发规则中加入:\n\n' + printf ' proxy_http_version 1.1;\n' + printf ' proxy_set_header Upgrade $http_upgrade;\n' + printf ' proxy_set_header Connection "upgrade";\n' + printf ' proxy_read_timeout 3600s;\n\n' + printf ' 云负载均衡(SLB/ALB):在监听器配置中开启 WebSocket 支持。\n' + printf ' Nginx:在 location / 块中补齐以上四行,nginx -s reload 生效。\n\n' + fi + fi +else + warn "容器 nginx WebSocket 握手异常 (HTTP ${_ws_probe}),请检查 im-service 是否正常运行" + info "排查命令: docker compose logs --tail 50 im-service" +fi + +# --------------------------------------------------------------------------- +# Step 10 — 全量验证 # --------------------------------------------------------------------------- log "运行全量验证"