一、认识网关
我们在开发微服务时,每个微服务都有不同的地址或端口,入口不同前端联调的时候发现了一些问题。请求不同数据时要访问不同的入口,需要维护多个入口地址,相当麻烦
1.1、什么是网关
顾明思议,网关就是网络的关口。数据在网络间传输,从一个网络传输到另一网络时就需要经过网关来做数据的路由和转发以及数据安全的校验。 通俗来说,网关就像是一个“门卫大爷”,
- 外面的人要想进入园区,必须经过大爷的认可,如果你是不怀好意的人,肯定被直接拦截。
- 外面的人要传话或送信,要找大爷。大爷帮你带给目标人。
现在,微服务网关就起到同样的作用。前端请求不能直接访问微服务,而是要请求网关 :
-
网关可以做安全控制,也就是登录身份校验,校验通过才放行
-
通过认证后,网关再根据请求判断应该访问哪个微服务,将请求转发过去
在SpringCloud当中,提供了两种网关实现方案:
-
Netflix Zuul:早期实现,目前已经淘汰
-
SpringCloudGateway:基于Spring的WebFlux技术,完全支持响应式编程,吞吐能力更强
SpringCloudGateway官网
1.2、快速入门
由于网关本身也是一个独立的微服务,因此也需要创建一个模块开发功能。大概步骤如下:
- 创建网关微服务
- 引入SpringCloudGatewat、NacosDiscovery依赖
- 编写启动类
- 配置网关路由
1.2.1、创建项目
1.2.2、引入依赖
<!--网关--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><!--nacos discovery--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--负载均衡--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency>
注意:如果没有启动类则创建启动类
1.2.3、配置路由
在resources
目录新建一个application.yaml
文件,内容如下:
server:port: 8080 #网关的端口号
spring:application:name: gateway cloud:nacos:server-addr: 192.168.150.101:8848 #nacos的地址gateway:routes:- id: item # 路由规则id,自定义,唯一uri: lb: //item-service # 路由的目标服务,lb代表负载均衡,会从注册中心拉取服务列表predicates: # 路由断言,判断当前请求是否符合当前规则,符合则路由到目标服务- Path=/items/**,/search/** # 这里是以请求路径作为判断规则- id: carturi: lb://cart-servicepredicates:- Path=/carts/**
启动启动启动类以http://localhost:8080请求发现相关功能都可以正常访问了
item端口号为8081,而网关把请求路由到了商品服务
1.3、路由过滤
网关路由对应的Java类型是RouteDefinition,其中常见属性
- id : 路由唯一指定
- uri : 路由目标地址
- predicates : 路由断言,判断请求是否满足路由条件
- filters : 路由过滤器,对请求或响应做特色处理
1.3.1、路由断言(predicates)
spring提供了12种基本的RoutePredicateFactory实现:
名称 | 说明 | 示例 |
---|---|---|
After | 是某个时间点后的请求 | - After=2037-01-20T17:42:47.789-07:00[America/Denver] |
Before | 是某个时间点之前的请求 | - Before=2031-04-13T15:14:47.433+08:00[Asia/Shanghai] |
Between | 是某两个时间点之前的请求 | - Between=2037-01-20T17:42:47.789-07:00[America/Denver], 2037-01-21T17:42:47.789-07:00[America/Denver] |
Cookie | 请求必须包含某些cookie | - Cookie=chocolate, ch.p |
Header | 请求必须包含某些header | - Header=X-Request-Id, \d+ |
Host | 请求必须是访问某个host(域名) | - Host=**.somehost.org,**.anotherhost.org |
Method | 请求方式必须是指定方式 | - Method=GET,POST |
Path | 请求路径必须符合指定规则 | - Path=/red/{segment},/blue/** |
Query | 请求参数必须包含指定参数 | - Query=name, Jack或者- Query=name |
RemoteAddr | 请求者的ip必须是指定范围 | - RemoteAddr=192.168.1.1/24 |
weight | 权重处理 |
1.3.1、路由过滤器(filters)
网关提供了33种过滤器,每种都有各自独特的作用
名称 | 说明 | 示例 |
---|---|---|
AddRequestHeader | 给当前请求添加一个请求头 | AddrequestHeader=headerName,headerValue |
RemoveRequestHeader | 移除请求中的一个请求头 | RemoveRequestHeader=headerName |
AddResponseHeader | 给响应结果中添加一个响应头 | AddResponseHeader=headerName,headerValue |
RemoveResponseHeader | 从响应结果中移除有一个响应头 | RemoveResponseHeader=headerName |
RewritePath | 请求路径重写 | RewritePath=/red/?(?<segment>.*),/${segment} |
StripPrefix | 去除请求路径中的N段前缀 | StripPrefix=1,则路径/a/b转发时只保留/b |
…… |
1.4、练习
接下来我们尝试添加一个请求头:
鼠标放在routers上按住Ctrl左键点进去
点进来之后我们发现是一个集合,集合当中的类型是RouteDefinition路由定义
鼠标再进RouteDefinition就进入了属性类了.我们就找到了源码
在routes下添加以下代码
在Controller下使用springMvc提供的注解@RequestHeader获取请求头并输出
运行之后我们可以看到拿到了请求头数据
以上的配置只在一个微服务有效如果想要在所有的微服务都能使用则在routes配置的同级下添加default-filters如: