Spring Cloud Gateway 使用示例
作者: Grey
原文地址:
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>
代码说明
第一个场景就是请求转发,例如
直接转到:http://jd.com:80/jd
请求:http://localhost:8080/greyzeng
直接转到:http://www.cnblogs.com/greyzeng
请求:http://localhost:8080/error
直接跳转到自定义的一个错误页面。
只需要做如下配置即可
@Bean public RouteLocator myRoutes(RouteLocatorBuilder builder, UriConfiguration uriConfiguration) { return builder.routes() .route(p -> p.path("/jd").uri("http://jd.com:80/")) .route(p -> p.path("/greyzeng").uri("http://www.cnblogs.com/")) .route(p -> p.path("/error").uri("forward:/fallback")) .build(); } @RequestMapping("/fallback") public Mono<String> fallback() { return Mono.just("fallback"); }
启动服务,运行 GatewayApplication.java
浏览器访问:http://localhost:8080/jd 和 http://localhost:8080/greyzeng,会直接跳转到对应的页面。
输入:http://localhost:8080/error,直接跳转到自定义的/fallback
请求服务中。
在转发过程中,也可以设置一些参数,比如
@Bean public RouteLocator myRoutes(RouteLocatorBuilder builder, UriConfiguration uriConfiguration) { final String httpUri = "http://httpbin.org:80"; return builder.routes() .route(p -> p.path("/get").filters(f -> f.addRequestHeader("Hello", "World")).uri(httpUri)) .build(); }
在请求: http://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=http://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,则直接返回正确结果即可。