十二、Gateway新一代网关

clipboard

一、概述

1、是什么?

gateway是zuul1.x版的替代

GateWay是在Spring生态系统之上构建的API网关服务,基于Spring 5 , Spring Boot2 和 Project Reactor等技术。

SpringCloud Gateway使用的是Webflux中的react-netty响应式编程组件,底层使用了Netty通讯框架

GateWay旨在提供一种简单有效的方式来对API进行路由,以及提供一些强大的过滤器功能,例如:熔断、限流、重试等

2、能干嘛?

反向代理

鉴权

流量监控

熔断

日志监控

3、服务架构中网关在哪?

网关是所有微服务的入口!!!

clipboard

4、为什么选择Gateway?

clipboard

5、SpringCloud Gateway 的特性?

clipboard

6、SpringCloud Gateway与 Zuul的区别?

clipboard

二、三大核心概念

Route(路由)

路由是构建网关的基本模块,它由ID,目标url,一系列的断言和过滤器组成,如果断言为true则匹配该路由

Predicate(断言)

参考java8的java.util.function.Predicate

开发人员可以匹配HTTP请求中的所有内容,如果请求和断言相匹配则进行路由

Filter(过滤)

指的是Spring框架中GateFilter的实例,使用过滤器,可以在请求被路由前,或者之后对请求进行修改

clipboard

三、Gateway工作流程

clipboard

clipboard

四、Gateway入门配置 —— 实操

1)新建工程 cloud-gateway-gateway9527

clipboard

2)pom文件

<dependencies>
    <!--gateway-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    <!--eureka-client-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
    <dependency>
        <groupId>com.atguigu.springcloud</groupId>
        <artifactId>cloud-api-commons</artifactId>
        <version>${project.version}</version>
    </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
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true  #开启从注册中心创建路由的功能,利用微服务进行路由
      routes:
        - id: payment_routh #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名
          #uri: http://localhost:8001          #匹配后提供服务的路由地址
          uri: lb://cloud-payment-service #匹配后提供服务的路由地址
          predicates:
            - Path=/payment/get/**         # 断言,路径相匹配的进行路由

        - id: payment_routh2 #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名
          #uri: http://localhost:8001          #匹配后提供服务的路由地址
          uri: lb://cloud-payment-service #匹配后提供服务的路由地址
          predicates:
            - Path=/payment/lb/**         # 断言,路径相匹配的进行路由
            #- After=2020-02-21T15:51:37.485+08:00[Asia/Shanghai]
            #- Cookie=username,zzyy
            #- Header=X-Request-Id, \d+  # 请求头要有X-Request-Id属性并且值为整数的正则表达式
eureka:
  client: #服务提供者provider注册进eureka服务列表内
    service-url:
      register-with-eureka: true
      fetch-registry: true
      defaultZone: http://localhost:7001/eureka
  instance:
    hostname: cloud-gateway-service

4)主启动类

@SpringBootApplication
@EnableEurekaClient
public class GatewayMain {
    public static void main(String[] args) {
        SpringApplication.run(GatewayMain.class,args);
    }
}

5)配置类配置

@Configuration
public class GatewayConfig {

    @Bean
    public RouteLocator customerRouteLocator(RouteLocatorBuilder rb){
        RouteLocatorBuilder.Builder routes = rb.routes();

        //访问 http://localhost:9527/guonei 将会转发到  http://news.baidu.com/guonei
        routes.route("path_route_atguigu",
                r -> r.path("/guonei").uri("http://news.baidu.com/guonei"))
                .route("payment_routh",
                r -> r.path("/payment/get/**").uri("http://localhost:8001/payment/get/**"));
        return routes.build();
    }
}

6)启动eureka7001 payment8001和gateway后访问 http://localhost:9527/payment/get/1

也能得到payment8001服务提供的结果,说明网关起作用了

clipboard

clipboard

五、gateway网关配置的两种方法

1) 如上的yaml配置

2) java配置

增加配置类 GateWayConfig

@Configuration
public class GatewayConfig {

    @Bean
    public RouteLocator customerRouteLocator(RouteLocatorBuilder rb){
        RouteLocatorBuilder.Builder routes = rb.routes();

        //访问 http://localhost:9527/guonei 将会转发到  http://news.baidu.com/guonei
        routes.route("path_route_atguigu",
                r -> r.path("/guonei").uri("http://news.baidu.com/guonei"))
                .route("payment_routh",
                r -> r.path("/payment/get/**").uri("http://localhost:8001/payment/get/**"));
        return routes.build();
      /*  return null;*/
    }
}

访问:http://localhost:9527/guonei , 说明配置类确实起作用了

clipboard

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

默认情况下Gateway会根据注册中心注册的服务列表,以注册中心上微服务名为路径创建路由转发,从而实现动态路由的功能

clipboard

cloud:
  gateway:
    discovery:
      locator:
        enabled: true  #开启从注册中心创建路由的功能,利用微服务进行路由
    routes:
      - id: payment_routh #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名
        #uri: http://localhost:8001          #匹配后提供服务的路由地址
        uri: lb://cloud-payment-service #匹配后提供服务的路由地址   lb:负载均衡的意思 cloud-payment-service:eureka注册中心的服务名
        predicates:
          - Path=/payment/get/**         # 断言,路径相匹配的进行路由

      - id: payment_routh2 #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名
        #uri: http://localhost:8001          #匹配后提供服务的路由地址
        uri: lb://cloud-payment-service #匹配后提供服务的路由地址
        predicates:
          - Path=/payment/lb/**         # 断言,路径相匹配的进行路由
          #- After=2020-02-21T15:51:37.485+08:00[Asia/Shanghai]
          #- Cookie=username,zzyy
          #- Header=X-Request-Id, \d+  # 请求头要有X-Request-Id属性并且值为整数的正则表达式

七、predicate的使用

常用的 Route Predicate

1、After Route Predicate

predicates:
     - Path=/payment/lb/**         # 断言,路径相匹配的进行路由
     - After=2020-02-21T15:51:37.485+08:00[Asia/Shanghai]

意思就是说在 2020-02-21T15:51:37之后访问的请求才有效

当时间改为:2022-02-21T15:51:37 访问出错:

clipboard

2、Before Route Predicate

在 2020-02-21T15:51:37之前访问的请求才有效

predicates:
     - Path=/payment/lb/**         # 断言,路径相匹配的进行路由
     - Before=2020-02-21T15:51:37.485+08:00[Asia/Shanghai]

3、Between Route Predicate

在 2020-02-21T15:51:37 ~ 2022-02-21T15:51:37这个时间段访问的请求才有效

predicates:
     - Path=/payment/lb/**         # 断言,路径相匹配的进行路由
     - Between =2020-02-21T15:51:37.485+08:00[Asia/Shanghai],2022-02-21T15:51:37.485+08:00[Asia/Shanghai]

4、Cookie Router Predicate

predicates:
  - Path=/payment/lb/**         # 断言,路径相匹配的进行路由
  - Cookie=username,zzyy

当没有携带cookie时:

clipboard

携带cookie时

clipboard

5、Header Router Predicate

predicates:
  - Path=/payment/lb/**         # 断言,路径相匹配的进行路由
  - Header=X-Request-Id,\d+     # 请求头要有属性为X-Request-Id,并且值为整数的正则表达式

6、Host Router Predicate

predicates:
  - Path=/payment/lb/**         # 断言,路径相匹配的进行路由
  - Host=*.atguigu.com          # 该域名的网站发出的请求才能访问

7、Method Router Predicate

predicates:
  - Path=/payment/lb/**         # 断言,路径相匹配的进行路由
  - Method=Get                  # get 请求才能放行

8、Query Router Predicate

predicates:
  - Path=/payment/lb/**         # 断言,路径相匹配的进行路由
  - Query=userId,\d+    # 参数必须携带userId,且值必须为正整数

八、Filter的使用

1、是什么

路由过滤器可用于修改进入的Http请求和返回的Http响应,路由过滤器只能指定路由进行使用

SpringCloud Gateway内置了多种路由过滤器,他们都由GateWayFilter的工程类来产生

2、SpringCloud Gateway的Filter

clipboard

3、常用的GatewayFilter

clipboard

4、自定义过滤器

自定义全局 GlobalFilter:

必须携带userName参数,否则控制台会报错

@Component
@Slf4j
public class MyLogGateWayFilter implements GlobalFilter,Ordered
{

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

        String uname = exchange.getRequest().getQueryParams().getFirst("uname");

        if(uname == null)
        {
            log.info("*******用户名为null,非法用户,o(╥﹏╥)o");
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            return exchange.getResponse().setComplete();
        }

        return chain.filter(exchange);
    }

    @Override
    public int getOrder()
    {
        return 0;
    }
}

clipboard

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值