Spring Cloud Gateway 使用示例
- 2022 年 11 月 19 日
- 筆記
- spring, Spring Cloud
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>
程式碼說明
第一個場景就是請求轉發,例如
直接轉到://jd.com:80/jd
直接轉到://www.cnblogs.com/greyzeng
直接跳轉到自定義的一個錯誤頁面。
只需要做如下配置即可
@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,則直接返回正確結果即可。