Day187.zuul路由网关、Gateway新一代网关 -SpringCloud

SpringCloud

十一、zuul路由网关

zuul核心人员走了两个,zuul2的研发过久,spring公司等不及,自己研发的Gateway网关。

zuul路由网关,阳哥没讲,跳过,没笔记。
https://github.com/Netflix/zuul/wiki


十二、Gateway新一代网关

https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/

简介

在这里插入图片描述
在这里插入图片描述


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


在这里插入图片描述
在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


三大核心概念


Route(路由)

在这里插入图片描述


Predicate(断言)

在这里插入图片描述


Filter(过滤)

在这里插入图片描述


总体

先根据断言条件找到指定的微服务,再路由转发,过滤可以在路由转发前或转发后加一些自己的东西

在这里插入图片描述
在这里插入图片描述


Gateway工作流程

官网总结
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


以上学过来 原理很相似SpringMvc

入门配置

  1. 新建模块cloud-gateway-gateway9527

  2. pom

    gateway 不能带spring-boot-starter-web

    <dependencies>
        <!--gateway-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
    
        <!-- 引用自己定义的api通用包,可以使用Payment支付Entity -->
        <dependency>
            <groupId>com.achang.springcloud</groupId>
            <artifactId>cloud-api-common</artifactId>
            <version>${project.version}</version>
        </dependency>
        <!--eureka client(通过微服务名实现动态路由)-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!--热部署-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    
  3. yml

    server:
      port: 9527
    
    spring:
      application:
        name: cloud-gateway
    
    eureka:
      instance:
        hostname: cloud-gateway-service
      client:
        fetch-registry: true
        register-with-eureka: true
        service-url:
          #单机版
          defaultZone: http://localhost:7001/eureka
          #集群版
    #      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka,http://eureka7003.com:7003/eureka
    
  4. 主启动类GatewayMain9527

    @SpringBootApplication
    @EnableEurekaClient
    public class GatewayMain9527 {
          
          
        public static void main(String[] args) {
          
          
            SpringApplication.run(GatewayMain9527.class,args);
        }
    }
    
  5. 修改yml文件
    在这里插入图片描述
    在这里插入图片描述

    server:
      port: 9527
    
    spring:
      application:
        name: cloud-gateway
      cloud:
        gateway:
          routes:
            - id: payment_route # 路由的id,没有规定规则但要求唯一,建议配合服务名
              #匹配后提供服务的路由地址
              uri: http://localhost:8001
              predicates:
                - Path=/payment/get/** # 断言,路径相匹配的进行路由
    
            - id: payment_route2
              uri: http://localhost:8001
              predicates:
                - Path=/payment/lb/** #断言,路径相匹配的进行路由
    
    eureka:
      instance:
        hostname: cloud-gateway-service
      client:
        fetch-registry: true
        register-with-eureka: true
        service-url:
          defaultZone: http://eureka7001.com:7001/eureka/
    
  6. 测试,启动7001,cloud-provider-payment8001,9527
    在这里插入图片描述
    在这里插入图片描述
    http://localhost:8001/payment/get/1


    在这里插入图片描述
    http://localhost:9527/payment/get/1
    在这里插入图片描述

    渐渐淡化了真是地址,通过网关端口访问

    服务器设置防火墙把8001墙了,只开放网关端口就好啦呀


Gateway网关路由的两种配置方式

  1. 在配置文件中配置
    在配置文件yml中配置(上面通过yaml文件配置)

  2. 在配置类中配置
    代码中注入RouteLocator的Bean(下面通过编码进ioc容器中配置)

    在这里插入图片描述
    在这里插入图片描述
    新建config.GatewayConfig

    @Configuration
    public class GatewayConfig {
          
          
    
        @Bean
        public RouteLocator CustomRouteLocator(RouteLocatorBuilder routeLocatorBuilder){
          
          
            RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
    
            routes.route("path_route_achang"
                    ,r -> r.path("/guonei")
                            .uri("http://news.baidu.com/guonei"))
                    .build();
                    //现在访问localhost:9527/guonei 会被转发到 http://news.baidu.com/guonei
    
            return routes.build();
        }
    
        
        @Bean
        public RouteLocator CustomRouteLocator2(RouteLocatorBuilder routeLocatorBuilder){
          
          
            RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
            
            routes.route("path_route_achang"
                    ,r -> r.path("/guoji")
                            .uri("http://news.baidu.com/guoji"))
                    .build();
            //现在访问localhost:9527/guonei 会被转发到 http://news.baidu.com/guoji
            return routes.build();
        }
    
    }
    
    // 测试结果:buld可以不加
    

yaml配置与编码的对比

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uewfVdxV-1612882122460)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20210209124801558.png)]

测试,启动7001,8001,9527
http://localhost:9527/guonei
在这里插入图片描述
http://localhost:9527/guoji
在这里插入图片描述


通过微服务名实现动态路由

在这里插入图片描述
修改yml文件

server:
  port: 9527

spring:
  application:
    name: cloud-gateway

==========================================================================

  cloud:
    gateway:
      discovery:
        locator:
          enabled: true  #开启从注册中心动态创建路由的功能,利用微服务名称进行路由(默认false)

      routes:
        - id: payment_route # 路由的id,没有规定规则但要求唯一,建议配合服务名
          #匹配后提供服务的路由地址
#          uri: http://localhost:8001
          uri: lb://cloud-payment-service # lb代表从注册中心获取服务
          predicates:
            - Path=/payment/get/** # 断言,路径相匹配的进行路由

        - id: payment_route2
#          uri: http://localhost:8001
          uri: lb://cloud-payment-service
          predicates:
            - Path=/payment/lb/** #断言,路径相匹配的进行路由

=======================================================================

eureka:
  instance:
    hostname: cloud-gateway-service
  client:
    fetch-registry: true
    register-with-eureka: true
    service-url:
      #单机版
      defaultZone: http://eureka7001.com:7001/eureka/
      #集群版
      #defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka,http://eureka7003.com:7003/eureka

enabled默认false
在这里插入图片描述

测试,启动7001,8001,8002,9527
http://localhost:9527/payment/lb
在这里插入图片描述
在这里插入图片描述


Predicate的使用

在这里插入图片描述
官网:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#gateway-request-predicates-factories
在这里插入图片描述

在这里插入图片描述

常用的Route Predicate

在这里插入图片描述


After/Before/Between

新建测试类T2

public class T2 {
    
    
    public static void main(String[] args) {
    
    
        //获取当前时间串
        ZonedDateTime zdt = ZonedDateTime.now();//默认时区
        System.out.println(zdt);
        // 2021-02-09T14:13:15.803+08:00[Asia/Shanghai]
    }

}

然后在yml中的predicates:加上

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xUrIfxde-1612882122464)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20210209142740946.png)]

			#指定时间后才能访问(After)时间往后写一小时
            - After=2021-02-09T14:13:15.803+08:00[Asia/Shanghai]

测试,启动7001,8001,8002,9527
http://localhost:9527/payment/lb
在这里插入图片描述

Before和Between作用一样:

			#指定时间前才能访问(Before)
            - Before=2021-02-10T15:13:15.803+08:00[Asia/Shanghai]
            #指定时间内才能访问(Between)
            - Between=2021-02-09T13:13:15.803+08:00[Asia/Shanghai],2021-02-10T15:13:15.803+08:00[Asia/Shanghai]

Cookie

在这里插入图片描述
在这里插入图片描述
在yml中的predicates:加上(记得把after的时间改成已经过去的时间,时间没到访问不了)

          - Cookie=username,achang   #带Cookie,并且username的值为angenin
  1. 不带cookie访问
    打开cmd终端,输入curl http://localhost:9527/payment/lb(直接访问失败)
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-idn9S4S7-1612882122468)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20210209220339790.png)]

  2. 带cookie访问
    输入curl http://localhost:9527/payment/lb --cookie "username=achang"
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ETYyx5fj-1612882122471)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20210209220700323.png)]


Header

在这里插入图片描述
在这里插入图片描述
注释掉其他两个,加上Header

#            - After=2020-06-17T12:53:40.325+08:00[Asia/Shanghai]
#            - Cookie=username,achang   #带Cookie,username的值为achang
            - Header=X-Request-Id, \d+   #请求头要有 X-Request-Id属性并且值为整数的正则表达式

重启9527,然后在终端输入curl http://localhost:9527/payment/lb -H "X-Request-Id:123"
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VMZEb6lh-1612882122473)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20210209221214068.png)]


Host

在这里插入图片描述
加上:

            - Host=**.achang.com	#Host: xxx.angenin.com 请求是Host必须有**.angenin.com

重启9527
curl http://localhost:9527/payment/lb -H "Host: www.achang.com"
在这里插入图片描述


Method

在这里插入图片描述

            - Method=GET	#只允许get请求访问

Path

在这里插入图片描述

			#访问的url地址有 /payment/lb/ 才能访问
			- Path=/payment/lb/**	

已经用过了,这里不进行演示。


Query

在这里插入图片描述

            - Query=username, \d+   #url请求地址上参数的要求,这里必须带上username参数,并且值必须为【整数】

curl http://localhost:9527/payment/lb?username=110
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结

在这里插入图片描述


Filter的使用

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

GatewayFilter(31种)
Global Filter(10种)

这里以AddRequestHeader为代表。

  • 要求匹配请求头上,有个参数X-Request-Red=【符合的正则表达式条件】,才可以访问

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I7H9vpRF-1612882122476)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20210209223416910.png)]


自定义过滤器

在这里插入图片描述
新建filter.MyLogGateWayFilter

这里也可以采用@Order(0)注解,和实现接口一样

@Component
@Slf4j
//@Order(0)   //设置过滤器优先次序
public class MyLogGateWayFilter implements GlobalFilter, Ordered {
    
    //Ordered优先次序设置;GlobalFilter过滤器设置

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    
    
        log.info("**************come in MyLogGateWayFilter:" + new Date());

        //获取request中的uname参数
        String uname = exchange.getRequest().getQueryParams().getFirst("uname");

        if(uname == null){
    
    
            log.info("*******用户名为null,非法用户!!");
            //设置响应,不被接受
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);

            return exchange.getResponse().setComplete();
        }

        //返回chain.filter(exchange),放行
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
    
    
        //返回值是过滤器的优先级,越小优先级越高(最小-2147483648,最大2147483648)
        return 0;
    }

}

启动7001,8001,8002,9527
http://localhost:9527/payment/lb?uname=111
在这里插入图片描述
http://localhost:9527/payment/lb?xxx=111
在这里插入图片描述

学习视频(p65-p73):https://www.bilibili.com/video/BV18E411x7eT?p=65
感谢尚硅谷

猜你喜欢

转载自blog.csdn.net/qq_43284469/article/details/113776868