• Spring Cloud:Gateway基础知识


    简介

    SpringCloud Gateway是SpringCloud的一个全新项目,基于Spring5+springboot2+project Reactor等技术开发的网关,它旨在为微服务架构提供一中简单有效的统一的Api路由管理方式,且基于Filter链的方式提供了网关基本的功能,如安全,监控,指标,限流。
    Spring Cloud Gateway使用的webflux中的reactor-netty响应式编程组件,底层使用了Netty通讯框架。
    GateWay具有如下特性:

    • 基于Spring5+springboot2+project Reactor等技术构建。
    • 可以对路由指定Predicate(断言)和filter(过滤器)。
    • 集成Hystrix的断路器功能。
    • 集成SpringCloud服务发现功能。
    • 易于编写的Predicate(断言)和filter(过滤器);
    • 请求限流功能。
    • 支持路径重写。

    三大核心概念

    路由(Route)是构建网关的基本模块,它由ID,目标URI,一系列断言和过滤器组成,如果断言为true则匹配该路由。
    断言(Predicate),开发人员可以匹配HTTP请求中的所有内容,例如请求头或请求参数,如果请求与断言相匹配则进行路由
    过滤(Filter),指的是Spring框架中的GatewayFilter的实例,使用过滤器,可以在请求被路由前或者后对请求进行修改
    官网截图:

    核心逻辑:路由转发+执行过滤器链

    Gateway环境搭建

    yml配置方式

    pom依赖:需要移除springboot的web场景启动器,否则会报错,无法启动

            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-gateway</artifactId>
            </dependency>
    

    配置文件yml,在配置文件中配置了网关

    server:
      port: 9527
    
    spring:
      application:
        name: cloud-gateway
      cloud:
        gateway:
          routes:
            - id:  payment_routh
              uri: http://localhost:8001
              predicates:
                - Path=/payment/get/**
            - id:  payment_routh2
              uri: http://localhost:8001
              predicates:
                - Path=/payment/create
    
    eureka:
      client:
        #是否将自己注册到Eureka Server 默认为true
        register-with-eureka: true
        #是否从EurekaServer抓取已有的注册信息,默认为true,单节点无所谓,集群必须设置true才能配合ribbon做负载均衡
        fetch-registry: true
        service-url:
          #设置eureka server交互的地址查询服务和注册服务都需要依赖这个地址
          defaultZone: http://localhost:7001/eureka
      instance:
        hostname: cloud-gateway-service
    

    然后我们通过9527端口就可以访问服务了:

    编码方式配置

    新写一个Gateway配置类:

    @Configuration
    public class GatewayConfig {
    
        @Bean
        public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder){
            RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
            routes.route("path_route_wj",r->{
                //意思是访问localhost:9527/guonei,将会转发到http://news.baidu.com/guonei
                        return r.path("/guonei").uri("http://news.baidu.com/guonei");
            }).build();
            return routes.build();
        }
    }
    

    我们在浏览器输入localhost:9527/guonei并访问,观察效果:

    Gateway实现动态路由

    yml配置
    需要注意的是:uri的协议为lb,表示启用Gateway的负载均衡功能.
    lb://serverName是Spring cloud Gateway在微服务中自动为我们创建的负载均衡uri

    spring:
      application:
        name: cloud-gateway
      cloud:
        gateway:
          routes:
            - id:  payment_routh
              #uri: http://localhost:8001
              uri: lb://CLOUD-PAYMENT-SERVICE
              predicates:
                - Path=/payment/get/**
            - id:  payment_routh2
              #uri: http://localhost:8001
              uri: lb://CLOUD-PAYMENT-SERVICE
              predicates:
                - Path=/payment/create
          discovery:
            locator:
              #开启从注册中心动态创建路由的功能,利用微服务名进行路由
              enabled: true
    

    常用的断言

    当我们启动Gateway服务时,发现控制台打印了一串Predicate

    官方文档有详细说明:https://docs.spring.io/spring-cloud-gateway/docs/2.2.5.RELEASE/reference/html/#gateway-request-predicates-factories
    这里不做过多介绍。

    filter

    filter分为两种,一个是GatewayFilter,一种是GlobalFilter。

    GatewayFilter

    没啥好说的,官网写的很清楚。https://docs.spring.io/spring-cloud-gateway/docs/2.2.5.RELEASE/reference/html/#gatewayfilter-factories
    举例:

    spring:
      application:
        name: cloud-gateway
      cloud:
        gateway:
          routes:
            - id:  payment_routh
              #uri: http://localhost:8001
              uri: lb://CLOUD-PAYMENT-SERVICE
              predicates:
                - Path=/payment/get/**
                #- After=2020-09-06T21:57:48.289+08:00[Asia/Shanghai]
              filters:
                #过滤器工厂会在匹配的请求头上加上一对请求头,名称为X-Request-red值是blue
                - AddRequestHeader=X-Request-red, blue
    

    自定义全局GlobalFilter:

    需要实现两个接口,GlobalFilter和Ordered。

    @Slf4j
    @Component
    public class MyGlobalFilter implements GlobalFilter, Ordered {
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            String name = exchange.getRequest().getQueryParams().getFirst("name");
            if(StringUtils.isBlank(name)){
                log.info("非法用户");
                exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST);
                return exchange.getResponse().setComplete();
            }
            return chain.filter(exchange);
        }
    
        @Override
        public int getOrder() {
            return 0;
        }
    }
    

    运行效果:

  • 相关阅读:
    Docker下安装redis
    Goodnotes5
    Notability
    浏览器好用的技术
    苹果平板上好用的软件推荐
    苹果平板爱思助手检验安兔兔
    积分超过排名的第一天
    卸载Windows控制面板的程序和功能中找不到的一些软件的方法
    怎样在GitHub上新建一个文件夹
    Vim的常用操作
  • 原文地址:https://www.cnblogs.com/wwjj4811/p/13622633.html
Copyright © 2020-2023  润新知