您现在的位置是:首页 >技术杂谈 >【SpringCloud组件——GateWay】网站首页技术杂谈

【SpringCloud组件——GateWay】

芃仔 2024-07-01 11:59:55
简介【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。

 

 七、跨域问题处理

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。