9.SpringCloud Gateway网关

SpringCloud系列文章列表

0. SpringCloud实战专栏介绍准备
1. SpringCloud父工程搭建
2. 服务注册中心之Eureka(单机+集群+Ribbon调用)
3. 服务注册中心之Zookeeper
4. 服务注册中心之Consul
5. eureka、zookeeper和consul三种注册中心之间的区别
6. 负载均衡服务调用之Ribbon
7. 服务调用之OpenFeign
8. Hystrix断路器全面实战总结
9. SpringCloud Gateway网关
10. SpringCloud Config配置中心
11. SpringCloud Bus消息总线
12. SpringCloud Stream消息驱动
13. SpringCloud Sleuth分布式请求链路追踪

1 Gateway介绍

官方文档:
https://docs.spring.io/spring-cloud-gateway/docs/2.2.5.RELEASE/reference/html/
中文 https://www.springcloud.cc/spring-cloud-greenwich.html#_spring_cloud_gateway

1.1 概述

在这里插入图片描述
SpringCloud Gateway是在Spring生态系统之上构建的API网关服务,基于Spring 5,Spring Boot 2和Project Reactor等技术。
SpringCloud Gateway旨在提供一种简单而有效的方式来对API进行路由,以及提供一些强大的过滤器功能,例如:熔断、限流、重试等;

SpringCloud Gateway作为Spring Cloud 生态系统中的网关,目标是替代Zuul,因为在Spring Cloud 2.0以上版本中,没有对应新版本的Zuul 2.x

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

1.2 功能
  • 反向代理
  • 鉴权
  • 熔断
  • 日志监控
1.3 gateway vs zuul
1.3.1 为什么选择Gateway?
  • neflix不太靠谱,zuul2.0一直跳票,迟迟不发布
    一方面因为Zuul1.0已经进入了维护阶段,而且Gateway是SpringCloud团队研发的,是亲儿子产品,值得信赖。而且很多功能Zuul都没有用起来也非常的简单便捷。
    Gateway是基于异步非阻塞模型上进行开发的,性能方面不需要担心。虽然Netflix早就发布了最新的Zuul 2x,但Spring Cloud貌似没有整合计划。而且Netflix相关组件都宣布进入维护期;不知前景如?
    多方面综合考虑Gateway是很理想的网关选择。

  • gateway具有如下特性
    在这里插入图片描述

  • gateway与zuul的区别
    在这里插入图片描述

1.3.2 Zuul1.x模型

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

1.3.3 Gateway模型

基于Spring WebFlux的异步非阻塞模型
在这里插入图片描述

1.4 三大核心概念
  • Route(路由)
    路由是构建网关的基本模块,它由ID,目标URI,一系列的断言和过滤器组成,如果断言为true则匹配i该路由

  • Predicate(断言)
    参考的是java8的java.util.function.Predicate,开发人员可以匹配Http请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由

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

在这里插入图片描述
web请求,通过一些匹配条件,定位到真正的服务节点。并在这个转发过程的前后,进行一些精细化控制。
predicate就是我们的匹配条件;而fiter,就可以理解为一个无所不能的拦截器。有了这两个元素,再加上目标uri,就可以实现一个具体的路由了

1.5 Gateway工作流程

官网总结
在这里插入图片描述
Clients make requests to Spring Cloud Gateway. If the Gateway Handler Mapping determines that a request matches a route, it is sent to the Gateway Web Handler. This handler runs the request through a filter chain that is specific to the request. The reason the filters are divided by the dotted line is that filters can run logic both before and after the proxy request is sent. All “pre” filter logic is executed. Then the proxy request is made. After the proxy request is made, the “post” filter logic is run.
翻译如下:
客户端向Spring Cloud网关发出请求。如果网关处理程序映射确定请求与路由匹配,则将其发送到网关Web处理程序。该处理程序运行通过特定于请求的筛选器链发送请求。筛选器由虚线分隔的原因是,筛选器可以在发送代理请求之前或之后执行逻辑。执行所有“前置”过滤器逻辑,然后发出代理请求。发出代理请求后,将执行“后”过滤器逻辑。

一句话,核心逻辑就是路由转发+执行过滤器链

2 实战

2.1 入门配置

新建项目cloud-gateway-gateway9527

  • pom.xml
		<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
  • application.yml
server:
  port: 9527

spring:
  application:
    name: cloud-gateway9527
  cloud:
    gateway:
      routes:
        - id: baidu
          uri: http://www.baidu.com
          predicates:
            - Path=/baidu
          filters: # 过滤器,对请求进行拦截,实现自定义的功能,对应 FilterDefinition 数组
            - StripPrefix=1 #会将请求的 Path 去除掉前缀,参数拼接在uri后面;默认0

        - id: payment_route
          uri: http://localhost:8001
          predicates:
            - Path=/payment/**

访问http://localhost:9527/baidu?gg=123的时候,实际访问到 http://www.baidu.com?gg=123
访问http://localhost:9527/payment/hello , 实际访问到 http://localhost:8001/payment/hello

  • 启动类
    无额外注解
  • 案例测试
    启动项目cloud-gateway-gateway9527、cloud-provider-payment8001
    浏览器访问:http://localhost:9527/baidu?gg=123
    在这里插入图片描述
    浏览器访问:http://localhost:9527/payment/hello
    实际访问到了8001项目的/payment/hello接口
    在这里插入图片描述
    总结:
    访问网关url,首先通过一系列predicates断言配置匹配路由规则,经过对应的filters过滤后,路由到对应的uri
2.2 通过微服务名实现动态路由

修改项目cloud-gateway-gateway9527,注册到eureka

  • pom.xml
		<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
  • yml
server:
  port: 9527

spring:
  application:
    name: cloud-gateway9527
  cloud:
    gateway:
      routes:
        - id: baidu
          uri: http://www.baidu.com
          predicates:
            - Path=/baidu
          filters: # 过滤器,对请求进行拦截,实现自定义的功能,对应 FilterDefinition 数组
            - StripPrefix=1 #会将请求的 Path 去除掉前缀,参数拼接在uri后面;默认0

        - id: payment_route
          #uri: http://localhost:8001
          uri: lb://PROVIDER-PAYMENT #动态路由
          predicates:
            - Path=/payment/**
eureka:
  instance:
    hostname: cloud-gateway-service
  client:
    service-url:
      register-with-eureka: false
      fetch-registry: true
      defaultZone: http://localhost:7001/eureka

注意 动态路由的uri格式就是 lb://服务名

  • 启动类
    新增注解@EnableEurekaClient
  • 案例测试
    启动项目cloud-eureka-server7001、cloud-provider-payment8001、cloud-gateway-gateway9527
    浏览器访问 http://localhost:9527/payment/hello
    在这里插入图片描述
    成功的访问到了8001项目
2.3 Gateway网关路由配置的两种方式

第一种方式就是上面的在application.yml配置文件中配置;
下面介绍第二种代码配置;
修改cloud-gateway-gateway9527

  • 新增配置类GatewayConfig
@Configuration
public class GatewayConfig {
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder){
        RouteLocatorBuilder.Builder routes = builder.routes();
        routes.route("path_rote1", r -> r.path("/guonei").uri("http://news.baidu.com/guonei")).build();
        routes.route("path_rote2", r -> r.path("/guoji").uri("http://news.baidu.com/guoji")).build();
        return routes.build();
    }

}

配置内容跟在yml中配置一样,只是换了种写法

  • 案例测试
    重启项目cloud-gateway-gateway9527
    浏览器访问 http://localhost:9527/guoji
    在这里插入图片描述
2.3 Predicate的使用

这块用法可以参考官方文档,写的比较详细,而且都有对应的例子,多练练,多理解
可以参考官方文档: https://docs.spring.io/spring-cloud-gateway/docs/2.2.5.RELEASE/reference/html/#gateway-request-predicates-factories
在这里插入图片描述

总结: 说白了,Predicate就是为了实现一组匹配规则,让请求过来找到对应的Route进行处理
在这里插入图片描述

2.4 Filter的使用

当一个请求到达一个Gateway的路由时,Filtering Web Handler会加载所有的GlobalFilter实例以及这个路由上配置的所有的GatewayFilter过滤器,然后组成一个完整的过滤链。
这个过滤链中过滤器使用org.springframework.core.Ordered接口进行排序,可以通过实现Ordered接口中的getOrder()方法或直接使用@Order注解修改过滤器的顺序。
由于Spring Cloud Gateway分开执行“pre”和“post”的过滤器,因此,优先级高的过滤器将先执行“pre”类型的过滤器,最后执行“post”类型的的过滤器

2.4.1 介绍
  • 概念
    路由过滤器可用于修改进入的HTTP请求和返回的HTTP响应,路由过滤器只能指定路由进行使用。
    Spring Cloud Gateway内置了多种路由过滤器,他们都由GatewayFilter的工厂类来产生。
  • 生命周期
    pre, 在业务逻辑之前
    post,在业务逻辑之后
  • 种类
    单一, GatewayFilter(31种,具体见下面官网地址)
    https://docs.spring.io/spring-cloud-gateway/docs/2.2.5.RELEASE/reference/html/#gatewayfilter-factories
    全局,GlobalFilter (10种,具体见下面官网地址)
    https://docs.spring.io/spring-cloud-gateway/docs/2.2.5.RELEASE/reference/html/#global-filters
2.4.2 自定义全局过滤器

implements GlobalFilter, Ordered两个接口
可以用来做全局日志记录、统一网关鉴权等

代码实战演示:
修改项目cloud-gateway-gateway9527
增加配置类

@Component
public class GlobalGatewayFilter implements GlobalFilter, Ordered {
    Logger logger = LoggerFactory.getLogger(GlobalFilter.class);
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        logger.info("========GlobalGatewayFilter========");
        String uname = exchange.getRequest().getQueryParams().getFirst("uname");
        if(uname == null){
            logger.info("========uname is null========");
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

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

案例测试:
启动项目cloud-eureka-server7001,cloud-gateway-gateway9527
浏览器访问:http://localhost:9527/guonei
在这里插入图片描述

在这里插入图片描述
可见,没携带uname参数,被filter拦截成功了。
浏览器访问:http://localhost:9527/guonei?uname=ws
在这里插入图片描述

在这里插入图片描述

点赞+评论+关注
本文源码地址: https://gitee.com/shuaidawang/SpringCloudDemo.git
有错误的地方欢迎各位大佬指正!可以加入qq交流群: 700637673

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

臭小子帅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值