Appearance
Go WebSocket 网关
网关是分布式架构的入口,负责将客户端连接分发到多个 IM 后端实例。
工作原理
客户端 A ──┐
客户端 B ──┼──▶ Go 网关 (:8080) ──┬──▶ IM 实例 1 (:3000)
客户端 C ──┤ ├──▶ IM 实例 2 (:3001)
客户端 D ──┘ └──▶ IM 实例 3 (:3002)网关对客户端透明:所有 WebSocket 连接和 HTTP 请求都通过网关统一入口,网关内部选择后端实例进行转发。
核心功能
WebSocket 代理:客户端与网关建立 WebSocket 连接后,网关选择一个健康的后端实例,与之建立上游 WebSocket 连接,然后双向透传消息帧。
HTTP API 代理:REST API 请求同样通过网关转发到后端,客户端只需知道网关地址。
健康检查:网关定期探测后端实例,自动摘除不健康的节点,恢复后自动加回。
负载均衡:默认使用 Round-Robin(轮询)策略,均匀分配连接到各后端。
配置文件
网关配置位于 server/gateway/gateway.yaml:
yaml
port: 8080 # 网关监听端口
backends: # 后端 IM 实例列表
- ws://localhost:3000
- ws://localhost:3001
- ws://localhost:3002
balance_mode: round_robin # 负载均衡策略(当前仅支持 round_robin)
health_check: true # 是否启用健康检查
health_interval: 10 # 健康检查间隔(秒)编译
需要安装 Go 1.21+:
bash
cd server/gateway
# 编译当前平台
go build -o ../dist/im-gateway
# 交叉编译 Linux
GOOS=linux GOARCH=amd64 go build -o ../dist/im-gateway-linux
# 交叉编译 Windows
GOOS=windows GOARCH=amd64 go build -o ../dist/im-gateway.exe也可以从项目根目录通过 npm 脚本编译:
bash
npm run build:gateway:linux部署
将编译好的 im-gateway 二进制放到服务器上,确保 gateway.yaml 在同目录下:
/opt/im/
├── im-gateway # Go 网关二进制
├── gateway.yaml # 网关配置
├── im-server-1/ # IM 实例 1
│ ├── im-server
│ └── config.yaml
├── im-server-2/ # IM 实例 2
│ ├── im-server
│ └── config.yaml
└── im-server-3/ # IM 实例 3
├── im-server
└── config.yaml启动顺序:先启动各 IM 后端实例,再启动网关。
bash
# 启动后端实例(每个实例不同端口)
cd im-server-1 && PORT=3000 STORAGE=mysql MESSENGER=redis ./im-server &
cd im-server-2 && PORT=3001 STORAGE=mysql MESSENGER=redis ./im-server &
cd im-server-3 && PORT=3002 STORAGE=mysql MESSENGER=redis ./im-server &
# 启动网关
./im-gateway前端对接
前端只需将连接地址改为网关地址:
javascript
// config.js
const config = {
imBaseURL: 'https://chat.example.com', // 指向网关
wsURL: 'wss://chat.example.com', // 指向网关
}网关会自动将请求转发到后端,前端无需感知多实例的存在。
Nginx 反代(推荐)
生产环境建议在网关前再加一层 Nginx 处理 TLS 终止和静态资源:
nginx
upstream im_gateway {
server 127.0.0.1:8080;
}
server {
listen 443 ssl;
server_name chat.example.com;
ssl_certificate /etc/ssl/cert.pem;
ssl_certificate_key /etc/ssl/key.pem;
# WebSocket
location /ws {
proxy_pass http://im_gateway;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
}
# REST API
location /api/ {
proxy_pass http://im_gateway;
proxy_set_header X-Real-IP $remote_addr;
}
# 静态资源
location / {
proxy_pass http://im_gateway;
}
}