
API 网关处理认证、限流、路由和可观测性,让服务专注于业务逻辑。
令牌桶限流(Redis + Lua)
func (l *TokenBucketLimiter) Allow(ctx context.Context, key string) (bool, error) {
script := redis.NewScript(`
local capacity = tonumber(ARGV[1])
local refill_rate = tonumber(ARGV[2])
local now = tonumber(ARGV[3])
local bucket = redis.call('HMGET', KEYS[1], 'tokens', 'last_refill')
local tokens = tonumber(bucket[1]) or capacity
local last_refill = tonumber(bucket[2]) or now
local new_tokens = math.min(capacity, tokens + (now - last_refill) * refill_rate)
if new_tokens >= 1 then
redis.call('HMSET', KEYS[1], 'tokens', new_tokens - 1, 'last_refill', now)
redis.call('EXPIRE', KEYS[1], 3600)
return 1
end
return 0
`)
result, err := script.Run(ctx, l.client, []string{key},
l.capacity, l.refillRate, time.Now().Unix()).Int()
return result == 1, err
}

边缘 JWT 验证
func AuthMiddleware(validator *JWTValidator, next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
auth := r.Header.Get("Authorization")
if !strings.HasPrefix(auth, "Bearer ") {
http.Error(w, "Unauthorized", 401)
return
}
claims, err := validator.Validate(auth[7:])
if err != nil {
http.Error(w, "Unauthorized", 401)
return
}
r.Header.Set("X-User-ID", claims.Subject)
r.Header.Set("X-User-Roles", strings.Join(claims.Roles, ","))
next.ServeHTTP(w, r)
})
}

请求聚合(BFF 模式)
func (gw *Gateway) GetDashboard(ctx context.Context, userID string) (*Dashboard, error) {
type result[T any] struct{ data T; err error }
userCh := make(chan result[*UserProfile], 1)
ordersCh := make(chan result[[]Order], 1)
metricsCh := make(chan result[*Metrics], 1)
go func() { d, e := gw.userSvc.GetProfile(ctx, userID); userCh <- result[*UserProfile]{d, e} }()
go func() { d, e := gw.orderSvc.GetRecent(ctx, userID, 10); ordersCh <- result[[]Order]{d, e} }()
go func() { d, e := gw.metricsSvc.Get(ctx, userID); metricsCh <- result[*Metrics]{d, e} }()
if u := <-userCh; u.err != nil {
return nil, u.err
} else {
return &Dashboard{User: u.data, Orders: (<-ordersCh).data, Metrics: (<-metricsCh).data}, nil
}
}

Kong 配置
services:
- name: order-service
url: http://order-service.production.svc:8080
plugins:
- name: rate-limiting
config:
minute: 100
policy: redis
redis_host: redis.production.svc
- name: jwt
config:
claims_to_verify: [exp]
routes:
- name: orders
paths: [/api/v1/orders]
methods: [GET, POST]
在边缘正确处理认证和限流,让每个服务无需重复实现相同逻辑。
→ 使用 URL 解析器 工具验证 API URL。