Spring Cloud Gateway 使用示例

Spring Cloud Gateway 使用示例

作者: Grey

原文地址:

部落格園:Spring Cloud Gateway 使用示例

CSDN:Spring Cloud Gateway 使用示例

說明

Spring Cloud Gateway 用於構建 API 網關,基於 Spring WebFlux。

Spring Cloud G 版發布時,

Spring 官方把 Spring Cloud Gateway 作為 Zuul 1 的替代方案

本文主要通過一個示例介紹了 Spring Cloud Gateway 的基礎使用。

環境

  • JDK 1.8+

  • Maven 3.5+

  • Spring Boot 版本:2.7.5

  • Spring Cloud 版本:2021.0.5

涉及的依賴包

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-circuitbreaker-reactor-resilience4j</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-contract-stub-runner</artifactId>
    <scope>test</scope>
</dependency>

程式碼說明

第一個場景就是請求轉發,例如

請求://localhost:8080/jd

直接轉到://jd.com:80/jd

請求://localhost:8080/greyzeng

直接轉到://www.cnblogs.com/greyzeng

請求://localhost:8080/error

直接跳轉到自定義的一個錯誤頁面。

只需要做如下配置即可

@Bean
public RouteLocator myRoutes(RouteLocatorBuilder builder, UriConfiguration uriConfiguration) {
    return builder.routes()
                .route(p -> p.path("/jd").uri("//jd.com:80/"))
                .route(p -> p.path("/greyzeng").uri("//www.cnblogs.com/"))
                .route(p -> p.path("/error").uri("forward:/fallback"))
                .build();
}
@RequestMapping("/fallback")
public Mono<String> fallback() {
    return Mono.just("fallback");
}

啟動服務,運行 GatewayApplication.java

瀏覽器訪問://localhost:8080/jd//localhost:8080/greyzeng,會直接跳轉到對應的頁面。

輸入://localhost:8080/error,直接跳轉到自定義的/fallback請求服務中。

在轉發過程中,也可以設置一些參數,比如

    @Bean
    public RouteLocator myRoutes(RouteLocatorBuilder builder, UriConfiguration uriConfiguration) {
        final String httpUri = "//httpbin.org:80";
        return builder.routes()
                .route(p -> p.path("/get").filters(f -> f.addRequestHeader("Hello", "World")).uri(httpUri))
                .build();
    }

在請求: //localhost:8080/get 這個服務過程中,增加一個 Header 參數

第二個場景就是結合熔斷器的使用,例如:Spring Cloud Circuit Breaker,過濾來自不同的 host 請求,比如,針對來自:*.circuitbreaker.com 的請求,將其轉到統一的異常處理頁面。

    @Bean
    public RouteLocator myRoutes(RouteLocatorBuilder builder, UriConfiguration uriConfiguration) {
        String httpUri = uriConfiguration.getHttpbin();
        return builder.routes()
            
                .route(p -> p.host("*.circuitbreaker.com").filters(f -> f.circuitBreaker(config -> config.setName("mycmd").setFallbackUri("forward:/fallback"))).uri(httpUri))
                .build();
    }

通過如下程式碼進行模擬測試,

import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static org.assertj.core.api.Assertions.assertThat;


@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = {"httpbin=//localhost:${wiremock.server.port}"})
@AutoConfigureWireMock(port = 0)
public class GatewayApplicationTest {

    @Autowired
    private WebTestClient webClient;

    @Test
    public void contextLoads() {
        //Stubs
      stubFor(get(urlEqualTo("/delay/3")).willReturn(aResponse().withBody("no fallback").withFixedDelay(3000)));
      webClient.get().uri("/delay/3").header("Host", "www.circuitbreaker.com").exchange().expectStatus().isOk().expectBody().consumeWith(response -> assertThat(response.getResponseBody()).isEqualTo("fallback".getBytes()));
    }
}

簡單說明一下

訪問過程中,如果某個請求的 Host 來自於 www.circuitbreaker.com,會直接返回 /fallback 中。

如果 Host 不是 www.circuitbreaker.com,則直接返回正確結果即可。

完整程式碼

spring-cloud-gateway-usage

參考資料

Spring Cloud Gateway

Building a Gateway

重新定義 Spring Cloud 實戰

Exit mobile version