Apache 反向代理下配置 WebSocket 完整教程(宝塔面板 + Go 二进制)

admin
11
2026-05-29

Apache 反向代理下配置 WebSocket 完整教程

适用场景:后端为 Go 二进制(如监听 127.0.0.1:8091),前面使用 Apache(宝塔面板常见)做 HTTP/HTTPS 反向代理。
不装 Nginx 也可以,但 必须在 Apache 里单独处理 WebSocket 握手,否则会出现实时消息、售后聊天、通知推送连不上的问题。


一、先搞懂:为什么会出现这条报错?

后端日志里若看到类似:

WebSocket 升级失败: websocket: the client is not using the websocket protocol:
'upgrade' token not found in 'Connection' header

含义是:到达 Go 的请求是普通 HTTP GET,不是 WebSocket 握手

常见原因分三类:

类型 说明 是否影响业务
误访问 浏览器地址栏直接打开 http://域名/api/ws/... 一般可忽略
反代未配 WS Apache 只写了 ProxyPass,未转发 Upgrade 会导致聊天/通知失效
探活/扫描 监控工具用 HTTP 探测 WS 路径 可忽略

结论:你即使用二进制启动 Go、不装 Nginx,只要域名前面有 Apache 反代,就必须给 WebSocket 单独加规则。


二、架构示意

浏览器 --wss/https--> Apache (80/443) --ws/http--> Go 二进制 (127.0.0.1:8091)
普通页面 /API:ProxyPass http://
WebSocket:需 Upgrade 转发到 ws://

本项目中 WebSocket 入口示例:

  • 售后/全局消息:/api/ws/aftersale?token=你的JWT
  • 接单大厅:/api/ws/lobby?token=你的JWT

前端在 HTTPS 页面下应连接:wss://你的域名/api/ws/aftersale?token=xxx


三、前置条件检查清单

在改配置前,请确认:

  1. Go 服务已监听 8091(或你自定义端口),本机可访问:
    curl http://127.0.0.1:8091/health
  2. 防火墙/安全组 已放行对外 80、443(Apache);8091 通常只本机访问,不必对公网开放。
  3. 站点已配置反代http://127.0.0.1:8091/(你当前的宝塔写法)。
  4. 若站点启用 HTTPS,必须同时改 443 的 VirtualHost,不能只改 80。

四、第一步:启用 Apache 模块(宝塔)

路径:软件商店 → Apache → 设置 → 模块 / 加载模块

请确保已启用:

  • proxy
  • proxy_http
  • proxy_wstunnel(WebSocket 关键模块)
  • rewrite

保存后 重载配置重启 Apache

若没有 proxy_wstunnelRewriteRule ... ws://... [P] 无法生效,WebSocket 一定失败。


五、第二步:修改站点 Apache 配置(核心)

5.1 找到配置位置

宝塔:网站 → 你的站点 → 设置 → 配置文件(Apache)。

找到类似段落:

# HTTP反向代理相关配置开始 >>>
...
# HTTP反向代理相关配置结束 <<<

5.2 推荐完整写法(80 端口示例)

将中间反代段 整体替换 为:

# HTTP反向代理相关配置开始 >>>
<IfModule mod_proxy.c>
    ProxyRequests Off
    SSLProxyEngine on
    ProxyPreserveHost On

    # ---------- WebSocket 升级转发(必须) ----------
    RewriteEngine On
    RewriteCond %{HTTP:Upgrade} =websocket [NC]
    RewriteCond %{HTTP:Connection} upgrade [NC]
    RewriteRule ^/(.*) ws://127.0.0.1:8091/$1 [P,L]

    # ---------- 普通 HTTP 请求 ----------
    ProxyPass / http://127.0.0.1:8091/
    ProxyPassReverse / http://127.0.0.1:8091/
</IfModule>
# HTTP反向代理相关配置结束 <<<

说明:

  • 8091 改成你 Go 程序实际监听端口。
  • RewriteRule 必须在 ProxyPass 之前生效:带 Upgrade: websocket 的请求走 ws://,其余走普通 HTTP。
  • [P,L] 表示通过代理模块处理并停止后续规则。

5.3 你原来的配置缺了什么?

仅下面两行时,页面和 API 正常,WebSocket 会失败

ProxyPass / http://127.0.0.1:8091/
ProxyPassReverse / http://127.0.0.1:8091/

因为 Apache 默认不会把 WebSocket 握手头转发成后端所需的 Connection: Upgrade


六、HTTPS(443)站点也要同样配置

若用户访问 https://pp.example.com,浏览器 WebSocket 使用 wss,走的是 443 的 VirtualHost。

请务必在 SSL 站点 的配置里加入 与 80 相同RewriteEngine + ProxyPass 段。

只改 80、不改 443 的典型现象:

  • 网站能打开(https)
  • 接口大部分正常
  • 实时消息、未读气泡、聊天一直连不上

七、验证是否配置成功

7.1 浏览器开发者工具

  1. 登录你的前台/后台页面。
  2. F12网络 (Network) → 筛选 WS
  3. 找到类似:/api/ws/aftersale?token=...
  4. 正常状态应为:101 Switching Protocols(已建立 WebSocket)。

若显示失败、一直 pending、或很快断开,优先检查 Apache 模块与 443 配置。

7.2 看 Go 日志

配置正确后:

  • 不应再频繁刷 upgrade token not found(偶发误访问可忽略)。
  • 连接成功会有业务侧日志(视项目而定)。

7.3 本机直连对比(排查用)

在服务器上:

curl http://127.0.0.1:8091/health

若本机正常、域名不正常,问题在 Apache 反代层,不是 Go 程序本身。


八、与「不装 Nginx、二进制启动」的关系

说法 是否正确
Go 二进制直接跑,可以不装 Nginx
前面没有反代,浏览器直连 IP:8091 一般不需要 Apache 配置
域名走宝塔 Apache 反代到 8091 必须配 WebSocket,与是否 Nginx 无关

你当前属于第三种:Apache 反代 + Go 二进制,按本文配置即可,无需再装 Nginx。


九、前端连接注意事项(开发参考)

  1. 协议跟随页面:HTTPS 页面必须用 wss://,HTTP 用 ws://
  2. Token 建议 URL 编码token=${encodeURIComponent(jwt)},避免特殊字符截断。
  3. 路径与后端一致:例如 /api/ws/aftersale

示例:

const wsUrl = `wss://${location.host}/api/ws/aftersale?token=${encodeURIComponent(token)}`
const ws = new WebSocket(wsUrl)

十、常见问题 FAQ

Q1:配了 Rewrite 仍连不上?

  • 确认 proxy_wstunnel 已启用并重载 Apache。
  • 确认改的是 用户实际访问的端口(https 改 443)。
  • 确认 Go 监听地址是 127.0.0.1:8091 与配置一致。

Q2:只有 WebSocket 报错,网站正常?

说明 HTTP 反代 OK,仅缺 WS 规则,按第五节补 RewriteEngine 即可。

Q3:可以用宝塔「反向代理」界面吗?

可以填目标 URL http://127.0.0.1:8091,有 WebSocket 开关请打开;但 Apache 环境下仍建议在 配置文件 中保留 RewriteRule,最稳妥。

Q4:需要给 8091 开端口给外网吗?

通常 不需要。外网只访问 80/443,由 Apache 转发到本机 8091。

Q5:和 Nginx 的配置等价吗?

思路相同:都要转发 UpgradeConnection。Nginx 写法是 proxy_set_header Upgrade $http_upgrade; 等;Apache 用本文 RewriteRule + proxy_wstunnel


十一、配置模板速查

仅本机 Go、无反代: ws://服务器IP:8091/api/ws/aftersale?token=xxx

域名 + Apache + HTTPS: wss://你的域名/api/ws/aftersale?token=xxx

Apache 反代核心三行逻辑:

  1. RewriteEngine On
  2. 检测 Upgrade=websocket → 转发到 ws://127.0.0.1:端口
  3. 其余请求 ProxyPasshttp://127.0.0.1:端口

十二、小结

  • 不装 Nginx、二进制跑 Go 完全可行。
  • 只要 Apache(宝塔)反代 到你的 Go 端口,就必须配置 WebSocket 升级转发
  • 核心是启用 proxy_wstunnel,并添加 RewriteRule ... ws://... [P,L]
  • HTTPS 站点(443) 与 HTTP(80)要同步修改。
  • 用浏览器 WS 面板看到 101 即表示成功。

按本文操作后,实时聊天、消息推送、接单大厅等依赖 WebSocket 的功能即可与 API 一样稳定对外服务。


本文由小氢云相关部署实践整理,如有环境差异(OpenLiteSpeed、CDN 等)可在评论补充。