在微服务架构中,一个系统往往由多个微服务组成,而这些服务可能部署在不同机房、不同地区、不同域名下。这种情况下,客户端想要直接请求这些服务,就需要知道它们具体的地址信息,例如 IP 地址、端口号等。这时就需要用到GateWay服务网关。
Spring Cloud Gateway旨在提供一种简单而有效的方法来路由到API,并为它们提供跨领域关注点,例如:安全性,监控/指标和弹性。Spring Cloud Gateway 是基于 WebFlux 框架实现的,使用的是Reactor-Netty响应组件,而 WebFlux 框架底层则使用了高性能的 Reactor 模式通信框架 Netty。
Spring Cloud Gateway 的目标是提供统一的路由方式且基于Filter链的方式提供了网关基本功能,例如:安全,监控/指标和限流。
路由Route
网关最基本的模块。它由一个 ID、一个目标 URI、一组断言(Predicate)和一组过滤器(Filter)组成。
默认情况下,Spring Cloud Gateway 会根据服务注册中心中维护的服务列表,以服务名(spring.application.name)作为路径创建动态路由进行转发,从而实现动态路由功能。
断言Predicate
断言是路由转发的判断条件,可以通过 Predicate 对 HTTP 请求进行匹配,例如请求方式、请求路径、请求头、参数等,如果请求与断言匹配成功,则将请求转发到相应的服务。
Spring Cloud Gateway 通过 Predicate 断言来实现 Route 路由的匹配规则。简单点说,Predicate 是路由转发的判断条件,请求只有满足了 Predicate 的条件,才会被转发到指定的服务上进行处理。
过滤Filter
过滤器,我们可以使用它对请求进行拦截和修改,还可以使用它对上文的响应进行再处理。
通常情况下,出于安全方面的考虑,服务端提供的服务往往都会有一定的校验逻辑,例如用户登陆状态校验、签名校验等。
在微服务架构中,系统由多个微服务组成,所有这些服务都需要这些校验逻辑,此时我们就可以将这些校验逻辑写到 Spring Cloud Gateway 的 Filter 过滤器中。
搭建spring cloud项目
创建maven子模块,命名为cloud-gateway9527
①导入依赖
<dependencies> <dependency> <groupId>org.springframework.cloudgroupId> <artifactId>spring-cloud-starter-gatewayartifactId> dependency> <dependency> <groupId>org.springframework.cloudgroupId> <artifactId>spring-cloud-starter-consul-discoveryartifactId> dependency> dependencies>②创建application.yml配置文件,设置路由router,断言predicate参数
server: port: 9527 spring: application: name: cloud-gateway cloud: consul: #consul注册中心配置 discovery: service-name: ${spring.application.name} hostname: localhost port: 8500 gateway: discovery: #允许服务发现 locator: enabled: true routes: #配置路由 - id: cloud-provider-1 #路由id自定义,必须唯一 uri: lb://cloud-provider #lb(负载均衡)://注册到注册中心的服务提供者的昵称 predicates: #断言(相关内容:https://www.jianshu.com/p/966abedb7e57) - Path=/provider/** #访问路径匹配③创建启动类
@EnableDiscoveryClient @SpringBootApplication public class Gateway9527 { public static void main(String[] args) { SpringApplication.run(Gateway9527.class, args); } }④创建GatewayLog类,简单实现过滤器filter功能(必须实现GlobalFilter, Ordered接口才能实现)
@Component public class GatewayLog implements GlobalFilter, Ordered { //过滤逻辑 @Override public Monofilter(ServerWebExchange exchange, GatewayFilterChain chain) { MultiValueMapparams = exchange.getRequest().getQueryParams(); System.out.println(params); return chain.filter(exchange); } //加载优先级 @Override public int getOrder() { return 0; } }测试
①启动注册中心
②依次启动provider8001,provider8002,provider8003
③启动gateway9527网关
④访问http://localhost:9527/provider/getUUID?num=1
⑤查看gateway9527控制台日志