Spring Cloud Gateway 入门
Spring Cloud Gateway介绍
前段时间刚刚发布了Spring Boot 2正式版,Spring Cloud Gateway基于Spring Boot 2,是Spring Cloud的全新项目,该项目提供了一个构建在Spring 生态之上的API网关,包括:Spring 5,Spring Boot 2和Project Reactor。 Spring Cloud Gateway旨在提供一种简单而有效的途径来发送API,并为他们提供横切关注点,例如:安全性,监控/指标和弹性。当前最新的版本是v2.0.0.M8,正式版最近也会到来。
Spring Cloud Gateway的特征:
- Java 8
- Spring Framework 5
- Spring Boot 2
- 动态路由
- 内置到Spring Handler映射中的路由匹配
- 基于HTTP请求的路由匹配 (Path, Method, Header, Host, etc…)
- 过滤器作用于匹配的路由
- 过滤器可以修改下游HTTP请求和HTTP响应 (Add/Remove Headers, Add/Remove Parameters, Rewrite Path, Set Path, Hystrix, etc…)
- 通过API或配置驱动
- 支持Spring Cloud DiscoveryClient配置路由,与服务发现与注册配合使用
vs Netflix Zuul
Zuul基于servlet 2.5(使用3.x),使用阻塞API。 它不支持任何长连接,如websockets。而Gateway建立在Spring Framework 5,Project Reactor和Spring Boot 2之上,使用非阻塞API。 Websockets得到支持,并且由于它与Spring紧密集成,所以将会是一个更好的开发体验。
Spring Cloud Gateway入门实践
笔者最近研读了Spring Cloud Gateway的源码,大部分功能的实现也写了源码分析的文章,但毕竟正式版没有发布,本文算是一篇入门实践,展示常用的几个功能,期待最近的正式版本发布。
示例启动两个服务:Gateway-Server和user-Server。模拟的场景是,客户端请求后端服务,网关提供后端服务的统一入口。后端的服务都注册到服务发现Consul(搭建zk,Eureka都可以,笔者比较习惯使用consul)。网关通过负载均衡转发到具体的后端服务。
用户服务
用户服务注册到Consul上,并提供一个接口/test。
依赖
需要的依赖如下:
org.springframework.cloud spring-cloud-starter-consul-discoveryorg.springframework.boot spring-boot-starter-web
配置文件
spring: application: name: user-service cloud: consul: host: 192.168.1.204 port: 8500 discovery: ip-address: ${HOST_ADDRESS:localhost} port: ${SERVER_PORT:${server.port}} healthCheckPath: /health healthCheckInterval: 15s instance-id: user-${server.port} service-name: userserver: port: 8005management: security: enabled: false
暴露接口
@SpringBootApplication@RestController@EnableDiscoveryClientpublic class GatewayUserApplication { public static void main(String[] args) { SpringApplication.run(GatewayUserApplication.class, args); } @GetMapping("/test") public String test() { return "ok"; }}
暴露/test接口,返回ok即可。
网关服务
网关服务提供多种路由配置、路由断言工厂和过滤器工厂等功能。
依赖
需要引入的依赖:
org.springframework.boot spring-boot-actuator//依赖于webflux,必须引入org.springframework.boot spring-boot-starter-webfluxorg.springframework.cloud spring-cloud-gateway-core//服务发现组件,排除web依赖org.springframework.cloud spring-cloud-starter-consul-discovery 2.0.0.M6org.springframework.boot spring-boot-starter-web //kotlin依赖org.jetbrains.kotlin kotlin-stdlib ${kotlin.version}trueorg.jetbrains.kotlin kotlin-reflect ${kotlin.version}true
如上引入了kotlin相关的依赖,这里需要支持kotlin的路由配置。Spring Cloud Gateway的使用需要排除web相关的配置,引入的是webflux的引用,应用启动时会检查,必须引入。
路由断言工厂
路由断言工厂有多种类型,根据请求的时间、host、路径、方法等等。如下定义的是一个基于路径的路由断言匹配。
@Beanpublic RouterFunction testFunRouterFunction() { RouterFunction route = RouterFunctions.route( RequestPredicates.path("/testfun"), request -> ServerResponse.ok().body(BodyInserters.fromObject("hello"))); return route;}
当请求的路径为/testfun时,直接返回ok的状态码,且响应体为hello字符串。
过滤器工厂
网关经常需要对路由请求进行过滤,进行一些操作,如鉴权之后构造头部之类的,过滤的种类很多,如增加请求头、增加请求参数、增加响应头和断路器等等功能。
@Beanpublic RouteLocator customRouteLocator(RouteLocatorBuilder builder, ThrottleGatewayFilterFactory throttle) { //@formatter:off return builder.routes() .route(r -> r.path("/image/webp") .filters(f -> f.addResponseHeader("X-AnotherHeader