您现在的位置是:首页 >技术杂谈 >【SpringCloud组件——GateWay】网站首页技术杂谈
【SpringCloud组件——GateWay】
前言:
在我们之前所用的Nacos和Feign以及Eureka,这些组件都是用与系统内部之间进行互相访问的,但是当用户访问系统时,我们没有采取任何措施,举个例子:系统管理员可以访问哪些接口并具备哪些操作权限,普通用户又可以访问哪些接口以及访问权限。这些我们都是没有做限制的,因此,我们需要一个组件来对访问的请求进行一些处理,这就可以使用我们接下来要讲的GateWay了。
一、网关(GateWay)的作用
1、身份认证和权限校验
对用户的身份信息以及操作权限进行校验。
2、服务路由、负载均衡
将用户发送的请求路由到某个微服务,如果该微服务存在多个实例,路由时就会采用负载均衡。
3、请求限流
当请求过载时,就会限制请求的路由量。
二、GateWay搭建
1、导入依赖
<!--gateway网关依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- nacos客户端依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
2、编写路由配置及Nacos地址
server:
port: 10010
spring:
application:
name: gateway
cloud:
nacos:
server-addr: localhost:80
gateway:
routes: #配置路由规则
- id: user-service #路由标识,必须唯一
uri: lb://userservice #路由的目标地址 lb表示loadBalance(负载均衡)
predicates: #路由断言,判断请求是否符合规则
- Path=/user/** #判断路径是否是以/user开头,如果是则符合
- id: order-service
uri: lb://orderservice
predicates:
- Path=/order/**
3、启动微服务,查看Nacos控制台微服务实例详细信息
我们启动了三个userService实例和一个orderService实例。
4、通过网关访问微服务系统
4.1、浏览器输入地址:
http://localhost:10010/user/1
http://localhost:10010/order/101
4.2、查看页面响应:
4.3、查看系统后台控制台信息
我们分别输入用户id为1、2、3,访问三次,查看控制台信息得知,此时gateway的负载均衡采用的是随机规则,即将请求随机发送给某服务的某个实例。
4.4、流程图
4.5、总结
三、路由断言工厂
1、Spring当中为我们提供的断言规则有哪些
2、案例演示(Before和After)
2.1、order-service断言配置
- id: order-service
uri: lb://orderservice
predicates:
- Path=/order/**
- Before=2031-04-13T15:14:47.433+08:00[Asia/Shanghai]
2.2、user-service断言配置
- id: user-service #路由标识,必须唯一
uri: lb://userservice #路由的目标地址
predicates: #路由断言,判断请求是否符合规则
- Path=/user/** #判断路径是否是以/user开头,如果是则符合
- After=2031-04-13T15:14:47.433+08:00[Asia/Shanghai]
2.3、浏览器测试
系统测试时间:
(1)order-service
(2)user-service
(3)结论
断言规则After表示,请求访问时间是否在此时间之后,如何是,则允许请求路由到微服务实例当中进行处理,否则404.
断言规则Before表示,请求访问时间是否在此时间之前,如果是,则允许请求路由到微服务实例当中进行处理,否则404.
3、总结
四、路由过滤器(GatewayFilter)
1、路由过滤器的作用
用户发送的请求,首先会抵达网关,网关并不会直接将请求路由到对应的微服务当中去执行,而是将请求传递给过滤器,由过滤器对请求做出一系列处理之后才转发到微服务当中,同理,微服务处理完请求后也不会直接将响应传递到路由上,也是经过一系列过滤器之后才抵达路由,由路由对用户的访问进行响应。
2、如何实现
案例一(局部——添加请求头信息):
(userService)网关配置:
- id: user-service #路由标识,必须唯一 uri: lb://userservice #路由的目标地址 predicates: #路由断言,判断请求是否符合规则 - Path=/user/** #判断路径是否是以/user开头,如果是则符合 filters: - AddRequestHeader=Truth,ZYP IS SO aowsome!
userController代码调整:
@GetMapping("/{id}") public User queryById(@PathVariable("id") Long id, @RequestHeader(value = "Truth",required = false) String truth) { System.out.println(truth + ">>>>>>>>>>>>>>>>"); return userService.queryById(id); }
效果验证:
案例二(全局——添加请求头信息):
全局网关配置:
gateway: routes: #配置路由规则 - id: user-service #路由标识,必须唯一 uri: lb://userservice #路由的目标地址 predicates: #路由断言,判断请求是否符合规则 - Path=/user/** #判断路径是否是以/user开头,如果是则符合 - id: order-service uri: lb://orderservice predicates: - Path=/order/** default-filters: - AddRequestHeader=Truth,My mother holds a special place in my heart.
效果验证:
五、全局过滤器(GlobalFilter)
全局过滤器是对路由过滤器功能的一种补充和扩展。
@Component
@Order(0)//过滤器的顺序,越小优先级越高
public class AuthorizeFilter implements GlobalFilter{
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//1.获取请求参数
ServerHttpRequest request = exchange.getRequest();
MultiValueMap<String,String> params = request.getQueryParams();
//2.获取参数中的authorization参数
String value = params.getFirst("authorization");
//3.判断参数值是否为admin
if (value.equals("admin")){
//4.是就放行
//chain是过滤器链,调这个方法类似于找到这个过滤器的下一个过滤器,调用他的filter方法
return chain.filter(exchange);
}else {
//5.否就拦截
//5.1、设置状态码
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
//5.2、拦截请求
return exchange.getResponse().setComplete();
}
}
}
效果测试:
总结:
六、过滤器链的执行顺序
路由过滤器、DefaultFilter、GlobalFilter。