正在加载,请稍候…

API 网关模式:限流、边缘认证与请求聚合

设计和实现 API 网关模式,包括令牌桶限流、JWT 验证、请求聚合、服务发现及 Kong 配置,让服务专注于业务逻辑。

API 网关模式:限流、边缘认证与请求聚合

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
}

API 网关模式:限流、边缘认证与请求聚合 示意图

边缘 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)
    })
}

API 网关模式:限流、边缘认证与请求聚合 示意图

请求聚合(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
    }
}

API 网关模式:限流、边缘认证与请求聚合 示意图

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。