97 lines
3.6 KiB
Markdown
97 lines
3.6 KiB
Markdown
# @go/gateway
|
||
|
||
基于 `@go/service` 和 Redis 的高性能、事件驱动的动态 API 网关。
|
||
|
||
`gateway` 专注于充当配置下发的搬运工,将路由匹配、转发等所有繁重工作剥离给底层的 `service` 核心。支持通过 Redis 进行 0 延迟、0 丢包的路由级全量/局部热更新。
|
||
|
||
## 功能特性
|
||
|
||
- **极致性能**:基于 `service` 包的 Copy-on-Write (写时复制) 原语,无锁构建,转发阶段无锁等待。
|
||
- **事件驱动热更新**:摒弃轮询,监听 Redis Pub/Sub,精准下发变更配置,旧连接不受影响。
|
||
- **服务发现原生集成**:与 `@go/discover` 无缝集成,支持基于服务名的直连与负载均衡。
|
||
- **生命周期接管**:由 `@go/starter` 接管,支持通过 `kill -SIGHUP` 触发本地全量重新同步。
|
||
|
||
## 路由匹配规则 (无需正则的高性能模式)
|
||
|
||
网关底层针对高并发场景深度优化,默认支持 O(1) 级别的哈希匹配和高性能前缀匹配,**极大程度地避免了正则表达式的性能开销**。
|
||
|
||
### 1. Host 域名自适应降级匹配
|
||
网关在匹配请求的 Host 时,遵循一套人性化的自动降级回退机制,确保最灵活的配置:
|
||
1. **精确域名+端口**: `aa.com:8080` (最高优先级)
|
||
2. **纯域名提取**: `aa.com` (能同时适配 `aa.com:8080` 和 `aa.com:80`)
|
||
3. **纯端口截获**: `:80` 或 `:8080` (匹配任意该端口的主机)
|
||
4. **全局通配符**: `*` 或空字符串 `""` (兜底拦截所有未匹配请求)
|
||
|
||
### 2. Path 路径极速前缀匹配
|
||
默认情况下,非正则路径是**精确绝对匹配**。为了取代高消耗的前缀正则,网关特别引入了 `/*` 高性能通配符:
|
||
- **精确匹配 (默认)**: `"Path": "/api"` 仅匹配完全等于 `/api` 的请求。
|
||
- **极速前缀匹配 (带 `/*`)**: `"Path": "/api/*"` 将匹配任何以 `/api/` 开头的请求,底层直接使用原生 `strings.HasPrefix` 剥离正则损耗。
|
||
- *路径截取映射*: 当配置 `{"Path": "/old/*", "ToPath": "/new/*"}` 时,请求 `/old/user/1` 会被极速映射为 `/new/user/1`。
|
||
|
||
*注:只有当匹配规则需要提取复杂的动态参数(如中间段 `$1` 捕获)时,才建议使用正则匹配 `^/api/([a-z]+)/xxx`。*
|
||
|
||
Gateway 将配置存储在 Redis 的 Hash 结构中,并按照 **Host (域名)** 进行字段隔离,提升拉取效率和管理粒度。
|
||
|
||
- **`gateway:proxies`** 代理规则
|
||
- **`gateway:rewrites`** 重写规则
|
||
- **`gateway:statics`** 静态目录服务
|
||
|
||
### 结构示例
|
||
|
||
假设配置的 Host 为 `api.example.com`:
|
||
|
||
```json
|
||
// HSET gateway:proxies "api.example.com"
|
||
[
|
||
{ "Path": "^/user/(.*)$", "AuthLevel": 0, "ToApp": "user-service", "ToPath": "/$1" },
|
||
{ "Path": "/direct", "AuthLevel": 0, "ToApp": "http://10.0.0.1:8080", "ToPath": "/hello" }
|
||
]
|
||
|
||
// HSET gateway:rewrites "api.example.com"
|
||
[
|
||
{ "Path": "^/old-api/(.*)$", "ToPath": "/api/$1" }
|
||
]
|
||
|
||
// HSET gateway:statics "www.example.com"
|
||
{
|
||
"/ui": "/var/www/html"
|
||
}
|
||
```
|
||
|
||
## 动态热更新 API (Pub/Sub)
|
||
|
||
无需重启进程,向 Redis 的 `gateway:channel` 频道发布 JSON 消息,网关会在收到消息后仅拉取变化的那一部分(局部全量更新):
|
||
|
||
```json
|
||
{
|
||
"action": "update",
|
||
"type": "proxy", // 可选: "proxy", "rewrite", "static"
|
||
"host": "api.example.com"
|
||
}
|
||
```
|
||
|
||
## 启动与管理
|
||
|
||
```bash
|
||
# 以后台进程启动
|
||
./gateway start
|
||
|
||
# 查看服务状态 (通过 IPC)
|
||
./gateway status
|
||
|
||
# 平滑重启 / 重载兜底
|
||
./gateway restart
|
||
./gateway reload # 触发底层 service 的 OnReload,全量同步 Redis
|
||
```
|
||
|
||
## 环境变量配置
|
||
|
||
支持通过环境变量或 `env.yml` 覆盖。
|
||
|
||
```yaml
|
||
gateway:
|
||
Redis: "127.0.0.1:6379"
|
||
Prefix: "gateway"
|
||
Channel: "gateway:channel"
|
||
```
|