API网关(API Gateway)是微服务架构中的统一入口,作为客户端和微服务之间的中间层,提供路由、认证、鉴权、限流、监控等功能,屏蔽内部服务细节,简化客户端调用。
API网关概述 什么是API网关? API网关是微服务架构中的统一入口点,所有客户端请求都通过API网关路由到后端服务。它充当了客户端和后端服务之间的反向代理,提供横切关注点的统一处理。
graph TB
A[客户端] --> B[API网关]
B --> C[服务1]
B --> D[服务2]
B --> E[服务3]
B --> F[服务N]
B --> B1[路由]
B --> B2[认证鉴权]
B --> B3[限流熔断]
B --> B4[监控日志]
style B fill:#FFE66D
核心作用:
单点入口 :所有请求统一入口
屏蔽内部细节 :客户端无需知道后端服务细节
横切关注点 :统一处理认证、限流、监控等
协议转换 :支持多种协议转换
API网关的价值 graph LR
A[API网关] --> B[简化客户端]
A --> C[统一管理]
A --> D[安全保护]
A --> E[性能优化]
style A fill:#51CF66
价值体现:
简化客户端 :客户端只需知道网关地址
统一管理 :集中管理API策略和配置
安全保护 :统一的安全策略和防护
性能优化 :缓存、负载均衡、限流等
API网关架构 graph TB
A[客户端] --> B[API网关]
B --> C[路由层]
C --> D[中间件层]
D --> E[服务层]
D --> D1[认证中间件]
D --> D2[鉴权中间件]
D --> D3[限流中间件]
D --> D4[日志中间件]
D --> D5[监控中间件]
E --> E1[订单服务]
E --> E2[用户服务]
E --> E3[商品服务]
style B fill:#FFE66D
核心功能 路由 路由是API网关的核心功能,负责将请求转发到正确的后端服务。
路由概述 graph LR
A[请求] --> B[路由匹配]
B --> C[服务选择]
C --> D[请求转发]
style B fill:#51CF66
路由功能:
路径匹配 :根据URL路径匹配路由规则
服务发现 :动态发现后端服务
负载均衡 :在多个服务实例间分发请求
路由重写 :重写请求路径
路由配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 routes: - name: order-service path: /api/orders methods: [GET , POST , PUT , DELETE ] service: order-service strip_path: true - name: user-service path: /api/users methods: [GET , POST ] service: user-service strip_path: true - name: product-service path: /api/products methods: [GET ] service: product-service strip_path: true
重写路由 路由重写允许在转发请求前修改请求路径,实现路径转换。
graph LR
A["/api/v1/orders"] --> B[路由重写]
B --> C["/orders"]
C --> D[后端服务]
style B fill:#FFE66D
重写规则:
1 2 3 4 5 6 7 8 9 10 routes: - name: order-service-v1 path: /api/v1/orders rewrite_path: /orders service: order-service - name: order-service-v2 path: /api/v2/orders rewrite_path: /v2/orders service: order-service-v2
实现示例:
1 2 3 4 5 6 7 8 9 10 11 12 func RewritePathMiddleware (next http.Handler) http.Handler { return http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) { route := getRoute(r.URL.Path) if route != nil && route.RewritePath != "" { r.URL.Path = route.RewritePath } next.ServeHTTP(w, r) }) }
动态路由 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 type Router struct { routes map [string ]*Route discovery ServiceDiscovery } type Route struct { Path string Service string RewritePath string Methods []string } func (r *Router) Match(path string ) (*Route, error ) { if route, ok := r.routes[path]; ok { return route, nil } for pattern, route := range r.routes { if strings.HasPrefix(path, pattern) { return route, nil } } for pattern, route := range r.routes { matched, _ := regexp.MatchString(pattern, path) if matched { return route, nil } } return nil , fmt.Errorf("no route found for path: %s" , path) } func (r *Router) Forward(route *Route, req *http.Request) (*http.Response, error ) { instances, err := r.discovery.GetInstances(route.Service) if err != nil { return nil , err } instance := r.loadBalancer.Select(instances) targetURL := fmt.Sprintf("http://%s:%d%s" , instance.Host, instance.Port, route.RewritePath) return r.httpClient.Do(req, targetURL) }
认证 认证(Authentication)是验证用户身份的过程,确认”你是谁”。
认证概述 graph LR
A[客户端] --> B[提供凭证]
B --> C[API网关验证]
C --> D{验证通过?}
D -->|是| E[允许访问]
D -->|否| F[拒绝访问]
style C fill:#51CF66
style F fill:#FF6B6B
认证方式:
API Key :简单的密钥认证
JWT Token :基于Token的认证
OAuth 2.0 :标准授权协议
Basic Auth :基础认证
API Key认证 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 type APIKeyAuth struct { keys map [string ]string } func (a *APIKeyAuth) Authenticate(req *http.Request) (string , error ) { apiKey := req.Header.Get("X-API-Key" ) if apiKey == "" { return "" , fmt.Errorf("API key required" ) } userID, ok := a.keys[apiKey] if !ok { return "" , fmt.Errorf("invalid API key" ) } return userID, nil } func APIKeyAuthMiddleware (auth *APIKeyAuth) func (http.Handler) http.Handler { return func (next http.Handler) http.Handler { return http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) { userID, err := auth.Authenticate(r) if err != nil { http.Error(w, err.Error(), http.StatusUnauthorized) return } ctx := context.WithValue(r.Context(), "user_id" , userID) next.ServeHTTP(w, r.WithContext(ctx)) }) } }
JWT Token认证 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 import ( "github.com/golang-jwt/jwt/v5" ) type JWTAuth struct { secretKey []byte } func (a *JWTAuth) Authenticate(req *http.Request) (*Claims, error ) { tokenString := req.Header.Get("Authorization" ) if tokenString == "" { return nil , fmt.Errorf("token required" ) } if strings.HasPrefix(tokenString, "Bearer " ) { tokenString = tokenString[7 :] } token, err := jwt.ParseWithClaims(tokenString, &Claims{}, func (token *jwt.Token) (interface {}, error ) { return a.secretKey, nil }) if err != nil { return nil , err } if claims, ok := token.Claims.(*Claims); ok && token.Valid { return claims, nil } return nil , fmt.Errorf("invalid token" ) } type Claims struct { UserID string `json:"user_id"` Role string `json:"role"` jwt.RegisteredClaims } func JWTAuthMiddleware (auth *JWTAuth) func (http.Handler) http.Handler { return func (next http.Handler) http.Handler { return http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) { claims, err := auth.Authenticate(r) if err != nil { http.Error(w, err.Error(), http.StatusUnauthorized) return } ctx := context.WithValue(r.Context(), "claims" , claims) next.ServeHTTP(w, r.WithContext(ctx)) }) } }
OAuth 2.0认证 graph LR
A[客户端] --> B[API网关]
B --> C[OAuth服务器]
C --> D[返回Token]
D --> B
B --> E[验证Token]
E --> F[允许访问]
style C fill:#4DABF7
style E fill:#51CF66
OAuth 2.0认证适用于以下典型使用场景:
第三方应用授权访问资源 当用户希望允许第三方应用访问某些受保护的资源(如社交信息、文件等)而无需直接暴露用户名和密码时,OAuth 2.0非常适合。用户通过授权流程给应用颁发访问令牌(Access Token),实现安全、灵活的授权。
单点登录(SSO) 通过OAuth 2.0,用户可以在一个身份认证服务中登录后,无需重复登录即可访问多个受信任的应用,实现便捷的单点登录体验。
开放平台API安全接入 许多开放平台(如微信、支付宝、GitHub、Google等)要求第三方开发者通过OAuth 2.0标准安全地调用平台的API接口,确保数据访问权限和安全合规。
微服务体系下的服务认证 在微服务架构中,后端各服务间也可通过OAuth 2.0协议验证和传递访问令牌,用于服务间调用的安全控制和身份识别。
移动端和前端分离系统 OAuth 2.0因其支持Token机制,适合前后端分离、移动端、小程序、桌面客户端等多端接入场景,提高了灵活性和安全性,避免了传统Session暴露风险。
总结 :OAuth 2.0擅长于“委托式授权”和“令牌驱动”安全访问,能够保护用户隐私,避免凭证泄露,广泛用于社交登录、开放云服务API、企业内部/跨系统认证授权等场景。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 type OAuth2Auth struct { tokenEndpoint string client *http.Client } func (a *OAuth2Auth) Authenticate(req *http.Request) (*TokenInfo, error ) { token := req.Header.Get("Authorization" ) if !strings.HasPrefix(token, "Bearer " ) { return nil , fmt.Errorf("invalid token format" ) } token = token[7 :] return a.introspectToken(token) } func (a *OAuth2Auth) introspectToken(token string ) (*TokenInfo, error ) { req, _ := http.NewRequest("POST" , a.tokenEndpoint, strings.NewReader("token=" +token)) req.Header.Set("Content-Type" , "application/x-www-form-urlencoded" ) resp, err := a.client.Do(req) if err != nil { return nil , err } defer resp.Body.Close() var info TokenInfo json.NewDecoder(resp.Body).Decode(&info) if !info.Active { return nil , fmt.Errorf("token is not active" ) } return &info, nil }
鉴权 鉴权(Authorization)是验证用户权限的过程,确认”你能做什么”。
鉴权概述 graph LR
A[已认证用户] --> B[检查权限]
B --> C{有权限?}
C -->|是| D[允许访问]
C -->|否| E[拒绝访问]
style B fill:#51CF66
style E fill:#FF6B6B
鉴权模型:
RBAC :基于角色的访问控制
ABAC :基于属性的访问控制
ACL :访问控制列表
RBAC鉴权 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 type RBACAuthorizer struct { permissions map [string ][]string } func (a *RBACAuthorizer) Authorize(userRole, resource, action string ) bool { perms, ok := a.permissions[userRole] if !ok { return false } requiredPerm := fmt.Sprintf("%s:%s" , resource, action) for _, perm := range perms { if perm == requiredPerm || perm == "*" { return true } } return false } func NewRBACAuthorizer () *RBACAuthorizer { return &RBACAuthorizer{ permissions: map [string ][]string { "admin" : {"*" }, "user" : { "orders:read" , "orders:create" , }, "guest" : { "products:read" , }, }, } } func RBACMiddleware (auth *RBACAuthorizer) func (http.Handler) http.Handler { return func (next http.Handler) http.Handler { return http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) { claims, ok := r.Context().Value("claims" ).(*Claims) if !ok { http.Error(w, "unauthorized" , http.StatusUnauthorized) return } resource := extractResource(r.URL.Path) action := extractAction(r.Method) if !auth.Authorize(claims.Role, resource, action) { http.Error(w, "forbidden" , http.StatusForbidden) return } next.ServeHTTP(w, r) }) } } func extractResource (path string ) string { parts := strings.Split(path, "/" ) if len (parts) >= 3 { return parts[2 ] } return "" } func extractAction (method string ) string { switch method { case "GET" : return "read" case "POST" : return "create" case "PUT" , "PATCH" : return "update" case "DELETE" : return "delete" default : return "unknown" } }
ABAC鉴权 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 type ABACAuthorizer struct { policies []Policy } type Policy struct { Subject map [string ]interface {} Resource map [string ]interface {} Action string Condition func (*Request) bool Effect string } func (a *ABACAuthorizer) Authorize(req *Request) bool { for _, policy := range a.policies { if !a.matchSubject(policy.Subject, req.User) { continue } if !a.matchResource(policy.Resource, req.Resource) { continue } if policy.Action != req.Action && policy.Action != "*" { continue } if policy.Condition != nil && !policy.Condition(req) { continue } return policy.Effect == "allow" } return false }
限流 限流(Rate Limiting)是控制请求速率,防止系统过载。
限流概述 graph LR
A[请求] --> B[限流检查]
B --> C{允许?}
C -->|是| D[转发请求]
C -->|否| E[返回429]
style B fill:#FFE66D
style E fill:#FF6B6B
限流算法:
固定窗口 :固定时间窗口内的请求数限制
滑动窗口 :滑动时间窗口内的请求数限制
令牌桶 :令牌桶算法
漏桶 :漏桶算法
固定窗口限流 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 type FixedWindowLimiter struct { limit int window time.Duration counters map [string ]*Counter mu sync.RWMutex } type Counter struct { count int windowEnd time.Time } func NewFixedWindowLimiter (limit int , window time.Duration) *FixedWindowLimiter { return &FixedWindowLimiter{ limit: limit, window: window, counters: make (map [string ]*Counter), } } func (l *FixedWindowLimiter) Allow(key string ) bool { l.mu.Lock() defer l.mu.Unlock() now := time.Now() counter, ok := l.counters[key] if !ok || now.After(counter.windowEnd) { l.counters[key] = &Counter{ count: 1 , windowEnd: now.Add(l.window), } return true } if counter.count >= l.limit { return false } counter.count++ return true }
令牌桶限流 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 type TokenBucketLimiter struct { capacity int64 rate int64 tokens map [string ]*Bucket mu sync.RWMutex } type Bucket struct { tokens int64 lastTime time.Time } func NewTokenBucketLimiter (capacity, rate int64 ) *TokenBucketLimiter { return &TokenBucketLimiter{ capacity: capacity, rate: rate, tokens: make (map [string ]*Bucket), } } func (l *TokenBucketLimiter) Allow(key string ) bool { l.mu.Lock() defer l.mu.Unlock() now := time.Now() bucket, ok := l.tokens[key] if !ok { bucket = &Bucket{ tokens: l.capacity, lastTime: now, } l.tokens[key] = bucket } elapsed := now.Sub(bucket.lastTime) tokensToAdd := int64 (elapsed.Seconds()) * l.rate bucket.tokens = min(bucket.tokens+tokensToAdd, l.capacity) bucket.lastTime = now if bucket.tokens > 0 { bucket.tokens-- return true } return false }
限流中间件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 func RateLimitMiddleware (limiter RateLimiter) func (http.Handler) http.Handler { return func (next http.Handler) http.Handler { return http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) { key := getRateLimitKey(r) if !limiter.Allow(key) { w.Header().Set("X-RateLimit-Limit" , strconv.Itoa(limiter.Limit())) w.Header().Set("X-RateLimit-Remaining" , "0" ) w.Header().Set("Retry-After" , strconv.Itoa(limiter.RetryAfter())) http.Error(w, "rate limit exceeded" , http.StatusTooManyRequests) return } next.ServeHTTP(w, r) }) } } func getRateLimitKey (r *http.Request) string { if userID := r.Context().Value("user_id" ); userID != nil { return fmt.Sprintf("user:%s" , userID) } return fmt.Sprintf("ip:%s" , getClientIP(r)) }
请求处理 请求处理包括请求数据的重写、转换和过滤。
请求处理概述 graph TB
A[原始请求] --> B[请求处理]
B --> C[重写请求数据]
B --> D[请求转换]
B --> E[请求验证]
E --> F[转发请求]
style B fill:#FFE66D
重写请求数据 重写请求数据允许在转发前修改请求内容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 func RequestRewriteMiddleware (next http.Handler) http.Handler { return http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) { r.Header.Set("X-Forwarded-For" , getClientIP(r)) r.Header.Set("X-Forwarded-Proto" , getScheme(r)) r.Header.Set("X-Gateway-Version" , "v1.0" ) if r.Body != nil { body, _ := io.ReadAll(r.Body) r.Body.Close() modifiedBody := modifyRequestBody(body) r.Body = io.NopCloser(bytes.NewReader(modifiedBody)) r.ContentLength = int64 (len (modifiedBody)) } next.ServeHTTP(w, r) }) } func modifyRequestBody (body []byte ) []byte { var data map [string ]interface {} json.Unmarshal(body, &data) data["gateway_timestamp" ] = time.Now().Unix() modified, _ := json.Marshal(data) return modified }
请求验证 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 func RequestValidationMiddleware (next http.Handler) http.Handler { return http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) { if r.ContentLength > maxRequestSize { http.Error(w, "request too large" , http.StatusRequestEntityTooLarge) return } if r.Method == "POST" || r.Method == "PUT" { contentType := r.Header.Get("Content-Type" ) if !strings.HasPrefix(contentType, "application/json" ) { http.Error(w, "invalid content type" , http.StatusBadRequest) return } } if err := validateRequiredParams(r); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } next.ServeHTTP(w, r) }) }
过滤响应 过滤响应允许在返回给客户端前修改响应内容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 type ResponseFilter struct { filters []ResponseFilterFunc } type ResponseFilterFunc func (*http.Response) error func (f *ResponseFilter) Filter(next http.Handler) http.Handler { return http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) { rw := &responseWriter{ ResponseWriter: w, filters: f.filters, } next.ServeHTTP(rw, r) }) } type responseWriter struct { http.ResponseWriter filters []ResponseFilterFunc body []byte status int } func (rw *responseWriter) Write(b []byte ) (int , error ) { rw.body = append (rw.body, b...) return len (b), nil } func (rw *responseWriter) WriteHeader(statusCode int ) { rw.status = statusCode } func (rw *responseWriter) flush() error { resp := &http.Response{ StatusCode: rw.status, Header: rw.Header(), Body: io.NopCloser(bytes.NewReader(rw.body)), } for _, filter := range rw.filters { if err := filter(resp); err != nil { return err } } for k, v := range resp.Header { for _, val := range v { rw.ResponseWriter.Header().Add(k, val) } } rw.ResponseWriter.WriteHeader(resp.StatusCode) body, _ := io.ReadAll(resp.Body) rw.ResponseWriter.Write(body) return nil } func RemoveSensitiveDataFilter (resp *http.Response) error { if resp.Header.Get("Content-Type" ) != "application/json" { return nil } body, _ := io.ReadAll(resp.Body) resp.Body.Close() var data map [string ]interface {} json.Unmarshal(body, &data) delete (data, "password" ) delete (data, "token" ) delete (data, "secret" ) modified, _ := json.Marshal(data) resp.Body = io.NopCloser(bytes.NewReader(modified)) resp.ContentLength = int64 (len (modified)) return nil }
其他功能 熔断 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 type CircuitBreaker struct { maxFailures int timeout time.Duration state CircuitState failures int lastFailure time.Time mu sync.RWMutex } func (cb *CircuitBreaker) Execute(fn func () error ) error { cb.mu.Lock() state := cb.state cb.mu.Unlock() if state == StateOpen { if time.Since(cb.lastFailure) > cb.timeout { cb.mu.Lock() cb.state = StateHalfOpen cb.mu.Unlock() } else { return ErrCircuitOpen } } err := fn() cb.mu.Lock() if err != nil { cb.failures++ cb.lastFailure = time.Now() if cb.failures >= cb.maxFailures { cb.state = StateOpen } } else { cb.failures = 0 if cb.state == StateHalfOpen { cb.state = StateClosed } } cb.mu.Unlock() return err }
缓存 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 func CacheMiddleware (cache Cache) func (http.Handler) http.Handler { return func (next http.Handler) http.Handler { return http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) { if r.Method != "GET" { next.ServeHTTP(w, r) return } cacheKey := generateCacheKey(r) if cached, ok := cache.Get(cacheKey); ok { w.Header().Set("X-Cache" , "HIT" ) w.Write(cached) return } rw := &cacheResponseWriter{ ResponseWriter: w, cache: cache, cacheKey: cacheKey, } next.ServeHTTP(rw, r) }) } }
监控和日志 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 func MonitoringMiddleware (next http.Handler) http.Handler { return http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) { start := time.Now() rw := &monitoringResponseWriter{ ResponseWriter: w, statusCode: http.StatusOK, } next.ServeHTTP(rw, r) duration := time.Since(start) recordMetrics(r, rw.statusCode, duration) logRequest(r, rw.statusCode, duration) }) } func recordMetrics (r *http.Request, status int , duration time.Duration) { httpRequestsTotal.WithLabelValues( r.Method, r.URL.Path, strconv.Itoa(status), ).Inc() httpRequestDuration.WithLabelValues( r.Method, r.URL.Path, ).Observe(duration.Seconds()) }
主流API网关 Kong Kong是开源的API网关,基于Nginx和OpenResty。
Kong特性 graph TB
A[Kong] --> B[插件系统]
A --> C[高性能]
A --> D[云原生]
A --> E[管理API]
核心特性:
基于Nginx,性能优秀
丰富的插件生态
支持云原生部署
RESTful管理API
Kong配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 _format_version: "3.0" services: - name: order-service url: http://order-service:8080 routes: - name: order-route paths: - /api/orders methods: - GET - POST plugins: - name: rate-limiting config: minute: 100 - name: jwt config: secret_is_base64: false plugins: - name: cors config: origins: - "*" methods: - GET - POST - PUT - DELETE
Nginx Nginx是高性能的Web服务器和反向代理,也可以作为API网关使用。
Nginx配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 upstream order_service { server order-service-1 :8080 ; server order-service-2 :8080 ; server order-service-3 :8080 ; } server { listen 80 ; server_name api.example.com; limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s; location /api/orders { limit_req zone=api_limit burst=20 ; auth_request /auth; proxy_pass http://order_service; proxy_set_header Host $host ; proxy_set_header X-Real-IP $remote_addr ; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for ; } location = /auth { internal; proxy_pass http://auth-service:8080/validate; proxy_pass_request_body off ; proxy_set_header Content-Length "" ; proxy_set_header X-Original-URI $request_uri ; } }
Envoy Envoy是云原生的代理服务器,常用于服务网格和API网关。
Envoy配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 static_resources: listeners: - name: listener_0 address: socket_address: address: 0.0 .0 .0 port_value: 80 filter_chains: - filters: - name: envoy.filters.network.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager stat_prefix: ingress_http route_config: name: local_route virtual_hosts: - name: local_service domains: ["*" ] routes: - match: prefix: "/api/orders" route: cluster: order_service http_filters: - name: envoy.filters.http.router clusters: - name: order_service connect_timeout: 0. 25s type: LOGICAL_DNS lb_policy: ROUND_ROBIN load_assignment: cluster_name: order_service endpoints: - lb_endpoints: - endpoint: address: socket_address: address: order-service port_value: 8080
Traefik Traefik是云原生的HTTP反向代理和负载均衡器。
Traefik特性
自动服务发现
动态配置
Let’s Encrypt集成
丰富的中间件
API网关最佳实践 1. 网关设计原则 graph TB
A[网关设计] --> B[单一职责]
A --> C[高可用]
A --> D[高性能]
A --> E[可扩展]
style A fill:#FFE66D
原则:
单一职责 :只处理横切关注点
高可用 :网关本身要高可用
高性能 :低延迟,高吞吐
可扩展 :支持水平扩展
2. 安全设计
认证 :统一认证入口
鉴权 :细粒度权限控制
加密 :HTTPS传输
防护 :防DDoS、防SQL注入等
3. 性能优化
缓存 :缓存响应数据
连接池 :复用后端连接
压缩 :响应数据压缩
限流 :防止过载
4. 监控和日志
指标监控 :请求数、延迟、错误率
日志记录 :完整的请求日志
追踪 :分布式追踪支持
告警 :异常告警
总结 API网关是微服务架构中的重要组件,提供统一入口和横切关注点的处理。
核心功能:
路由 :请求路由和转发
认证 :用户身份验证
鉴权 :权限控制
限流 :流量控制
请求处理 :请求重写和响应过滤
最佳实践:
选择合适的网关方案
设计合理的路由规则
实现完善的认证鉴权
配置合理的限流策略
完善的监控和日志
通过系统性的API网关设计,可以构建安全、高性能、易维护的微服务系统。