最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Cloud Gateway詳細使用最佳實踐

 更新時間:2025年11月29日 10:51:59   作者:龍茶清歡  
Spring Cloud Gateway 是 Spring Cloud 生態(tài)系統(tǒng)中的現(xiàn)代化 API 網(wǎng)關組件,用于構(gòu)建微服務架構(gòu)中的統(tǒng)一入口網(wǎng)關,本文介紹Spring Cloud Gateway詳細使用最佳實踐,感興趣的朋友一起看看吧

1. Spring Cloud Gateway 是什么?

Spring Cloud Gateway 是 Spring Cloud 生態(tài)系統(tǒng)中的現(xiàn)代化 API 網(wǎng)關組件,用于構(gòu)建微服務架構(gòu)中的統(tǒng)一入口網(wǎng)關。它基于 Spring Framework 5、Project Reactor 和 Spring Boot 2.x 構(gòu)建,采用響應式編程模型,提供高性能、非阻塞式的 API 路由和橫切關注點處理能力。

1.1 技術(shù)架構(gòu)基礎

  • 響應式編程:基于 Project Reactor 的響應式流處理
  • WebFlux:使用 Spring WebFlux 而非傳統(tǒng)的 Servlet 模型
  • 函數(shù)式編程:支持 Java 8+ 的函數(shù)式編程風格
  • 高性能:相比 Zuul 1.x(阻塞式),性能提升顯著

1.2 在微服務架構(gòu)中的定位

客戶端 → Spring Cloud Gateway → 微服務A
                             → 微服務B  
                             → 微服務C

作為所有微服務的統(tǒng)一入口點,客戶端只需要與網(wǎng)關交互,無需知道后端服務的具體位置。

2. Spring Cloud Gateway 的作用

2.1 核心作用

  • 統(tǒng)一入口:為所有微服務提供單一訪問入口
  • 路由轉(zhuǎn)發(fā):根據(jù)配置規(guī)則將請求路由到對應的服務
  • 負載均衡:集成 Spring Cloud LoadBalancer 實現(xiàn)服務發(fā)現(xiàn)和負載均衡
  • 協(xié)議適配:支持 HTTP/HTTPS、WebSocket 等協(xié)議
  • 監(jiān)控指標:收集請求日志、性能指標等監(jiān)控數(shù)據(jù)

2.2 橫切關注點處理

  • 認證(Authentication):統(tǒng)一處理用戶身份驗證
  • 安全防護:防重放攻擊、IP 黑白名單、基礎安全頭設置
  • 限流熔斷:實現(xiàn)請求限流、服務降級等保護機制
  • 請求/響應修改:修改請求頭、響應頭等

3. Spring Cloud Gateway 的特點

3.1 技術(shù)特點

  • 響應式非阻塞:基于 Reactor 的異步非阻塞處理模型
  • 高性能:單機可處理數(shù)萬 QPS
  • 靈活路由:支持多種路由匹配方式(Path、Host、Method、Header 等)
  • 豐富過濾器:內(nèi)置多種過濾器,支持自定義過濾器
  • 動態(tài)配置:支持運行時動態(tài)修改路由配置
  • 服務發(fā)現(xiàn)集成:無縫集成 Eureka、Consul、Nacos 等注冊中心

3.2 功能組件

  • Route(路由):定義請求如何被轉(zhuǎn)發(fā)到目標服務
  • Predicate(斷言):匹配 HTTP 請求的各種條件
  • Filter(過濾器):修改請求和響應的邏輯
  • GlobalFilter(全局過濾器):應用于所有路由的過濾器

4. 網(wǎng)關應該做什么 vs 不應該做什么

4.1 ? 網(wǎng)關應該做的事情

4.1.1 路由和轉(zhuǎn)發(fā)

  • 根據(jù)路徑、主機名等條件路由請求
  • 實現(xiàn)負載均衡和服務發(fā)現(xiàn)
  • 處理協(xié)議轉(zhuǎn)換(如 WebSocket)

4.1.2 基礎安全(認證層面)

  • 身份認證:驗證 JWT Token、API Key 等的有效性
  • Token 驗證:檢查簽名、過期時間、基本格式
  • 安全頭處理:添加 X-Forwarded-For、X-Real-IP 等頭信息
  • 基礎防護:IP 黑白名單、防刷、防重放攻擊

4.1.3 運維和監(jiān)控

  • 統(tǒng)一日志:記錄訪問日志、請求響應時間
  • 指標收集:收集 QPS、響應時間、錯誤率等指標
  • 健康檢查:提供網(wǎng)關自身的健康檢查端點
  • 限流熔斷:基于 Redis 或內(nèi)存的請求限流

4.1.4 請求/響應處理

  • 路徑重寫:StripPrefix、PrefixPath 等
  • 頭信息修改:添加、刪除、修改請求/響應頭
  • 重試機制:對失敗請求進行重試

4.2 ? 網(wǎng)關不應該做的事情

4.2.1 業(yè)務權(quán)限控制(授權(quán))

  • 不應該進行細粒度權(quán)限驗證(如:用戶A能否訪問用戶B的數(shù)據(jù))
  • 不應該驗證業(yè)務級別的權(quán)限(如:是否有刪除權(quán)限、編輯權(quán)限)
  • 不應該替代業(yè)務服務的安全邏輯

4.2.2 業(yè)務邏輯處理

  • 不應該包含業(yè)務邏輯(如:訂單狀態(tài)驗證、庫存檢查)
  • 不應該調(diào)用業(yè)務數(shù)據(jù)庫進行復雜查詢
  • 不應該處理業(yè)務數(shù)據(jù)轉(zhuǎn)換

4.2.3 復雜數(shù)據(jù)處理

  • 不應該解析和驗證復雜的請求體
  • 不應該進行業(yè)務數(shù)據(jù)的校驗和轉(zhuǎn)換
  • 不應該緩存業(yè)務數(shù)據(jù)

4.3 ??? 正確的安全分層架構(gòu)

客戶端 → 網(wǎng)關層(Authentication) → 業(yè)務服務層(Authorization)
         ↓                          ↓
    驗證"你是誰"                驗證"你能做什么"
    Token有效性驗證             業(yè)務權(quán)限驗證
    基礎安全防護               數(shù)據(jù)權(quán)限控制

5. 詳細使用示例

5.1 基礎環(huán)境搭建

5.1.1 Maven 依賴配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.0</version>
        <relativePath/>
    </parent>
    <groupId>com.example</groupId>
    <artifactId>spring-cloud-gateway-demo</artifactId>
    <version>1.0.0</version>
    <name>spring-cloud-gateway-demo</name>
    <properties>
        <java.version>11</java.version>
        <spring-cloud.version>2021.0.3</spring-cloud.version>
    </properties>
    <dependencies>
        <!-- Spring Cloud Gateway 核心依賴 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <!-- 服務發(fā)現(xiàn)客戶端(用于集成注冊中心) -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
        <!-- Actuator 監(jiān)控端點 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!-- Redis 依賴(用于限流) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

5.1.2 基礎配置文件 (application.yml)

server:
  port: 9000  # 網(wǎng)關服務端口
spring:
  application:
    name: api-gateway  # 應用名稱
  cloud:
    gateway:
      # 全局跨域配置
      globalcors:
        cors-configurations:
          '[/**]':
            allowedOrigins: "*"      # 允許所有源
            allowedMethods: "*"      # 允許所有HTTP方法
            allowedHeaders: "*"      # 允許所有請求頭
            allowCredentials: true   # 允許攜帶憑證
      # 路由配置
      routes:
        # 用戶服務路由 - 網(wǎng)關只負責路由和基礎認證
        - id: user-service-route
          uri: http://localhost:8081
          predicates:
            - Path=/api/users/**     # 匹配用戶相關路徑
          filters:
            - StripPrefix=2          # 去掉 /api/users 前綴,實際轉(zhuǎn)發(fā)到 /**
        # 訂單服務路由
        - id: order-service-route
          uri: http://localhost:8082
          predicates:
            - Path=/api/orders/**
          filters:
            - StripPrefix=2
# Actuator 監(jiān)控配置
management:
  endpoints:
    web:
      exposure:
        include: '*'               # 暴露所有監(jiān)控端點
  endpoint:
    gateway:
      enabled: true                # 啟用網(wǎng)關管理端點

5.2 路由配置詳解

5.2.1 Java 代碼配置路由

package com.example.gateway.config;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
 * 網(wǎng)關路由配置類
 * 使用 Java 代碼方式配置路由,相比配置文件更加靈活
 * 注意:這里只配置路由規(guī)則,不包含業(yè)務權(quán)限邏輯
 */
@Configuration
public class GatewayRouteConfig {
    /**
     * 配置自定義路由規(guī)則
     * @param builder RouteLocatorBuilder 用于構(gòu)建路由
     * @return RouteLocator 路由定位器
     */
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                // 用戶服務路由
                .route("user-service", r -> r
                        .path("/api/users/**")           // 匹配路徑
                        .uri("http://localhost:8081")    // 目標服務地址
                        .filters(f -> f.stripPrefix(2))  // 去掉前兩個路徑段 (/api/users)
                )
                // 訂單服務路由
                .route("order-service", r -> r
                        .path("/api/orders/**")
                        .uri("http://localhost:8082")
                        .filters(f -> f.stripPrefix(2))
                )
                // 公開API路由(無需認證)
                .route("public-api", r -> r
                        .path("/api/public/**")
                        .uri("http://localhost:8083")
                        .filters(f -> f.stripPrefix(2))
                )
                .build();
    }
}

5.3 斷言(Predicates)使用示例

package com.example.gateway.config;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
 * 各種斷言使用示例
 * 斷言用于定義路由匹配條件,只有滿足條件的請求才會被路由
 * 這些都是基礎的路由條件,不涉及業(yè)務邏輯
 */
@Configuration
public class PredicateConfig {
    @Bean
    public RouteLocator predicateRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                // 1. Path 斷言:基于URL路徑匹配
                .route("path-route", r -> r
                        .path("/api/v1/**", "/api/v2/**")  // 支持多個路徑模式
                        .uri("http://localhost:8081")
                )
                // 2. Method 斷言:基于HTTP方法匹配
                .route("method-route", r -> r
                        .path("/api/method/**")
                        .and()
                        .method("GET", "POST")  // 只匹配GET和POST請求
                        .uri("http://localhost:8082")
                )
                // 3. Header 斷言:基于請求頭匹配
                .route("header-route", r -> r
                        .path("/api/header/**")
                        .and()
                        .header("X-API-Version", "v1")  // 必須包含指定請求頭
                        .uri("http://localhost:8083")
                )
                // 4. Query 斷言:基于查詢參數(shù)匹配
                .route("query-route", r -> r
                        .path("/api/query/**")
                        .and()
                        .query("version", "1.0")  // 查詢參數(shù) version=1.0
                        .uri("http://localhost:8084")
                )
                // 5. Host 斷言:基于Host頭匹配
                .route("host-route", r -> r
                        .host("api.example.com", "api.test.com")  // 匹配指定域名
                        .uri("http://localhost:8085")
                )
                .build();
    }
}

5.4 過濾器(Filters)使用示例

5.4.1 內(nèi)置過濾器配置

package com.example.gateway.config;
import org.springframework.cloud.gateway.filter.ratelimit.RedisRateLimiter;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
 * 內(nèi)置過濾器使用示例
 * 過濾器用于修改請求和響應,但只做基礎處理,不涉及業(yè)務邏輯
 */
@Configuration
public class FilterConfig {
    @Bean
    public RouteLocator filterRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                // 1. 添加請求頭過濾器
                .route("add-header-route", r -> r
                        .path("/api/add-header/**")
                        .filters(f -> f
                                // 添加網(wǎng)關來源標識
                                .addRequestHeader("X-Gateway-Source", "spring-cloud-gateway")
                                // 添加請求時間戳
                                .addRequestHeader("X-Request-Timestamp", 
                                    String.valueOf(System.currentTimeMillis()))
                        )
                        .uri("http://localhost:8081")
                )
                // 2. 添加響應頭過濾器
                .route("add-response-header-route", r -> r
                        .path("/api/add-response-header/**")
                        .filters(f -> f
                                .addResponseHeader("X-Gateway-Processed", "true")
                        )
                        .uri("http://localhost:8082")
                )
                // 3. 路徑重寫過濾器
                .route("strip-prefix-route", r -> r
                        .path("/api/strip/**")
                        .filters(f -> f.stripPrefix(1))  // 去掉第一個路徑段
                        .uri("http://localhost:8083")
                )
                // 4. 限流過濾器(使用Redis)
                .route("rate-limiter-route", r -> r
                        .path("/api/rate-limiter/**")
                        .filters(f -> f
                                .requestRateLimiter()
                                .rateLimiter(RedisRateLimiter.class)
                                // 配置限流參數(shù):每秒5個請求,突發(fā)容量10個
                                .configure(c -> c.setBurstCapacity(10).setReplenishRate(5))
                        )
                        .uri("http://localhost:8084")
                )
                // 5. 重試過濾器
                .route("retry-route", r -> r
                        .path("/api/retry/**")
                        .filters(f -> f.retry(3))  // 失敗時重試3次
                        .uri("http://localhost:8085")
                )
                .build();
    }
}

5.5 網(wǎng)關安全配置(正確的做法)

5.5.1 網(wǎng)關層認證過濾器(只做身份認證)

package com.example.gateway.filter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.Arrays;
import java.util.List;
/**
 * 網(wǎng)關認證過濾器 - 只負責身份認證,不負責權(quán)限授權(quán)
 * 
 * 職責范圍:
 * ? 驗證JWT Token的有效性(簽名、過期時間)
 * ? 驗證Token的基本格式
 * ? 將用戶信息傳遞給下游服務
 * ? 不進行業(yè)務權(quán)限驗證
 * ? 不調(diào)用業(yè)務數(shù)據(jù)庫
 * ? 不處理復雜的業(yè)務邏輯
 */
@Component
public class AuthenticationGlobalFilter implements GlobalFilter, Ordered {
    // 公開路徑列表(無需認證的路徑)
    private static final List<String> PUBLIC_PATHS = Arrays.asList(
        "/api/public/**",
        "/api/auth/login",
        "/api/auth/register",
        "/actuator/**"
    );
    /**
     * 全局過濾器執(zhí)行邏輯
     * @param exchange 當前請求交換對象
     * @param chain 過濾器鏈
     * @return Mono<Void> 響應式返回
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String requestPath = exchange.getRequest().getURI().getPath();
        // 1. 檢查是否為公開路徑,如果是則直接放行
        if (isPublicPath(requestPath)) {
            return chain.filter(exchange);
        }
        // 2. 從請求頭中提取認證令牌
        String token = extractToken(exchange);
        if (token == null || token.isEmpty()) {
            return handleUnauthorized(exchange, "Missing authentication token");
        }
        try {
            // 3. 驗證令牌有效性(只驗證簽名和過期時間,不驗證業(yè)務權(quán)限)
            if (!validateTokenSignatureAndExpiry(token)) {
                return handleUnauthorized(exchange, "Invalid or expired token");
            }
            // 4. 從令牌中提取用戶基本信息
            String userId = extractUserIdFromToken(token);
            String userRoles = extractUserRolesFromToken(token);
            // 5. 將用戶信息添加到請求頭,傳遞給下游業(yè)務服務
            // 下游服務將基于這些信息進行具體的權(quán)限驗證
            ServerHttpRequest modifiedRequest = exchange.getRequest().mutate()
                    .header("X-User-Id", userId)
                    .header("X-User-Roles", userRoles)
                    .header("X-Authenticated", "true")
                    .build();
            return chain.filter(exchange.mutate().request(modifiedRequest).build());
        } catch (Exception e) {
            return handleUnauthorized(exchange, "Authentication processing failed: " + e.getMessage());
        }
    }
    /**
     * 判斷路徑是否為公開路徑
     * @param path 請求路徑
     * @return 是否為公開路徑
     */
    private boolean isPublicPath(String path) {
        return PUBLIC_PATHS.stream()
                .anyMatch(publicPath -> path.matches(publicPath.replace("**", ".*")));
    }
    /**
     * 從請求中提取認證令牌
     * 支持 Bearer Token 和自定義 Header
     */
    private String extractToken(ServerWebExchange exchange) {
        // 優(yōu)先從 Authorization 頭獲取
        String authHeader = exchange.getRequest().getHeaders().getFirst("Authorization");
        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            return authHeader.substring(7); // 去掉 "Bearer " 前綴
        }
        // 也可以從自定義頭或查詢參數(shù)獲取
        String tokenHeader = exchange.getRequest().getHeaders().getFirst("X-API-Token");
        if (tokenHeader != null) {
            return tokenHeader;
        }
        return null;
    }
    /**
     * 驗證令牌簽名和過期時間
     * 注意:這里只做基礎驗證,不做業(yè)務權(quán)限驗證
     */
    private boolean validateTokenSignatureAndExpiry(String token) {
        // 實際項目中應該使用 JWT 庫進行驗證
        // 這里簡化處理,實際應該驗證簽名、過期時間等
        try {
            // 偽代碼:驗證 JWT 簽名和過期時間
            // Jwts.parser().setSigningKey(secret).parseClaimsJws(token);
            return token.length() > 20; // 簡單驗證
        } catch (Exception e) {
            return false;
        }
    }
    /**
     * 從令牌中提取用戶ID
     * 實際項目中應該解析 JWT payload
     */
    private String extractUserIdFromToken(String token) {
        // 偽代碼:從 JWT 中提取用戶ID
        return "user123"; // 簡化處理
    }
    /**
     * 從令牌中提取用戶角色
     * 實際項目中應該解析 JWT payload 中的角色信息
     */
    private String extractUserRolesFromToken(String token) {
        // 偽代碼:從 JWT 中提取角色
        return "USER,PREMIUM"; // 簡化處理
    }
    /**
     * 處理未授權(quán)請求
     */
    private Mono<Void> handleUnauthorized(ServerWebExchange exchange, String message) {
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        exchange.getResponse().getHeaders().add("Content-Type", "application/json");
        String response = "{\"error\":\"Unauthorized\",\"message\":\"" + message + "\"}";
        return exchange.getResponse().writeWith(
            Mono.just(exchange.getResponse().bufferFactory().wrap(response.getBytes()))
        );
    }
    /**
     * 設置過濾器執(zhí)行順序
     * 數(shù)值越小,優(yōu)先級越高
     */
    @Override
    public int getOrder() {
        return -100; // 在很早的階段執(zhí)行認證
    }
}

5.5.2 業(yè)務服務層權(quán)限控制(真正的授權(quán))

// 用戶服務中的權(quán)限控制示例
package com.example.userservice.controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.http.HttpStatus;
/**
 * 用戶控制器 - 在業(yè)務服務中進行真正的權(quán)限驗證
 * 
 * 網(wǎng)關已經(jīng)完成了身份認證,這里進行業(yè)務級別的權(quán)限授權(quán)
 */
@RestController
@RequestMapping("/api")
public class UserController {
    /**
     * 獲取用戶詳情
     * 需要驗證當前用戶是否有權(quán)限訪問目標用戶
     */
    @GetMapping("/users/{userId}")
    public User getUser(@RequestHeader("X-User-Id") String currentUserId,
                       @RequestHeader("X-User-Roles") String userRoles,
                       @PathVariable String userId) {
        // 1. 驗證是否是訪問自己的信息(普通用戶只能訪問自己)
        if (!currentUserId.equals(userId)) {
            // 2. 如果不是訪問自己,檢查是否具有管理員角色
            if (!userRoles.contains("ADMIN")) {
                throw new ResponseStatusException(HttpStatus.FORBIDDEN, 
                    "Insufficient permissions to access this user data");
            }
        }
        // 3. 執(zhí)行業(yè)務邏輯
        return userService.findById(userId);
    }
    /**
     * 刪除用戶 - 需要管理員權(quán)限
     * 使用 Spring Security 注解進行權(quán)限控制
     */
    @PreAuthorize("hasRole('ADMIN')")
    @DeleteMapping("/users/{userId}")
    public void deleteUser(@PathVariable String userId) {
        userService.delete(userId);
    }
}

5.6 日志和監(jiān)控配置

5.6.1 訪問日志過濾器

package com.example.gateway.filter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.time.LocalDateTime;
/**
 * 訪問日志全局過濾器
 * 記錄請求的基本信息,用于監(jiān)控和審計
 * 注意:只記錄基礎信息,不記錄敏感業(yè)務數(shù)據(jù)
 */
@Component
public class AccessLogGlobalFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 記錄請求開始時間
        long startTime = System.currentTimeMillis();
        String path = exchange.getRequest().getURI().getPath();
        String method = exchange.getRequest().getMethodValue();
        String clientIp = getClientIp(exchange);
        System.out.println(String.format(
            "[ACCESS-LOG] %s | %s | %s | %s", 
            LocalDateTime.now(), method, path, clientIp
        ));
        // 繼續(xù)處理請求,并記錄響應時間
        return chain.filter(exchange).doOnTerminate(() -> {
            long duration = System.currentTimeMillis() - startTime;
            System.out.println(String.format(
                "[ACCESS-LOG] Response time: %d ms for %s", duration, path
            ));
        });
    }
    private String getClientIp(ServerWebExchange exchange) {
        String xForwardedFor = exchange.getRequest().getHeaders().getFirst("X-Forwarded-For");
        if (xForwardedFor != null && !xForwardedFor.isEmpty()) {
            return xForwardedFor.split(",")[0].trim();
        }
        return exchange.getRequest().getRemoteAddress() != null ? 
               exchange.getRequest().getRemoteAddress().getAddress().getHostAddress() : "unknown";
    }
    @Override
    public int getOrder() {
        return Ordered.LOWEST_PRECEDENCE - 1; // 在最后執(zhí)行,確保能獲取到完整信息
    }
}

5.7 完整的啟動類

package com.example.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
 * Spring Cloud Gateway 網(wǎng)關啟動類
 * 
 * 設計原則:
 * ? 網(wǎng)關只負責:路由轉(zhuǎn)發(fā)、身份認證、基礎安全、監(jiān)控日志
 * ? 網(wǎng)關不負責:業(yè)務權(quán)限、業(yè)務邏輯、數(shù)據(jù)驗證
 * 
 * 啟動后可用端點:
 * - 網(wǎng)關服務:http://localhost:9000
 * - 路由信息:http://localhost:9000/actuator/gateway/routes
 * - 健康檢查:http://localhost:9000/actuator/health
 */
@SpringBootApplication
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
        System.out.println("=====================================");
        System.out.println("Spring Cloud Gateway 啟動成功!");
        System.out.println("網(wǎng)關地址: http://localhost:9000");
        System.out.println("路由管理: http://localhost:9000/actuator/gateway/routes");
        System.out.println("=====================================");
    }
}

6. 最佳實踐總結(jié)

6.1 網(wǎng)關職責邊界

  • 網(wǎng)關層:路由 + 認證 + 基礎安全 + 監(jiān)控
  • 業(yè)務層:授權(quán) + 業(yè)務邏輯 + 數(shù)據(jù)驗證

6.2 性能優(yōu)化建議

  • 合理配置線程池和連接池
  • 避免在過濾器中執(zhí)行耗時操作
  • 使用緩存減少重復計算

6.3 安全最佳實踐

  • 網(wǎng)關只做身份認證,不做權(quán)限授權(quán)
  • 敏感信息不要在網(wǎng)關層處理
  • 使用 HTTPS 保護傳輸安全

6.4 監(jiān)控和運維

  • 集成 Prometheus + Grafana
  • 配置合理的健康檢查
  • 記錄詳細的訪問日志

這份文檔詳細說明了 Spring Cloud Gateway 的正確使用方式,特別強調(diào)了網(wǎng)關的職責邊界,避免了常見的架構(gòu)設計誤區(qū)。所有示例都包含詳細的中文注釋,幫助您理解每個組件的正確用途和實現(xiàn)方式。

到此這篇關于Spring Cloud Gateway詳細使用最佳實踐的文章就介紹到這了,更多相關Spring Cloud Gateway使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 基于Java+OpenClaw實現(xiàn)企業(yè)級智能體自動化

    基于Java+OpenClaw實現(xiàn)企業(yè)級智能體自動化

    本文介紹了OpenClaw開源框架,它為Java程序員提供了一個無需學習Python便可調(diào)用AI智能體的API網(wǎng)關,文章詳細講解了OpenClaw的核心功能、架構(gòu)設計、環(huán)境準備、Java集成實戰(zhàn)及企業(yè)級落地的關鍵細節(jié),需要的朋友可以參考下
    2026-04-04
  • java常用工具類 Reflect反射工具類、String字符串工具類

    java常用工具類 Reflect反射工具類、String字符串工具類

    這篇文章主要為大家詳細介紹了java常用工具類,包括Reflect反射工具類、String字符串工具類,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-05-05
  • Java 如何遍歷JsonObject對象

    Java 如何遍歷JsonObject對象

    這篇文章主要介紹了Java 如何遍歷JsonObject對象?今天小編就為大家分享一篇Java遍歷JsonObject對象案例,希望對大家有所幫助吧
    2021-01-01
  • java?工作流引擎設計實現(xiàn)解析流程定義文件

    java?工作流引擎設計實現(xiàn)解析流程定義文件

    這篇文章主要為大家介紹了java?工作流引擎設計與實現(xiàn)及流程定義文件解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-05-05
  • Android token過期刷新處理的方法示例

    Android token過期刷新處理的方法示例

    這篇文章主要介紹了Android token過期刷新處理的方法示例,本文詳細的介紹了2種方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-10-10
  • JAVA多態(tài)的底層實現(xiàn)機制解析(最新推薦)

    JAVA多態(tài)的底層實現(xiàn)機制解析(最新推薦)

    本文將深入解析?Java?多態(tài)的底層實現(xiàn)原理,并附帶可運行的實踐用例,幫助你徹底理解多態(tài)為何可行、如何執(zhí)行、性能如何保證,感興趣的朋友跟隨小編一起看看吧
    2025-12-12
  • RabbitMQ實現(xiàn)Work Queue工作隊列的示例詳解

    RabbitMQ實現(xiàn)Work Queue工作隊列的示例詳解

    工作隊列(又稱任務隊列)的主要思想是避免立即執(zhí)行資源密集型任務,而不得不等待它完成。本篇文章將記錄和分享RabbitMQ工作隊列相關的知識點,希望對大家有所幫助
    2023-01-01
  • 解決創(chuàng)建springboot后啟動報錯:Failed?to?bind?properties?under‘spring.datasource‘

    解決創(chuàng)建springboot后啟動報錯:Failed?to?bind?properties?under‘spri

    在Spring?Boot項目中,application.properties和application.yml是用于配置參數(shù)的兩種文件格式,properties格式簡潔但不支持層次結(jié)構(gòu),而yml格式支持層次性,可讀性更好,在yml文件中,要注意細節(jié),比如冒號后面需要空格
    2024-10-10
  • Spring?Boot使用Hutool快速集成驗證碼的兩種方案

    Spring?Boot使用Hutool快速集成驗證碼的兩種方案

    驗證碼作為一種簡單而有效的身份驗證手段,被廣泛應用于各種在線服務中,這篇文章主要介紹了Spring?Boot使用Hutool快速集成驗證碼的兩種方案,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2026-02-02
  • idea不使用maven如何將項目打包

    idea不使用maven如何將項目打包

    使用IDEA 2021版本,不借助Maven進行打WAR包的步驟是:首先點擊Project Structure,然后點擊Artifacts,接著選擇需要的打包類型,設置好包的名稱,最后進行打包,這種方法適用于不使用Maven進行項目管理的情況
    2024-09-09

最新評論

横山县| 梁河县| 吕梁市| 蒲江县| 和田县| 克什克腾旗| 明溪县| 邹城市| 赫章县| 荥经县| 钟山县| 常宁市| 五大连池市| 荣昌县| 无棣县| 荥阳市| 文山县| 马山县| 宁波市| 进贤县| 丹凤县| 班戈县| 高碑店市| 中卫市| 阿鲁科尔沁旗| 东安县| 托克逊县| 淳化县| 报价| 汶川县| 曲麻莱县| 易门县| 天津市| 大连市| 黎川县| 镇巴县| 米泉市| 永昌县| 宣恩县| 武夷山市| 富锦市|