From f0d04ff723f33a79f5085159dbc1fa7722adb5c8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 31 Mar 2026 11:41:55 +0000 Subject: [PATCH 1/2] Initial plan From aca1bea425692611999bb34d3d8e47afa33dc222 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 31 Mar 2026 11:50:23 +0000 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20CN=20relay=20Nginx=E5=90=AF=E5=8A=A8?= =?UTF-8?q?=E5=A4=B1=E8=B4=A5=20+=20=E8=AE=A2=E9=98=85=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=95=85=E9=9A=9C=E8=BD=AC=E7=A7=BB=20+=20=E9=AA=8C=E8=AF=81?= =?UTF-8?q?=E6=AD=A5=E9=AA=A4=E5=BC=BA=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根因: setup-cn-relay.sh使用systemctl reload但Nginx未运行→静默失败→端口2053未监听 修复: 1. setup-cn-relay.sh: reload→start/reload智能切换, 健康检查失败报错退出 2. subscription-server.js: 添加url-test自动选择组, SG直连优先, CN故障自动切换 3. deploy-proxy-service.yml: 验证步骤失败时报错不再静默通过 Agent-Logs-Url: https://github.com/qinfendebingshuo/guanghulab/sessions/e0510c81-17f8-4d94-955a-a2c8cfdf6fd3 Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com> --- .github/workflows/deploy-proxy-service.yml | 38 +++++++++++++-- server/proxy/service/subscription-server.js | 33 +++++++++++-- server/proxy/setup/setup-cn-relay.sh | 54 ++++++++++++++++++--- 3 files changed, 108 insertions(+), 17 deletions(-) diff --git a/.github/workflows/deploy-proxy-service.yml b/.github/workflows/deploy-proxy-service.yml index 36fa9156..a26423ad 100644 --- a/.github/workflows/deploy-proxy-service.yml +++ b/.github/workflows/deploy-proxy-service.yml @@ -287,16 +287,36 @@ jobs: # 通过SG跳板验证CN中转服务状态 echo "🔍 通过SG跳板验证CN中转..." - ssh cn-target " + VERIFY_RESULT=$(ssh cn-target " + FAIL=0 + echo '§1 Nginx状态:' - systemctl is-active nginx && echo ' ✅ Nginx运行中' || echo ' ❌ Nginx未运行' + if systemctl is-active --quiet nginx; then + echo ' ✅ Nginx运行中' + else + echo ' ❌ Nginx未运行' + FAIL=1 + fi echo '§2 中转端口 2053:' - ss -tlnp | grep -q ':2053 ' && echo ' ✅ 端口2053监听中' || echo ' ⚠️ 端口2053未监听' + if ss -tlnp | grep -q ':2053'; then + echo ' ✅ 端口2053监听中' + else + echo ' ❌ 端口2053未监听' + FAIL=1 + fi echo '§3 HTTP健康检查:' - curl -sf http://127.0.0.1/health 2>/dev/null && echo ' ✅ HTTP健康检查正常' || echo ' ⚠️ HTTP健康检查未响应' - " + if curl -sf http://127.0.0.1/health >/dev/null 2>&1; then + echo ' ✅ HTTP健康检查正常' + else + echo ' ⚠️ HTTP健康检查未响应' + fi + + exit \$FAIL + " 2>&1) && CN_OK=true || CN_OK=false + + echo "$VERIFY_RESULT" # 从外部验证CN HTTP (GitHub Actions可以通过HTTP访问中国服务器) CN_HOST="${{ secrets.ZY_CN_SERVER_HOST }}" @@ -307,6 +327,14 @@ jobs: echo "⚠️ CN HTTP外部检查: 状态码 $HTTP_CODE (可能需要等待或在防火墙开放80端口)" fi + # 关键服务必须运行 + if [ "$CN_OK" = "false" ]; then + echo "" + echo "❌ CN中转关键服务未就绪 (Nginx未运行或端口2053未监听)" + echo " 请检查CN服务器Nginx状态和腾讯云安全组2053端口" + exit 1 + fi + - name: '🧹 清理SSH密钥' if: always() run: rm -f ~/.ssh/id_sg ~/.ssh/id_cn ~/.ssh/config diff --git a/server/proxy/service/subscription-server.js b/server/proxy/service/subscription-server.js index 17774048..bfcec63b 100644 --- a/server/proxy/service/subscription-server.js +++ b/server/proxy/service/subscription-server.js @@ -167,14 +167,37 @@ function generateClashYaml(keys, serverHost) { client-fingerprint: chrome` : ''; // 代理组中的节点列表 + // SG直连优先 (更可靠的直连节点排在前面作为默认) const proxyList = cnRelayHost - ? ` - "🇨🇳 铸渊专线-CN中转" - - "🏛️ 铸渊专线-SG直连"` + ? ` - "🏛️ 铸渊专线-SG直连" + - "🇨🇳 铸渊专线-CN中转"` : ' - "🏛️ 铸渊专线-SG直连"'; const proxyListWithDirect = cnRelayHost - ? ` - "🇨🇳 铸渊专线-CN中转" + ? ` - "🏛️ 铸渊专线-SG直连" + - "🇨🇳 铸渊专线-CN中转" + - DIRECT` + : ` - "🏛️ 铸渊专线-SG直连" + - DIRECT`; + + // 自动选择组 (url-test: 自动测试延迟,选择最快可用节点) + // CN中转如果不可用(connection refused)会自动被排除 + const autoGroupBlock = cnRelayHost ? ` + - name: "♻️ 自动选择" + type: url-test + proxies: - "🏛️ 铸渊专线-SG直连" + - "🇨🇳 铸渊专线-CN中转" + url: "http://www.gstatic.com/generate_204" + interval: 300 + tolerance: 50 +` : ''; + + // 主代理组: 有CN时默认使用自动选择,无CN时直接使用SG + const mainGroupProxies = cnRelayHost + ? ` - "♻️ 自动选择" + - "🏛️ 铸渊专线-SG直连" + - "🇨🇳 铸渊专线-CN中转" - DIRECT` : ` - "🏛️ 铸渊专线-SG直连" - DIRECT`; @@ -211,8 +234,8 @@ proxy-groups: - name: "🌐 铸渊专线" type: select proxies: -${proxyListWithDirect} - +${mainGroupProxies} +${autoGroupBlock} - name: "🤖 AI服务" type: select proxies: diff --git a/server/proxy/setup/setup-cn-relay.sh b/server/proxy/setup/setup-cn-relay.sh index a0edeb95..acfa866a 100644 --- a/server/proxy/setup/setup-cn-relay.sh +++ b/server/proxy/setup/setup-cn-relay.sh @@ -279,8 +279,21 @@ log_step "§5 测试并应用配置" NGINX_TEST_OUTPUT=$(nginx -t 2>&1) if echo "$NGINX_TEST_OUTPUT" | grep -q "test is successful"; then - systemctl reload nginx - log_info "✅ Nginx配置测试通过 · 已重载" + # reload 只能用于已运行的Nginx,如果Nginx未运行则需要 start + if systemctl is-active --quiet nginx; then + systemctl reload nginx + log_info "✅ Nginx配置测试通过 · 已重载" + else + systemctl enable nginx 2>/dev/null || true + systemctl start nginx + if systemctl is-active --quiet nginx; then + log_info "✅ Nginx配置测试通过 · 已启动" + else + log_error "Nginx启动失败" + systemctl status nginx --no-pager 2>&1 || true + exit 1 + fi + fi else log_warn "Nginx配置测试未通过,尝试自动修复..." echo "$NGINX_TEST_OUTPUT" @@ -299,8 +312,14 @@ else # 重新测试 if nginx -t 2>&1; then - systemctl reload nginx - log_info "✅ 自动修复成功 · Nginx已重载" + if systemctl is-active --quiet nginx; then + systemctl reload nginx + log_info "✅ 自动修复成功 · Nginx已重载" + else + systemctl enable nginx 2>/dev/null || true + systemctl start nginx + log_info "✅ 自动修复成功 · Nginx已启动" + fi else log_error "Nginx配置测试失败 (自动修复未能解决)" nginx -t 2>&1 @@ -337,18 +356,39 @@ log_step "§7 健康检查" sleep 1 +# 确认Nginx真正在运行 +if ! systemctl is-active --quiet nginx; then + log_warn "Nginx未运行,尝试启动..." + systemctl enable nginx 2>/dev/null || true + systemctl start nginx + sleep 2 +fi + +HEALTH_OK=true + # 检查中转端口 -if ss -tlnp | grep -q ":${RELAY_PORT} "; then +if ss -tlnp | grep -q ":${RELAY_PORT}[[:space:]]"; then log_info "✅ 中转端口 ${RELAY_PORT}: 监听中" else - log_warn "中转端口 ${RELAY_PORT}: 未监听 (可能需要等待)" + log_error "中转端口 ${RELAY_PORT}: 未监听" + HEALTH_OK=false fi # 检查HTTP if curl -sf http://127.0.0.1/health >/dev/null 2>&1; then log_info "✅ HTTP健康检查: 正常" else - log_warn "HTTP健康检查: 未响应" + log_warn "HTTP健康检查: 未响应 (可能80端口被占用)" +fi + +# 如果关键端口未监听,报告Nginx状态用于调试 +if [ "$HEALTH_OK" = "false" ]; then + log_error "关键服务未就绪 · Nginx诊断信息:" + systemctl status nginx --no-pager 2>&1 || true + echo "" + echo "Nginx错误日志 (最后10行):" + tail -10 /var/log/nginx/error.log 2>/dev/null || echo " (无日志)" + exit 1 fi echo ""