1.引入
网关可以把它理解成坐高铁时的安检,他可以对用户做身份验证,哪些人能通过,哪些人不能通过,都由他决定,如果没有安检,那么高铁的安全性将受到打击,一个微服务没有网关,那么接口都将暴露出来,安全性大打折扣
2.作用
- 对用户的请求做身份验证,权限验证,类似于过滤器,只有符合规则的请求才能被响应
- 将用户的请求路由到微服务,并且实现负载均衡
- 对用户请求进行限流,限制访问人数
3.简单实现
网关也是微服务架构中的一环,因此就决定了它本身也是服务,所以我们要单另新建一个服务来专门作网关
项目结构:
3.1.引入依赖
XML
<!--nacos发现依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--网关gateway-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
刚刚上面说了,网关Gateway也是一个服务,所以我们也得把它放在Nacos上管理,所以要引入Nacos的发现依赖,gateway作为springcloud的一个依赖,在springcloud版本2020以上的时候,已经摒弃了ribbon这个负载均衡器,而用的是loadbalancer这个负载均衡器,所以我们得单另再引入这个的依赖,如下:
XML
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
3.2.编写配置文件
编写了网关的相关配置才能起作用,配置如下:
- id:是路由的标识,必须要是唯一
- uri:路由的目标地址,这里的lb是负载均衡的意思,后面跟的服务名称
- predicates:是断言的意思,请求只有符合断言,才能被路由
上图就是网关在整个请求访问中的作用,用户发送请求访问网关,网关通过断言来判断请求合不合法,如果合法,则通过uri从Nacos注册中心拉取服务,然后再通过负载均衡随机访问一个服务
4.过滤器工厂
在网关里存在过滤器,其作用是对路由的请求或者响应做加工处理,比如添加或者删除请求头之类的操作
spring提供了多种不同的路由过滤器工厂GatewayFilterFactory,这里我就挑一个来做个示范
4.1.编写配置
- 注意格式,What是请求头的键,后面Today Is Sunday是请求头的值,这两者缺一不可
- 我把filters的配置写在了user-service配置下边,order-service配置上边,所以只对user-service服务的请求有效,如果要对所有服务请求的添加一个请求头,可以在配置的最下面写这个filter的配置,但是有细微的变化,如下:
5.全局过滤器
之前上面讲的过滤器都是通过配置的方式来实现过滤的,这样的过滤器没办法手动更改业务逻辑,所以接下来讲一个可以在类中手动更改业务逻辑的全局过滤器GlobalFilter
5.1.添加一个过滤器类
让这个类实现GlobalFilter这个全局过滤器的接口,然后来手动编写业务逻辑
- 要实现的方法只有一个,这方法有两个参数,第一个参数是请求上下文,从请求经过网关开始到结束,这个时间段里,这个exchange一直可以被共享,用来获取请求或者响应的相关信息,第二个是用来放行过滤器的
- 下面的例子增添的业务逻辑是,看看在请求参数中authorization的值是否是author,如果是,那就放行,如果不是那就拦截
java
@Order(1)
@Component
public class AuthorizeFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//1.获取请求参数
MultiValueMap<String, String> params = exchange.getRequest().getQueryParams();
//2.获取authorization参数
String authorization = params.getFirst("authorization");
//3.校验
if ("author".equals(authorization)){
//放行
return chain.filter(exchange);
}
//4.拦截
//4.1.设置状态码401
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
//4.2.拦截请求
return exchange.getResponse().setComplete();
}
}
其中的注解也说明下,第一个@Order,是用来管理过滤器的顺序的,后面的参数越小,表示这个过滤器越早被访问到,第二个@Component,用来把这个类注册到spring中
5.2.过滤器执行顺序
到此为止,过滤器讲了有路由过滤器 ,defaultFilter ,全局过滤器,那么这三个过滤器的执行顺序是怎样的呢?
- 这里只做简单的了解,如果配置了@Order注解,那么值越小,优先级越高,如果@Order值相等,那么顺序是defaultFiltet > 路由过滤器 > 全局过滤器