Gateway服务网关

11.1 是什么Gateway

Cloud 全家桶中有一个非常重要得组件就是网关。 在1.x 版本 我们都采用得zuul网关。

在zuul 一直跳票。 springcloud自己研发了一个网关替代zuul。

gateway 是 zuul1.x 替代。

Spring cloud Gateway 使用得webflux 中得reactor-netty 响应编程组件。 底层使用得netty框架

11.2 能干什么Gateway
  • 反向代理

  • 鉴权

  • 流量控制

  • 熔断

  • 日志监控

    。。。。

有了zuul 怎么出来gateway ?

为什么选择gateway ? 1. zuul 网络跳票

gateway特性。

  1. 对路由有断言和过滤器
  2. 集成hystrix 断路器的功能
  3. spring cloud服务发现高效
  4. 限流
  5. 支持路由
  6. /。。

gateway和zuul 有什么区别

  1. zuul 1.x 是一个阻塞io api
  2. zuul 1.x 基于servlet 2.5 阻塞架构。 不支持任何长连接 (websocket) zuul设计和nginx 有点像。每次i/o操作都是从工作线程种选择一个执行。 请求线程被阻塞工作线程完成。
  3. zuul2. 理念先进。 netty非阻塞和支持长连接。 zuul2. 比 zuul1 快了1.6倍。。
  4. gateway spring faramework 5 spring boot 2 z之上 使用非阻塞。
  5. spring cloud gateway 还支持 websocket 。

zuul1. 模型

采用的tomcat 容器。 使用servlet io 处理器。

servlet 是一个简单网络io模型。 当请求servlet container servlet contrainer 会为其绑定一个线程。 在并发不高的情况下。 这种模型

使用。 但是一旦高并发。 线程数就会往上涨。

webflux

在传统的web框架中 spring mvc struts2 都是基于servlet容器基础之上运行。

在servlet 3.1 版本之后 才用异步非阻塞(AIO)的支持。 而webflux 是一个经典的非阻塞异步的框架。 spring boot tomcat (undertow)非阻塞+ 函数式编程。

11.3 怎么玩Gateway

三大核心 概念

  1. Rout路由 - 路由时构建网关的基本模块 他有id 目标url 一系列断言和过滤器组成
  2. Predicate断言 - 开发人员可以匹配http 请求中的所有内容
  3. Filter 过滤器 - 在使用过滤器 可以在请求被路由或者之前之后对请求进行修改
11.4 Gatway 网关路由配置2中方式:
11.4.1 在配置文件中yaml 配置
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          #匹配后提供服务的路由地址
          predicates:
             - Path=/payment/lb/**         # 断言,路径相匹配的进行路由
11.4.2 代码注入RouteLocator的bean
package com.etc.cloud.config;

import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Author kalista
 * @Description
 * @Date 2020/8/24  14:31
 **/
@Configuration
public class GatewayConfig {


    @Bean
    public RouteLocator constom(RouteLocatorBuilder builder){

        RouteLocatorBuilder.Builder routes = builder.routes();
        routes.route("path_route" ,r -> r.path("/guoji").uri("https://news.baidu.com/guoji"));

        return routes.build();

    }

    @Bean
    public RouteLocator constom2(RouteLocatorBuilder builder){

        RouteLocatorBuilder.Builder routes = builder.routes();
        routes.route("path_route" ,r -> r.path("/guonei").uri("https://news.baidu.com/guonei"));

        return routes.build();

    }

    @Bean
    public RouteLocator constom3(RouteLocatorBuilder builder){

        RouteLocatorBuilder.Builder routes = builder.routes();
        routes.route("path_route" ,r -> r.path("/mil").uri("https://news.baidu.com/mil"));

        return routes.build();

    }
}

11.5 Predicate 断言

断言的类型分为 9 类型:

After - 在时间之后才能路由
Before - 在时间之前才能路由
Between - 在时间区间才能路由
Cookie - 路由断言工程会取2个参数 cookie 名称对应的key value
Header - 根据header配置 。 如果携带header 和断言工程一致就匹配成功负责就失败
Host - 对请求的host地址进行断言。 如果成功就路由 www.huaxinzhiyuan.com **.jiaoxuebu.com
Method - 对请求的方法进行短信配置。 如果成功就路由 比如过 post get
Query - 对请求的参数进行断言 。 如果成功就路由 比如说 localhost:80/user/get?id=1
RemoteAddr - 对网段字符或者ip进行断言。 成功就路由

小总结:

断言就是为了实现一组匹配规则。 让请求过来找到对应的路由进行处理。

11.5.1 After Route Predicate
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/**         # 断言,路径相匹配的进行路由
            - After=2020-08-24T15:08:59.777+08:00[Asia/Shanghai]

注意时间参数 时间类是ZonedDateTime ISO-8601日历系统中具有时区的日期时间

public class Test {
    public static void main(String[] args) {
//        ZonedDateTime now = ZonedDateTime.now();

        //自定义
        ZonedDateTime now = ZonedDateTime.now(ZoneId.of("America/New_York"));
        
        System.out.println(now);
    }
}
11.5.2 Before Route Predicate
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/**         # 断言,路径相匹配的进行路由
            - Before=2020-08-26T15:08:59.777+08:00[Asia/Shanghai]

如果请求的时间在配置的时间之前分会为true 。 如果为false 报 404

11.5.3 Between Route Predicate

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/**         # 断言,路径相匹配的进行路由
            - Between=2020-08-24T15:08:59.777+08:00[Asia/Shanghai],2020-08-24T15:22:59.777+08:00[Asia/Shanghai]

11.5.4 Method Route Predicate

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/**         # 断言,路径相匹配的进行路由
            - Method=GET

如果这个请求的方法名是get 断言返回true

11.5.5 Cookie Route Predicate
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/**         # 断言,路径相匹配的进行路由
            - Cookie=username, wgslcuky

如果请求的cookie种有name的值。 并且根据name取出的值进行配置 true

11.5.6 Host Route Predicate
spring:
  cloud:
    gateway:
      routes:
      - id: host_route
        uri: http://www.xinyues.com
        predicates:
        - Host=**.somehost.org,**.anotherhost.org,{sub}.myhost.org

11.5.7 RemoteAddr Route Predicate

spring:
  cloud:
    gateway:
      routes:
      - id: remoteaddr_route
        uri: http://www.xinyues.com
        predicates:
        - RemoteAddr=192.168.1.1/24

如果请求的客户端的ip地址是192.168.1.1 到192.168.1.24 之间的范围都是返回true

11.6 过滤器

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

spring colud gateway 内置了多种过滤器。 他们都由 gatewayfilter工程类产生

2种过滤器 “pre” 和 “post”

pre : 这种过滤器在请求被路由之前调用

post : 这种过滤器在请求被路由之后调用

在gateway 过滤器 又可以分为2种。 GatewayFileter 和 GlobalFilter

GlobalFilter 全局过滤器

GatewayFileter 将应用到单个路由或者一个分组的路由上

能干什么 全局日志记录 统一的网关鉴权

自定义一个GlobalFilter:

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

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        log.info("come in global filter:{}", new Date());
        ServerHttpRequest request = exchange.getRequest();
        String uname = request.getQueryParams().getFirst("uname");
        if (StringUtils.isEmpty(uname)) {
            log.error("用户为null 非法用户");
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            return exchange.getResponse().setComplete();
        }

        return chain.filter(exchange);
    }

    /**
     * 过滤器加载的顺序越小。 优先级越高
     *
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值