Skip to main content

网关服务 (Gateway Service)

1. 快速了解​

核心特性​

功能说明状态
🔐 ECC加密ECC+AES-GCM端到端加密✅ 生产可用
🛡️ 防重复提交多维度防重复提交保护✅ 生产可用
🔑 认证授权JWT令牌、SSO单点登录✅ 生产可用
🏢 多租户租户隔离和权限控制✅ 生产可用
🚀 灰度发布多维度Canary发布✅ 生产可用
⚡ 熔断限流Sentinel统一保护✅ 生产可用
🌍 国际化多语言支持✅ 生产可用

技术栈​

技术版本
Spring Cloud Gateway4.x
Java21 (ZGC)
Sentinel最新版
Redis6.x+
Nacos2.x

2. 部署架构​

网关支持两种主流部署模式:ECS传统部署和K8S容器化部署。不同部署环境下,网关在网络架构中所处的位置和职责有所不同。

ECS部署架构​

架构概述​

在ECS部署环境中,网关作为统一入口,所有内外网请求都必须经过网关进行鉴权和路由转发。内外网请求使用独立的网关实例,确保安全隔离。

网络拓扑​

核心特点​

前置层:

  • LB软负载均衡: 接收所有公网请求,分发到多个Nginx实例
  • 方案1: Nginx多实例 - LB分发到多台Nginx实例,Nginx转发到Gateway
  • 方案2: Nginx多实例 + Keepalive - LB分发到多台Nginx实例,Nginx通过Keepalive实现VIP高可用,再转发到Gateway

网关层:

  • 外网网关: 独立集群,分为ToB和ToC两套独立的网关实例
    • ToB网关:处理企业客户请求
    • ToC网关:处理个人用户请求
  • 内网网关: 独立集群,处理ECS内网请求
  • 多实例部署: 所有网关均采用多实例部署,确保高可用

安全机制:

  • ✅ 内外网隔离: 内外网网关完全独立,物理/逻辑隔离
  • ✅ 强制鉴权: 所有请求(包括内网请求)都必须经过网关鉴权
  • ✅ 防非法访问: 防止ECS内网非法访问,即使内网请求也需要通过网关验证身份

请求流向:

外网请求: 客户端 → LB → Nginx → 外网Gateway(ToB/ToC) → 业务服务集群
内网请求: ECS内网客户端 → 内网Gateway → 业务服务集群

流量隔离说明​

隔离策略:

  • 🔒 ToB和ToC网关完全隔离,互不干扰
  • 🔒 内网网关独立部署,与公网网关物理隔离
  • 🔒 所有网关均需进行鉴权,防止非法访问

K8S部署架构​

架构概述​

在K8S容器化部署环境中,网关作为集群入口,所有公网请求必须经过网关。服务间请求可以通过K8s Service直接通信,无需经过网关,利用K8s的CoreDNS和Service机制实现负载均衡和路由。

网络拓扑​

核心特点​

入口层:

  • LB软负载均衡: 接收公网请求,分发到多个Ingress Controller实例
  • Ingress Controller: 多实例部署,根据Ingress规则将请求路由到Gateway Service

网关层:

  • Gateway Service: K8s Service,通过CoreDNS进行服务发现
  • Gateway Pods: 多实例部署,通过Service实现负载均衡
  • 公网流量: 所有公网请求必须经过Gateway Pod

业务服务层:

  • Service间通信: 服务间请求可直接调用,无需经过Gateway
  • CoreDNS + Service: 利用K8s原生服务发现和负载均衡
  • NetworkPolicy: K8s网络策略保证服务间安全,替代请求签名

安全机制:

  • ✅ K8s安全: 通过NetworkPolicy、RBAC等机制保证服务安全
  • ✅ 无需签名: 服务间请求无需签名验证,由K8s保证安全
  • ✅ CoreDNS路由: 通过CoreDNS实现服务发现和负载均衡

请求流向:

公网请求: 客户端 → LB软负载均衡 → Ingress Controller → Gateway Service → Gateway Pod → 业务Service → 业务Pod
服务间请求: Service Pod → 目标Service (CoreDNS) → 目标Pod (直连,无需Gateway)

服务间通信模式​

K8s Service路由机制​

K8s原生能力:

  • 🔍 CoreDNS: 自动解析Service名称到ClusterIP
  • ⚖️ Service负载均衡: 自动在Pod间分发请求
  • 🔒 NetworkPolicy: 定义Pod间网络访问规则
  • 🛡️ RBAC: 控制Pod的访问权限

两种部署模式对比​

对比维度ECS部署K8S部署
前置层LB软负载均衡 → Nginx多实例 或 Nginx多实例 + KeepaliveLB软负载均衡 → Ingress Controller多实例
网关部署多实例独立部署多Pod通过Deployment部署
请求路径所有请求必过Gateway公网请求过Gateway,服务间直连
负载均衡Nginx/LBCoreDNS + Service
服务发现注册中心(Nacos)CoreDNS + Service
安全机制网关鉴权 + 请求签名K8s NetworkPolicy + RBAC
服务间通信需要签名,可选过Gateway无需签名,直连,由K8s保证安全
隔离策略内外网独立网关,ToB/ToC独立通过Namespace隔离
运维复杂度需要手动配置Nginx、KeepaliveK8s自动化管理
扩展性手动扩容自动扩缩容(HPA)

选择建议​

选择ECS部署:

  • ✅ 传统企业环境,已有ECS基础设施
  • ✅ 需要严格的网络隔离(内外网、ToB/ToC)
  • ✅ 对容器化要求不高
  • ✅ 需要精细控制每个网关实例

选择K8S部署:

  • ✅ 容器化环境,已有K8s集群
  • ✅ 需要自动化运维和弹性扩缩容
  • ✅ 服务间调用频繁,希望减少网关负担
  • ✅ 利用K8s原生能力(Service、NetworkPolicy等)

3. 过滤器架构​

五层架构​

过滤器清单​

顺序过滤器功能层级
-1000I18nFilter国际化处理基础设施
-900EccCryptoFilterECC+AES-GCM加密基础设施
-800SecurityFilterIP限流、黑名单安全防护
-700IssueTokensFilterToken签发认证授权
0AuthenticationFilterJWT认证(基准点)认证授权
100SsoFilter单点登录认证授权
200DuplicateSubmitFilter防重复提交业务逻辑
300TenantFilter租户隔离业务逻辑
400InterfaceAuthFilter接口权限业务逻辑
MAXCanaryLoadBalancerFilter灰度负载均衡路由转发

4. 核心功能​

ECC加密通信​

技术原理​

ECC(椭圆曲线加密)+ AES-GCM(对称加密)混合加密方案

为什么使用混合加密?

  • ECC: 安全但慢,用于密钥交换
  • AES-GCM: 快速且安全,用于数据加密
  • 结合: 用ECC交换密钥,用AES-GCM加密数据

ECC+AES-GCM vs 简单HTTPS 对比​

对比维度ECC+AES-GCM混合加密简单HTTPS加密说明
🔐 加密方式
传输层加密❌ 无(应用层加密)✅ TLS/SSLHTTPS依赖TLS协议
应用层加密✅ ECC密钥交换 + AES-GCM❌ 无双重加密,更安全
端到端加密✅ 客户端↔网关↔后端(可选)❌ 仅客户端↔网关ECC可以延伸到后端
🛡️ 安全性
机密性✅ AES-256✅ TLS 1.2+ (AES-128/256)加密强度相当
完整性保护✅ AES-GCM Tag认证✅ TLS MAC都有完整性校验
前向安全性✅ KeyPair定期更新(24小时)⚠️ 依赖TLS版本ECC可以主动轮换密钥
密钥泄露风险✅ 每会话独立密钥⚠️ 长期证书密钥ECC会话密钥更安全
中间人攻击防护✅ ECC密钥交换验证✅ 证书链验证防护机制不同
⚡ 性能
加密/解密开销⚠️ 应用层处理(10-50ms)✅ TLS硬件加速(<5ms)HTTPS有硬件加速优势
首次握手延迟⚠️ 密钥交换(100-200ms)✅ TLS握手(50-100ms)HTTPS握手稍快
数据传输性能✅ AES-GCM高效✅ TLS加密高效性能相当
CPU占用⚠️ 较高(ECC计算)✅ 较低(硬件加速)HTTPS更省CPU
🔧 部署与运维
证书管理✅ 无需CA证书❌ 需要CA证书/Let's EncryptECC无需证书管理
证书过期问题✅ 无❌ 需要定期续期ECC避免证书过期
证书成本✅ 零成本⚠️ 企业证书需付费ECC无证书成本
配置复杂度⚠️ 需要客户端集成✅ 服务器配置即可HTTPS配置更简单
客户端适配⚠️ 需要集成客户端库✅ 浏览器/HTTP客户端原生支持HTTPS兼容性更好
🎯 适用场景
公开网站❌ 不适用✅ 首选HTTPS更适合
移动App✅ 完美适用✅ 也适用两者都可用
内部系统✅ 更灵活✅ 也适用ECC更灵活
高安全要求✅ 端到端加密⚠️ 仅传输加密ECC安全性更高
金融支付✅ 推荐✅ 也适用ECC更适合敏感数据
🔑 密钥管理
密钥生成✅ 客户端和服务端各自生成❌ 仅服务端证书ECC密钥对独立生成
密钥轮换✅ 可动态轮换(24小时)⚠️ 证书过期才轮换ECC轮换更灵活
密钥存储✅ 内存中,不持久化❌ 证书文件存储ECC密钥更安全
多租户密钥✅ 可支持多KeyPair⚠️ 需要多证书ECC更灵活
🌍 兼容性
浏览器支持✅ Web Crypto API✅ 原生TLS都支持
移动端支持✅ 需要集成库✅ 原生支持HTTPS兼容性更好
后端服务✅ 可选加密✅ 必须HTTPSECC可选
旧系统兼容⚠️ 需要升级客户端✅ 广泛兼容HTTPS兼容性更好
💰 成本
证书费用✅ 免费⚠️ 企业证书需付费ECC无证书成本
开发成本⚠️ 需要客户端开发✅ 几乎无需开发HTTPS开发成本低
运维成本✅ 无需证书管理⚠️ 需要证书管理ECC运维更简单
📊 可控制性
加密粒度✅ 按接口/路径配置❌ 全站加密ECC可精细控制
加密算法选择✅ 完全可控⚠️ 依赖TLS版本ECC算法可控
性能调优✅ 可优化加密路径⚠️ 依赖TLS配置ECC更可控
日志与审计✅ 可记录加密信息⚠️ TLS层不可见ECC可审计性更好

选择建议​

使用 ECC+AES-GCM 的场景:

  • ✅ 高安全要求的业务系统(金融、支付、医疗)
  • ✅ 需要端到端加密的场景
  • ✅ 希望避免证书管理的复杂性
  • ✅ 需要精细控制加密粒度(按接口/路径)
  • ✅ 移动App内部通信
  • ✅ 多租户系统(不同租户使用不同密钥)

使用 简单HTTPS 的场景:

  • ✅ 公开网站和Web应用
  • ✅ 标准HTTP API服务
  • ✅ 需要快速部署和零客户端开发
  • ✅ 浏览器访问为主要场景
  • ✅ 需要兼容性优先的场景

最佳实践:混合使用

  • 🌐 公开接口:使用HTTPS(零配置,兼容性好)
  • 🔐 敏感接口:使用ECC+AES-GCM(高安全性,端到端加密)
  • 📱 移动App:优先使用ECC+AES-GCM(无需证书管理,更灵活)

密钥交换原理(ECDH)​

核心特点:

  • 🔐 双方各自生成密钥对,私钥永不传输
  • 🤝 交换公钥后,通过ECDH算法计算出相同的共享密钥
  • ⚡ 共享密钥仅用于本次会话,网关KeyPair会定期更新

完整加密流程​

AES-GCM加密详解​

安全特性:

  • 🔒 机密性: AES-256加密,无法破解
  • ✅ 完整性: Tag认证标签,防篡改
  • 🔄 前向安全: KeyPair定期更新,旧密钥失效
  • 🚀 高性能: AES-GCM有硬件加速

配置​

platform:
gateway:
ecc-crypto:
enabled: true # 启用ECC加密
key-pair-ttl: 86400000 # KeyPair有效期24小时
include-paths:
- "/api/auth/**" # 认证接口加密
- "/api/payment/**" # 支付接口加密
exclude-paths:
- "/api/public/**" # 公开接口不加密

客户端集成​

参见:


防重复提交​

技术原理​

双重防护机制: 客户端防护(本地队列)+ 服务端防护(Redis缓存)

核心思想:

  • 为每个请求生成唯一标识(requestId)
  • 在时间窗口内,相同requestId的请求只允许一次
  • 超过时间窗口后,自动清理记录

请求标识生成算法​

生成公式:

requestId = MD5(
URL路径 +
HTTP方法 +
⌊当前时间 / 时间窗口⌋ + // 时间分片,同一窗口内相同
IP地址(可选) +
用户ID(可选) +
MD5(请求体)(可选)
)

示例:

URL: /api/order/submit
方法: POST
时间窗口: 3000ms
当前时间: 1730419200000
用户ID: user123
IP: 192.168.1.100
请求体: {"orderId":"12345","amount":100}

requestId = MD5(
"/api/order/submit" +
"POST" +
"576806400" + // ⌊1730419200000 / 3000⌋
"192.168.1.100" +
"user123" +
"a1b2c3d4e5f6" // MD5(请求体)
) = "7f8a9b1c2d3e4f5a"

双重防护流程​

多维度防护​

维度说明配置项适用场景
路径指定哪些API需要检查include-paths
exclude-paths
所有场景
方法只检查写操作自动识别所有场景
时间窗口同一窗口内去重time-window: 3000所有场景
用户同一用户时间窗口内不能重复enable-user-level: true登录后操作
IP同一IP时间窗口内不能重复enable-ip-level: true防恶意攻击
请求体相同请求体哈希去重enable-body-hash: true防重复数据

时间窗口机制​

说明:

  • ⏰ 时间窗口: 3秒内同一requestId只允许一次
  • 🔄 自动清理: 缓存过期时间通常是时间窗口的2-3倍
  • ✅ 窗口后: 时间窗口过后,自动允许新请求

缓存策略​

Redis缓存键结构:

platform:gateway:duplicate-submit:{requestId}

值: 固定为"1"
过期时间: 10秒(时间窗口的3倍)

为什么过期时间要大于时间窗口?

原因:

  • ⏱️ 防止边界条件下的重复提交
  • 🔄 给Redis一些清理缓冲时间
  • 🛡️ 增加额外的安全边界

配置​

platform:
gateway:
duplicate-submit:
enabled: true # 启用
time-window: 3000 # 时间窗口3秒
cache-expire: 10000 # 缓存10秒
enable-user-level: true # 用户级别检查
enable-ip-level: true # IP级别检查
enable-body-hash: true # 请求体哈希
include-paths: ["/api/**"]
exclude-paths:
- "/api/health/**"
- "/api/auth/login" # 登录允许重试
error-code: "DUPLICATE_SUBMIT"
error-message: "请求过于频繁,请稍后再试"

双重防护​

客户端检查 (本地队列) → 服务端检查 (Redis缓存)
↓ ↓
立即拒绝 HTTP 429

认证授权​

JWT令牌​

生命周期:

配置:

platform:
gateway:
token:
expire-time: 2 # 有效期2小时
expiration-renewal-time: 10 # 到期前10分钟续期
secret: "your-jwt-secret-key" # JWT密钥
blacklist-path: "platform:gateway:token:"
login-uri-list:
- /api/auth/login # 登录接口
ignore-uri-list:
- /api/public/** # 忽略公开接口

SSO单点登录​

功能: 同一账号只能在一处登录,新登录会踢掉旧会话

配置:

platform:
gateway:
sso:
enable: true
sso-login-url: "http://localhost:8080/sso/login"
online-token-path: "platform:gateway:online-token:"

安全防护​

IP限流策略​

规则说明
banned_ip封禁IP地址
custom_http_status返回自定义错误
redirect重定向到错误页面

配置示例​

platform:
gateway:
security:
enable: true
rule: banned_ip # 封禁策略
security-threshold: 60 # 60次/分钟
security-time-interval-value: 1
security-time-interval-unit: minutes
banned:
permanent: false # 非永久封禁
security-block-time: 5 # 封禁5分钟
security-block-time-unit: minutes

灰度发布​

三种维度​

维度说明使用场景
VERSION基于版本号服务端控制
ID基于特征ID(用户ID、门店ID等)指定用户测试
CUSTOM客户端动态指定灵活控制

配置​

platform:
gateway:
deploy:
enable: true
canary-category: VERSION # 或 ID, CUSTOM
id-list: # ID模式时使用
- 111
- 222

Sentinel熔断器​

核心优势​

  • ✅ 托管Netty连接池 - 防止熔断失效
  • ✅ 统一保护 - 内外网请求统一经过Sentinel
  • ✅ 动态规则 - 规则通过Nacos动态下发
  • ✅ 多维度保护 - 流控、熔断、降级、热点参数、系统保护

配置​

spring:
cloud:
sentinel:
transport:
dashboard: 10.100.0.90:8899
datasource:
flow:
nacos:
server-addr: 10.100.0.112:8848
data-id: gateway-flow-rules.json
rule-type: flow
degrade:
nacos:
server-addr: 10.100.0.112:8848
data-id: gateway-degrade-rules.json
rule-type: degrade

5. 配置指南​

最小化配置​

application.yml (本地配置)​

server:
port: 8080

spring:
application:
name: rydeen-gateway-service
cloud:
nacos:
discovery:
server-addr: 10.100.0.51:8848
namespace: production
config:
server-addr: 10.100.0.51:8848
namespace: production
name: gateway-service.yaml
group: global
file-extension: yaml

logging:
config: ./logback-spring.xml

gateway-service.yaml (Nacos配置中心)​

# Redis配置
spring:
data:
redis:
host: 10.100.0.87
port: 6379
password: your-password
database: 0
lettuce:
pool:
max-active: 100
max-idle: 10
min-idle: 5

# 路由配置
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/user/**
filters:
- StripPrefix=1

# Sentinel熔断器
sentinel:
transport:
dashboard: 10.100.0.90:8899
datasource:
flow:
nacos:
server-addr: 10.100.0.112:8848
data-id: gateway-flow-rules.json

# 网关功能配置
platform:
gateway:
# ECC加密
ecc-crypto:
enabled: true

# 防重复提交
duplicate-submit:
enabled: true
time-window: 3000

# JWT认证
token:
expire-time: 2
secret: your-jwt-secret

# 安全防护
security:
enable: true
rule: banned_ip
security-threshold: 60

核心配置对照表​

功能配置路径默认值说明
ECC加密platform.gateway.ecc-crypto.enabledfalse是否启用
防重复提交platform.gateway.duplicate-submit.enabledfalse是否启用
时间窗口platform.gateway.duplicate-submit.time-window3000毫秒
JWT有效期platform.gateway.token.expire-time2小时
Token续期platform.gateway.token.expiration-renewal-time10分钟
IP限流platform.gateway.security.security-threshold120次/分钟
SSOplatform.gateway.sso.enablefalse是否启用
多租户platform.gateway.tenant.enablefalse是否启用
灰度发布platform.gateway.deploy.enablefalse是否启用

6. 客户端集成​

客户端库概览​

位置: src/main/resources/client-library/

网关提供多语言客户端库,支持 ECC+AES-GCM 加密和防重复提交功能。所有客户端采用统一的接口设计,业务代码自行定义 URL 枚举。

支持的语言/平台​

语言/平台状态适用场景运行时依赖
TypeScript (Web)✅ 生产可用Web 应用、React、Angular、Vue零依赖(浏览器原生API)
Node.js✅ 生产可用Node.js 服务器端应用零依赖(Node.js 18+内置模块)
Go✅ 生产可用后端服务、CLI 工具、微服务零依赖(Go标准库)
Swift✅ 生产可用iOS、macOS 原生应用零依赖(Swift标准库)
Kotlin✅ 生产可用Android 原生应用零依赖(Android标准库)
Rust✅ 生产可用高性能场景、嵌入式需安装依赖(见rust/Cargo.toml)
C++✅ 生产可用Windows/Linux 桌面应用需OpenSSL库

图例:

  • ✅ 生产可用:完整实现,包含完整文档和示例
  • 🚧 框架代码:核心代码已实现,需要完善
  • 📋 计划中:未开始实现

架构设计:接口分离​

所有客户端都采用接口分离的设计:

  • 库代码:定义 URL 接口(Protocol/Trait/Interface)
  • 业务代码:定义自己的 URL 枚举,实现接口

这样设计的好处:

  • ✅ 库代码更简洁,只关注 HTTP 客户端功能
  • ✅ 业务代码完全控制 URL 定义
  • ✅ 符合各语言的最佳实践

功能对比表​

功能TypeScript (Web)Node.jsGoSwiftKotlinRustC++
核心功能
HTTP 客户端✅✅✅✅✅✅✅
URL 接口分离✅✅✅✅✅✅✅
防重复提交✅✅✅✅✅✅✅
加密功能
ECC 密钥交换✅✅✅✅✅🚧✅
AES-GCM 加密✅✅✅✅✅🚧✅
自动重新握手✅✅✅✅✅🚧✅
文档和示例
详细文档✅✅✅✅✅✅✅
完整示例✅✅✅✅✅✅✅
框架集成示例✅✅✅✅✅✅📋

TypeScript/Web 客户端(推荐)​

最完整的实现,支持三大框架:React 18+、Angular 17+、Vue 3

快速开始​

步骤1: 定义URL配置

import { Url, Method } from './framework/url';

export class AppUrl {
// 公开数据:不加密,不防重复
public static readonly MENU_ALL = new Url(
'MENU_ALL', '/api/menu/all', Method.GET
);

// 登录:加密,不防重复(允许快速重试)
public static readonly USER_LOGIN = new Url(
'USER_LOGIN', '/api/auth/login', Method.POST,
true, // ✅ 加密
false // ❌ 不防重复
);

// 支付:加密,防重复(最高安全)
public static readonly PAYMENT_CREATE = new Url(
'PAYMENT_CREATE', '/api/payment/create', Method.POST,
true, // ✅ 加密
true // ✅ 防重复提交
);
}

步骤2: 创建HTTP客户端

import { HttpClient } from './framework/http-client';

const client = new HttpClient({
baseUrl: 'https://your-gateway.com',
clientId: 'my-app',
duplicateSubmitTimeWindow: 3000
});

步骤3: 发送请求

// 自动根据URL配置处理加密和防重复提交
const result = await client.request(AppUrl.PAYMENT_CREATE, {
body: { amount: 100, currency: 'CNY' }
});

框架集成​

React 18+:

import { useHttpClient } from './hooks/useHttpClient';
import { AppUrl } from './app.url';

function MyComponent() {
const client = useHttpClient();

const handleSubmit = async () => {
await client.request(AppUrl.ORDER_SUBMIT, { body: orderData });
};
}

Angular 17+:

import { Component, inject } from '@angular/core';
import { HttpClientService } from './services/http-client.service';
import { AppUrl } from './app.url';

@Component({ standalone: true })
export class MyComponent {
private httpClient = inject(HttpClientService);

async handleSubmit() {
await this.httpClient.request(AppUrl.ORDER_SUBMIT, { body: orderData });
}
}

Vue 3:

<script setup lang="ts">
import { useHttpClient } from './composables/useHttpClient';
import { AppUrl } from './app.url';

const client = useHttpClient();

const handleSubmit = async () => {
await client.request(AppUrl.ORDER_SUBMIT, { body: orderData });
};
</script>

依赖说明​

运行时依赖: ✅ 零外部依赖

  • 使用浏览器原生API:window.crypto.subtle(Web Crypto API)、fetch(Fetch API)
  • 浏览器要求:Chrome 37+, Firefox 34+, Safari 11+, Edge 79+

开发依赖(可选):

  • TypeScript: typescript@^5.0.0
  • React: react@^18.0.0 react-dom@^18.0.0
  • Angular: @angular/core@^17.0.0 @angular/common@^17.0.0
  • Vue: vue@^3.0.0

Node.js 客户端​

服务器端应用,零外部运行时依赖(Node.js 18+)

快速开始​

import { HttpClient } from './framework/http-client';
import { AppUrl } from './app.url';

// 创建客户端
const client = new HttpClient({
baseUrl: 'https://your-gateway.com',
clientId: 'my-nodejs-client',
userId: 'user123',
authToken: 'your-token'
});

// 发送请求
const result = await client.request(AppUrl.USER_LOGIN, {
body: { username: 'user', password: 'pass' }
});

依赖说明​

运行时依赖: ✅ 零外部依赖(Node.js 18.0.0+)

  • 使用Node.js内置模块:crypto、fetch(Node.js 18+内置)

开发依赖(可选):

npm install --save-dev typescript@^5.0.0
npm install --save-dev @types/node@^20.0.0
npm install --save-dev ts-node@^10.9.0

Go 客户端​

性能优秀,单文件部署,零外部依赖

快速开始​

// 定义URL
type Url int

const (
UserLogin Url = iota
OrderSubmit
)

func (u Url) Path() string {
switch u {
case UserLogin: return "/api/auth/login"
case OrderSubmit: return "/api/order/submit"
}
}

func (u Url) Method() Method { return POST }
func (u Url) NeedEncryption() bool { return true }
func (u Url) NeedDuplicateCheck() bool { return false }

// 使用客户端
client := NewHttpClient(HttpClientConfig{
BaseUrl: "https://your-gateway.com",
})
result, err := client.Request(UserLogin, &RequestOptions{
Body: map[string]string{"username": "user", "password": "pass"},
})

依赖说明​

运行时依赖: ✅ 零外部依赖

  • 使用Go标准库:crypto/ecdh、crypto/aes、net/http等
  • 要求:Go 1.18+(推荐1.20+)

Swift/Kotlin 客户端(移动端)​

Swift(iOS/macOS)和Kotlin(Android)客户端,使用系统原生加密库。

Swift 示例​

enum Url: UrlProtocol {
case userLogin
case orderSubmit

var path: String {
switch self {
case .userLogin: return "/api/auth/login"
case .orderSubmit: return "/api/order/submit"
}
}

var method: Method { .post }
var needEncryption: Bool { true }
var needDuplicateCheck: Bool { false }
}

// 使用
let client = HttpClient(config: HttpClientConfig(
baseUrl: "https://your-gateway.com"
))
let result = try await client.request(Url.userLogin,
body: ["username": "user", "password": "pass"])

Kotlin 示例​

enum class Url : UrlInterface {
UserLogin {
override val path = "/api/auth/login"
override val method = Method.POST
override val needEncryption = true
override val needDuplicateCheck = false
}
}

// 使用
val client = HttpClient(HttpClientConfig(
baseUrl = "https://your-gateway.com"
))
val result = client.request(Url.UserLogin,
body = mapOf("username" to "user", "password" to "pass"))

四种配置组合​

加密防重复适用场景示例
❌❌公开只读数据菜单、字典
✅❌敏感数据,可重试登录、查询
❌✅普通操作,防重复文件上传
✅✅高安全操作支付、订单

请求头自动管理(自动头拷贝)​

客户端支持请求头的自动读取和持久化功能,实现业务无侵入的请求头管理。服务器返回的业务请求头会自动保存,并在后续请求中自动添加,无需手动处理。

功能特性​

  • ✅ 自动读取: 发送请求前,自动从存储读取缓存的请求头并添加到请求headers中
  • ✅ 自动保存: 响应返回后,自动将业务相关的响应头保存到存储
  • ✅ 智能过滤: 自动排除浏览器和系统内置的请求头,只保存业务相关的header
  • ✅ 零侵入: 完全自动化,无需在业务代码中手动处理

工作原理​

发送请求前:

  1. 自动从存储读取缓存的请求头(Web版本:localStorage,键名:http_headers)
  2. 将缓存的请求头合并到请求headers中
  3. 用户通过options.headers自定义的请求头优先级最高(会覆盖缓存的请求头)

响应返回后:

  1. 遍历响应头,识别业务相关的header
  2. 排除系统内置header(如content-type、cache-control、x-client-*等)
  3. 将业务请求头自动保存到存储

配置选项​

const client = new HttpClient({
baseUrl: 'https://your-gateway.com',
// 启用请求头自动管理(默认:true)
enableHeaderAutoManagement: true,
// localStorage中存储请求头的键名(默认:'http_headers')
headerStorageKey: 'http_headers'
});

使用示例​

自动功能(默认启用):

// 第一次请求:响应返回的header会被自动保存
const result1 = await client.request(AppUrl.USER_LOGIN, {
body: { username: 'user', password: 'pass' }
});
// 如果服务器返回了 X-Access-Token,会被自动保存到localStorage

// 第二次请求:之前保存的header会自动添加到请求中
const result2 = await client.request(AppUrl.USER_PROFILE);
// X-Access-Token 会自动添加到请求headers中,无需手动传递

手动管理请求头:

// 手动设置请求头到缓存
client.setCachedHeaders({
'X-Custom-Token': 'token123',
'X-Language': 'zh-CN',
'X-Timezone': 'Asia/Shanghai'
});

// 查看当前缓存的请求头
const cachedHeaders = client.getCachedHeaders();

// 移除指定的缓存请求头
client.removeCachedHeader('X-Custom-Token');

// 清除所有缓存的请求头
client.clearCachedHeaders();

系统内置请求头(自动过滤)​

以下请求头不会被保存(系统会自动过滤):

  • HTTP标准header: content-type, content-length, cache-control, expires, date, server, connection, transfer-encoding
  • 浏览器header: accept, accept-encoding, accept-language, referer, user-agent, origin
  • 客户端系统header: x-client-id, x-client-timestamp, x-client-public-key, x-gateway-keyid, x-encrypted-data
  • CORS header: access-control-*

业务请求头示例​

以下类型的请求头会被自动保存和使用:

// 这些header会被自动保存和管理
{
'X-Access-Token': 'eyJhbGciOiJIUzI1NiIs...',
'X-Refresh-Token': 'refresh_token_here',
'X-Custom-Token': 'custom_token',
'X-Language': 'zh-CN',
'X-Timezone': 'Asia/Shanghai',
'X-Device-Id': 'device123',
'X-User-Role': 'admin',
'Authorization': 'Bearer token123' // 如果服务器返回,也会被保存
}

存储方式​

  • Web版本: 使用 localStorage(持久化,跨会话保存)
  • Node.js版本: 使用内存存储(实例级别,进程内有效)

注意事项​

  1. 优先级: options.headers > 缓存的请求头 > 系统默认请求头
  2. 存储位置: Web版本默认使用localStorage,键名为http_headers
  3. 安全性: 敏感信息(如token)会保存在localStorage,请确保应用安全(XSS防护)
  4. 浏览器兼容性: 需要支持localStorage的现代浏览器
  5. Node.js版本: 使用内存存储,多实例之间不会共享缓存

核心功能​

ECC+AES-GCM 加密​

  • 🔐 ECC密钥交换(ECDH):使用P-256曲线,生成256位共享密钥
  • 🔐 AES-GCM加密:256位密钥,12字节IV,128位Tag验证
  • 🔄 自动重新握手:KeyPair过期时自动重新交换密钥

防重复提交​

  • 🛡️ 双重防护:客户端本地队列 + 服务器Redis缓存
  • ⏰ 时间窗口:可配置的时间窗口内阻止重复请求
  • 🔍 多维度检查:支持用户级别、IP级别、请求体哈希

错误处理​

所有客户端都支持两种错误:

错误说明处理建议
DUPLICATE_REQUEST客户端检测到重复提示用户请求正在处理中
DUPLICATE_SUBMIT服务器检测到重复(HTTP 429)提示用户请求过于频繁

更多资源​


7. JVM优化配置​

JDK21 分代ZGC配置(4C8G POD)​

完整配置示例:

# JDK21 分代ZGC优化配置(适用于4C8G起步的POD)
java -Xms3g -Xmx6g \
-XX:+UseZGC \
-XX:+ZGenerational \
-XX:+UnlockExperimentalVMOptions \
-XX:+UseStringDeduplication \
-XX:MaxMetaspaceSize=512m \
-XX:MaxDirectMemorySize=1g \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/app/logs/gateway/heapdump.hprof \
-XX:+PrintGCDetails \
-XX:+PrintGCDateStamps \
-Xlog:gc*:file=/app/logs/gateway/gc.log:time:filecount=5,filesize=100M \
-XX:+UseGCLogFileRotation \
-XX:NumberOfGCLogFiles=5 \
-XX:GCLogFileSize=100M \
-Djava.security.egd=file:/dev/./urandom \
-Dfile.encoding=UTF-8 \
-Duser.timezone=Asia/Shanghai \
-jar rydeen-gateway-service.jar

配置项详细说明:

配置项配置值配置原因说明
-Xms3g -Xmx6g3GB-6GB堆内存配置预留2GB给系统和其他进程,避免OOM
-XX:+UseZGC启用ZGC低延迟垃圾收集器ZGC暂停时间<1ms,适合网关高并发场景
-XX:+ZGenerational启用分代ZGC提升吞吐量和内存回收效率JDK21默认未开启分代ZGC,需手动加此参数
-XX:+UnlockExperimentalVMOptions启用实验性选项支持ZGC等实验性功能JDK21中ZGC仍需要此参数
-XX:+UseStringDeduplication启用字符串去重减少内存占用网关处理大量HTTP请求,字符串去重可节省内存
-XX:MaxMetaspaceSize=512m512MB元空间大小限制防止元空间无限增长,影响系统稳定性
-XX:MaxDirectMemorySize=1g1GB直接内存限制限制NIO缓冲区使用,防止内存泄漏
-XX:+HeapDumpOnOutOfMemoryError启用堆转储故障诊断OOM时自动生成堆转储文件,便于问题分析
-XX:HeapDumpPath=/app/logs/gateway/heapdump.hprof堆转储路径文件存储位置指定堆转储文件保存路径
-XX:+PrintGCDetails启用详细GC日志性能监控记录详细的GC信息,便于性能调优
-XX:+PrintGCDateStamps启用GC时间戳时间追踪在GC日志中添加时间戳,便于问题定位
-Xloggc:/app/logs/gateway/gc.logGC日志路径日志存储指定GC日志文件保存路径
-XX:+UseGCLogFileRotation启用日志轮转磁盘空间管理防止GC日志文件过大,自动轮转
-XX:NumberOfGCLogFiles=55个日志文件历史保留保留最近5个GC日志文件
-XX:GCLogFileSize=100M100MB单个文件大小单个GC日志文件最大100MB
-Djava.security.egd=file:/dev/./urandom随机数生成器启动性能使用/dev/urandom加速启动,避免阻塞
-Dfile.encoding=UTF-8UTF-8编码字符编码确保日志和消息的正确编码
-Duser.timezone=Asia/Shanghai上海时区时间处理设置系统时区,确保日志时间正确

ZGC垃圾收集器优势​

ZGC特性:

  1. 极低延迟:ZGC的暂停时间通常小于1毫秒,非常适合网关这种对延迟敏感的服务
  2. 可扩展性:ZGC的暂停时间不会随着堆大小增加而增加,适合大内存场景
  3. 并发处理:ZGC的大部分工作都是并发进行的,不会阻塞应用线程
  4. 内存效率:ZGC的内存使用效率高,碎片化程度低

内存分配策略:

  • 堆内存:设置为总内存的75%,为系统和其他进程预留25%
  • 直接内存:设置为总内存的12.5%,用于NIO缓冲区
  • 元空间:设置为总内存的6.25%,用于类元数据
  • 系统预留:预留6.25%给操作系统和其他进程

性能监控建议​

GC监控指标:

  • GC频率:监控GC发生的频率
  • GC暂停时间:监控每次GC的暂停时间
  • 内存使用率:监控堆内存和直接内存的使用情况

关键性能指标:

  • 响应时间:监控API响应时间
  • 吞吐量:监控每秒处理的请求数
  • 错误率:监控请求错误率

告警设置:

  • GC暂停时间>10ms时告警
  • 内存使用率>80%时告警
  • 响应时间>1s时告警

调优建议:

  1. 根据实际负载调整堆内存大小:监控内存使用情况,适当调整堆内存大小,避免设置过大的堆内存影响GC效率
  2. 监控GC日志:定期分析GC日志,发现性能问题,根据GC情况调整相关参数
  3. 系统资源监控:监控CPU使用率,避免CPU成为瓶颈;监控网络IO,确保网络性能满足需求

K8s环境下POD资源与JVM配置建议​

在Kubernetes(K8s)环境下,建议采用"小而多"的POD部署策略,合理分配单POD资源,通过副本数横向扩展提升整体吞吐和高可用性。

资源分配原则:

  • 单POD内存不宜过大,建议不超过4G,CPU不超过2-4核
  • JVM堆内存建议为POD内存的50%-70%,其余留给直接内存、元空间和系统
  • 优先通过增加POD副本数(横向扩展)提升能力,而非单POD堆内存无限增大
  • 生产环境建议POD副本数≥3,保证高可用和弹性伸缩

推荐配置表:

业务规模POD副本数CPU内存JVM堆建议适用场景
开发/测试1-20.5-1核1-2G512m-1g低并发/功能验证
小型生产2-31-2核2-3G1g-1.5g日活<5万
中型生产3-52核2-4G1.5g-2g日活5-20万
大型生产5-82-4核3-6G2g-3g日活20-100万

说明:JVM参数建议 -Xms=-Xmx=,其余内存分配给直接内存、元空间和系统。

横向扩展优势:

  • 高可用:单POD故障影响面小,K8s可自动重建副本
  • 弹性伸缩:可根据流量自动扩缩容,资源利用率高
  • 故障隔离:单POD崩溃不会拖垮整体服务,提升系统健壮性
  • 升级平滑:支持滚动升级,零停机

K8s资源配置YAML示例:

resources:
requests:
memory: "2Gi"
cpu: "1"
limits:
memory: "3Gi"
cpu: "2"

JVM参数建议:-Xms1g -Xmx1.5g -XX:MaxDirectMemorySize=512m ...

K8s下的最佳实践建议:

  1. 优先横向扩展副本数,单POD内存不宜超过4G
  2. 监控POD内存和GC日志,发现频繁Full GC或OOM时,优先增加副本数而非单POD资源
  3. 合理设置HPA(自动扩缩容),根据CPU/内存/自定义QPS等指标自动扩容
  4. 升级/发布采用滚动方式,避免全量重启
  5. 节点需预留部分资源给系统和其他服务,避免资源争抢

本节内容为K8s环境下POD资源与JVM配置专用建议,适用于Spring Cloud Gateway等微服务网关在Kubernetes平台的生产部署。


8. 附录​

快速命令​

健康检查​

curl http://localhost:8080/actuator/health

测试登录​

curl -X POST http://localhost:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"test","password":"test"}'

带Token请求​

curl -X GET http://localhost:8080/api/user/profile \
-H "x-rd-request-apitoken: YOUR_TOKEN"

常见问题​

问题原因解决方案
启动失败配置错误、端口占用检查配置语法、检查端口
Nacos连接失败地址错误、网络问题检查server-addr配置
Token验证失败密钥不匹配、Token过期检查secret配置
重复提交误拦截时间窗口过长调整time-window
加密失败KeyPair过期客户端会自动重新握手

监控指标​

关键指标​

指标监控项告警阈值
响应时间P95响应时间>1s
错误率5xx错误率>1%
吞吐量QPS根据容量规划
内存堆内存使用率>80%
GCGC暂停时间>10ms

Prometheus配置​

management:
endpoints:
web:
exposure:
include: health,metrics,prometheus
metrics:
export:
prometheus:
enabled: true

更新日志​

版本日期更新内容
4.6.02026-04新增客户端库(React/Angular/Vue),优化ECC加密和防重复提交
4.5.02025-01采用Sentinel替代Resilience4j,优化熔断器架构
4.3.02024-07新增SSO功能,完善国际化
4.2.02024-05新增多租户支持

📚 相关资源​


说明:

  • 本文档保留所有核心功能和配置,以简洁的表格和图表呈现
  • 详细的使用示例请参考各章节
  • 客户端集成请查看 client-library 目录