Spring Cloud作为Spring Cloud官方推荐的第二代框架,取代Zuul网关。网关作为流量控制,在微服务架构当中有非常重要的作用。网关常用的功能有路由转发、权限校验和限流控制等。
本案例来源于官网,在官网的基础之上进行实现。
本篇文章需要父项目(spring-cloud-brimen-gateway)和子工程(spring-cloud-gateway-first),关于父项目的创建过程以及相关依赖不再赘述,请查看 第二章 Spring Cloud 服务的注册与发现(Eureka Server)
创建一个普通的Spring Boot工程,并命名为:spring-cloud-gateway-first
4.0.0
com.brimen
spring-cloud-brimen-gateway
1.0-SNAPSHOT
com.brimen
spring-cloud-gateway-first
0.0.1-SNAPSHOT
spring-cloud-gateway-first
Spring Cloud GateWay 初体验
org.springframework.cloud
spring-cloud-starter-gateway
org.springframework.boot
spring-boot-maven-plugin
Spring Cloud 使用RouteLocatorBuilder 进行路由转发,将请求进行处理,最后转发到下游目标服务当中去,本案例转发到
http://httpbin.org:80 ,在转发的过程当中,添加了Header,key为Hello,value为World。
RouteLocatorBuilder不仅能够进行路由转发,还可以添加各种predicates和filters,predicates定义各种请求规则,满足规则的前提下,再去由router去处理。而filters用于过滤请求,可以添加各种判断,做各种拦截,例如权限校验。
package com.brimen.springcloudgatewayfirst;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class SpringCloudGatewayFirstApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudGatewayFirstApplication.class, args);
}
@Bean
public RouteLocator myRoutes(RouteLocatorBuilder builder) {
return builder.routes()
.route(p -> p
.path("/get")
.filters(f -> f.addRequestHeader("Hello", "World"))
.uri("http://httpbin.org:80"))
.build();
}
}
从图中结果我们可以看到,当我们请求接口/get时,服务将请求转发到了 httpbin.org ,在转发之前,加了一个filter,filter添加了一个header,header的key为Hello,value为World。
本功能是以上面的工程为基础实现的。
Spring Cloud GateWay当中可以使用Hystrix,Hystrix是Spring Cloud当中熔断降级的一个组件,在微服务架构系统当中非常的重要,Hystrix是Spring Cloud当中以filter的形式使用的,代码如下:
package com.brimen.springcloudgatewayfirst;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
@SpringBootApplication
@RestController
public class SpringCloudGatewayFirstApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudGatewayFirstApplication.class, args);
}
@Bean
public RouteLocator myRoutes(RouteLocatorBuilder builder) {
String httpUri = "http://httpbin.org:80";
return builder.routes()
.route(p -> p
.path("/get")
.filters(f -> f.addRequestHeader("Hello", "World"))
.uri(httpUri))
.route(p -> p
.host("*.hystrix.com")
.filters(f -> f
.hystrix(config -> config
.setName("mycmd")
.setFallbackUri("forward:/fallback")))
.uri(httpUri))
.build();
}
@RequestMapping("/fallback")
public Mono fallback() {
return Mono.just("fallback");
}
}
在上面的代码当中,我们使用了另一个路由,该路由使用host断言是否进入该路由,当请求的host有“*.hystrix.com”时,都有进入该路由,该路由当中有一个filter,filter当中可以配置name和fallback的指向性地址,当满足条件,会调用/fallback方法。
使用curl命令,如下:
curl --dump-header - --header 'Host: www.hystrix.com' http://localhost:8080/delay/3