SpringCloud 网关 - GateWay详解
官网地址:https://spring.io/projects/spring-cloud-gateway概括简介Cloud全家桶中有个很重要的组件就是网关,在1.x版本中都是采用Zuul网关;但是在2.x版本中,zuul的升级迟迟未更新,Spring Cloud最后自己研发了一个网关代替zuul, 那就是Spring Cloud GateWayGateWay基本介绍网关在微服务系统架构的位...
官网地址:https://spring.io/projects/spring-cloud-gateway
概括简介
Cloud全家桶中有个很重要的组件就是网关,在1.x版本中都是采用Zuul网关;但是在2.x版本中,zuul的升级迟迟未更新,Spring Cloud最后自己研发了一个网关代替zuul, 那就是Spring Cloud GateWay
GateWay基本介绍
网关在微服务系统架构的位置如下图:
以下是来自官网的翻译:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.2.RELEASE/reference/html/
Spring Cloud GateWay 是基于WebFlux框架 ,使用Reactor模式, 而WebFlux框架底层使用的Netty.
GateWay源码架构:
GateWay作用
- 反向代理
- 鉴权
- 流量控制
- 熔断
- 日志监控
- …
微服务网关所处的位置
zuul 和 gateway 各自特点和区别
SpringCloud GateWay 特征
SpringCloud GateWay 和 Zuul 区别
Zuul1.x模型
Spring Cloud集成Zuul1版本,采用的是Tomcat容器,使用的是传统的Servlet IO处理模型。
Servlet由Servlet container进行生命周期管理,
#### GateWay 模型
Spring Cloud GateWay 是基于WebFlux框架 ,使用Reactor模式, 而WebFlux框架底层使用的Netty
GateWay三大核心概念
Route(路由)
路由是构建网关 的基本模块,它有ID,目标URI,一系列的断言过滤器组成,如果断言为true则配备该路由
Predicate(断言)
Filter(过滤)
Filter 指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求前或者之后对请求进行修改
GateWay三大核心示意图
GateWay 工作流程
官网的工作流程图:
GateWay核心逻辑:路由转发 + 执行过滤器链
GateWay入门配置
-
新建一个springboot模块:springcloud-gateway9527
-
添加依赖
<!--gateway--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <!--eureka-client--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
-
yml配置文件添加配置
server: port: 9527 spring: application: name: cloud-gateway cloud: gateway: # 路由集合 routes: - id: payment_routh #payment_route #路由的ID,没有固定规则但要求唯一,建议配合服务名 uri: http://localhost:8003 #匹配后提供服务的路由地址 predicates: - Path=/payment/get/** # 断言,路径相匹配的进行路由 - id: payment_routh2 #payment_route #路由的ID,没有固定规则但要求唯一,建议配合服务名 uri: http://localhost:8002 #匹配后提供服务的路由地址 predicates: - Path=/order/getPaymenttimeoutById/** # 断言,路径相匹配的进行路由 #- After=2020-02-21T15:51:37.485+08:00[Asia/Shanghai] #- Cookie=username,zzyy #- Header=X-Request-Id, \d+ # 请求头要有X-Request-Id属性并且值为整数的正则表达式 eureka: instance: hostname: cloud-gateway-service client: #服务提供者provider注册进eureka服务列表内 service-url: register-with-eureka: true fetch-registry: true defaultZone: http://localhost:7001/eureka
-
主启动类
@EnableEurekaClient @SpringBootApplication public class SpringcloudGateway9527Application {
启动测试:
通过gateway网关 访问 8003 端口的微服务成功
GateWay动态路由
通过微服务名实现动态路由
默认情况下Gateway 会根据注册中心注册的服务列表,以注册中心上的微服务名为路径创建动态路由进行转发,从而实现动态路由功能(能负载均衡)
路由配置修改(负载均衡)
-
我们只需要修改YML配置文件
-
需要注意的是uri的协议为lb,表示启用Gateway的负载均衡功能。
lb://serviceName
-
gateway在微服务中自动为我们创建负载均衡uri
注意:注意添加
discovery.locator.enabled=true
表示开启从注册中心动态创建路由的功能,利用微服务名进行路由
或者在主启动类加上@EnableDiscoveryClient
表示开启服务注册和发现
@EnableDiscoveryClient
@SpringBootApplication
public class FyjmallGatewayApplication {
uri: lb://cloud-payment-service
表示匹配后提供服务的路由地址, cloud-payment-service是注册中心上的微服务名
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
# 路由集合
routes:
- id: payment_routh #payment_route #路由的ID,没有固定规则但要求唯一,建议配合服务名
uri: lb://cloud-payment-service #匹配后提供服务的路由地址
# uri: http://localhost:8003 #匹配后提供服务的路由地址
predicates:
- Path=/payment/get/** # 断言,路径相匹配的进行路由
- id: payment_routh2 #payment_route #路由的ID,没有固定规则但要求唯一,建议配合服务名
uri: lb://cloud-payment-service #匹配后提供服务的路由地址
# uri: http://localhost:8002 #匹配后提供服务的路由地址
predicates:
- Path=/order/getPaymenttimeoutById/** # 断言,路径相匹配的进行路由
路由先后顺序
路由断言匹配 是按照 配置的先后顺序的,如果路由配置断言匹配先匹配上,那么久进行路由,接下来的路由就不会走了
以上配置就能实现动态路由,实现负载均衡的功能
GateWay Predicate(断言)
我们先看上面我们的配置,如下图红框总的predicate配置,表示对路径进行配,如果路径匹配成功就进行路由,匹配不成功就不进行路由,相当于进行的断言判断
官网Predicate配置,官网地址:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.2.RELEASE/reference/html/#gateway-request-predicates-factories
官网配置截图:
常用的 Route Predicate:
对应的在yml配置:
注意predicates: 下面可以配置多个断言规则如下图:
更多Predicate配置请参考官网
GateWay 过滤器(Filter)
- GateWay Filter 只能在业务逻辑之前,和业务逻辑之后
- GateWay Filter 种类分为 单一的 GateWayFilter 和全局的 GlobalFilter
官网的GateWay Filter有很多,具体可以参考官网:
单一GateWay Filter配置如下截图:
注意 AddRequestParameter 参数表示添加请求参数,还有许多这样的参数配置,请参考官网。
自定义全局过滤器
自定义过滤器要实现2个接口,GlobalFilter,Ordered
主要能够实现全局日志记录,统一网关鉴权等…
案例代码:
@Component
public class MyGlobalFilter implements GlobalFilter,Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String username = exchange.getRequest().getQueryParams().getFirst("username");
if (username == null) {
exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
return exchange.getResponse().setComplete();
}
// 放行
return chain.filter(exchange);
}
// 表示排名
@Override
public int getOrder() {
return 0;
}
}
测试:
-
请求带有参数username,可以成功访问
-
请求没有带有参数username,无法访问
-
或者参数
总结:
通过以上案例,我们可以自己定义全局GlobalFilter,对请求进行过滤,可以根据我们自己的定义的规则来过滤每一个请求
更多推荐
所有评论(0)