SpringCloud之Gateway总结

参考:

官网

尚硅谷

聊聊Spring Cloud Gateway网关路由

Spring GateWay 路由源码分析

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

image-20200322232150746

在 SpringCloud Finchley 正式版之前,SpringCloud 推荐的网关是 Netflix 提供的 Zuul

  1. Zuul 1.x 是一个基于阻塞 I/O 的 API Gateway
  2. Zuul 1.x 基于 Servlet 2.5 使用阻塞架构 它不支持任何长连接(如 WebSocket) Zuul 的设计模式和 Nginx 很像,每次 I/O 操作都是从工作线程中选择一个执行,请求线程被阻塞到工作线程完成
  3. Spring Cloud Gateway 建立在 Spring Framework5, Project Reactor 和 Spring Boot 2 之上,使用非阻塞 API
  4. Spring Cloud Gateway 还支持 WebSocket

传统的 Web 框架,比如说:Struts2,SpringMVC 等都是基于 Servlet API 与 Servlet 容器基础之上运行的

但是在 Servlet3.1 之后有了异步非阻塞的支持。而 WebFlux 是一个典型的非阻塞异步的框架,它的核心是基于 Reactor 的相关 API 实现的。

Spring WebFlux 是 Spring5.0 引入的新的响应式框架,区别于 SpringMVC,它不需要依赖 Servlet API,它是完全异步非阻塞的,并且基于 Reactor 来实现响应式流规范

扫描二维码关注公众号,回复: 10921241 查看本文章

101

三大核心概念

  • Route(路由)
路由是构建网关的基本模块, 它由ID, 目标URI, 一系列的断言和过滤器组成, 如果断言为true则匹配该路由
  • Predicate(断言)
参考的是 Java8 的 java.util.function.Predicate
开发人员可以匹配 HTTP 请求中的所有内容(例如请求头或请求参数), 如果请求与断言相匹配则进行路由

102

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

103

官网 Gateway 处理请求如下所示:

104

客户端向 Spring Cloud Gateway 发出请求, 然后在 Gateway Handler Mapping 中找到与请求相匹配的路由, 将其发送到 Gateway Web Handler

Handler 再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。

过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前 (“pre”) 或之后 (“post”) 执行业务逻辑

Filter 在 “pre” 类型的过滤器可以做参数校验,权限校验, 流量监控,日志输出,协议转换等; 在 “post” 类型的过滤器中可以做响应内容,响应头的修改,日志的输出,流量监控等非常重要的作用

GatewayFilter Factories

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

SpringCloud Gateway 内置了多种路由过滤器,它们都是由 GatewayFilter 的工厂类来产生

yml中配置路由

示例

spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true #开启从注册中心动态创建路由的功能
          lower-case-service-id: true #使用小写服务名,默认是大写
      routes:
        - id: payment_routh #路由的ID,没有固定规则但要求唯一,建议配合服务名
          #uri: http://localhost:8001 #匹配提供服务的路由地址(路由地址写死,避免)
          uri: lb://服务名称
          predicates:
            - Path=/payment/get/** #断言, 路径相匹配的进行路由

        - id: payment_routh #路由的ID,没有固定规则但要求唯一,建议配合服务名
            #uri: http://localhost:8001 #匹配提供服务的路由地址
            uri: lb://服务名称
            predicates:
              - Path=/payment/lb/** #断言, 路径相匹配的进行路由

编码方式配置路由

@Configuration
public class GatewayConfig {

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder){
        return builder.routes()
            .route("path_route2",r -> r.path("/user/getByUsername")
                   .uri("http://localhost:8201/user/getByUsername"))
            .build();
    }
}

url 后面接上 /user/getByUsername 则会跳转至 http://localhost:8201/user/getByUsername 进行访问

自定义过滤器

@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,非法用户");
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        //过滤器数值越低, 优先级越高
        return 0;
    }
}

url 后面携带的参数不是 uname 格式,或者格式不正确 ,就会返回 401 UNAUTHORIZED 未授权的错误

发布了18 篇原创文章 · 获赞 0 · 访问量 419

猜你喜欢

转载自blog.csdn.net/mikelv01/article/details/105038984