欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

荐 SpringCloud(5)--服务网关(GateWay)

程序员文章站 2022-10-03 17:30:27
文章目录服务网关GateWay工作原理GateWay的使用动态路由Pridicate断言Filter过滤器系列链接:GitHub:源码SpringCloud(1)–入门、版本、环境搭建SpringCloud(2)–服务注册与发现(Eureka、Zookeeper、Consul)SpringCloud(3)–服务调用(Ribbon、OpenFeign)SpringCloud(4)–服务降级(Hystrix、降级、熔断、监控)…服务网关基本架构如下:GateWayGateway 是...

系列链接:


服务网关

基本架构如下:

荐
                                                        SpringCloud(5)--服务网关(GateWay)

GateWay

Gateway 是在 Spring 生态系统之上构建的 API 网关服务,基于 Spring 5、Spring Boot 2 和 Project Reactor 等技术。它提供了一种简单且有效的方式来对 API 进行路由,并提供了一些强大的过滤器功能(熔断、限流、重试等)。

Gateway 的底层是基于 WebFlux 框架实现的,而webFlux底层使用netty通信(NIO)。

GateWay的特性:

  • 基于 Spring 5、Spring Boot 2 和 Project Reactor 进行构建
  • 动态路由,能够匹配任何请求属性
  • 可以对路由指定和边写 Predicate(断言)和 Filter(过滤器)
  • 集成 Hystrix 的断路器功能
  • 集成 Spring Cloud 服务发现功能
  • 请求限流功能、支持路径重写

GateWay与zuul的区别:

  • Zuul 1.x 是一个基于 Servlet 2.5 的阻塞架构,性能较差。而 2.x 版本基于 Netty 非阻塞并支持长连接,但与 Spring Cloud 目前还没整合。
  • Gateway 使用非阻塞 API,支持 WebSocket 且与 Spring 紧密集成。

相关概念

  • 路由: 路由是构建网关的基本模块,它由ID,目标URI,一系列的断言和过滤器组成,就是根据某些规则,将请求发送到指定服务上。

  • 断言: 断言用于匹配 HTTP 请求中的所有内容(请求头/请求参数),如果请求与断言相匹配则进行路由。

  • 过滤: 实现的过滤器可以在请求被路由前或者之后,对请求进行修改。


工作原理

荐
                                                        SpringCloud(5)--服务网关(GateWay)

客户端向 Gateway 发出请求,然后在 Gateway Handler Mapping 中找到与请求匹配的路由,将其发送到 Gateway Handler。Handler 再通过指定的过滤器链,然后将请求发送到实际的服务执行业务逻辑,最后返回。

过滤器链之间用虚线分开,是因为在发送请求之前或之后执行一些其他的业务逻辑:

  • 之前:参数校验、权限校验、流量监控、日志输出、协议转换等。
  • 之后:相应内容与响应头的修改、日志输出、流量监控等。

GateWay的使用

  1. 新建名称为 cloud-gateway-gateway9527 的Module

  2. pom文件

    		<!--gateway-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-gateway</artifactId>
            </dependency>
    
  3. 配置文件

            server:
              port: 9527
    
            spring:
              application:
                name: cloud-gateway
    
            eureka:
              instance:
                hostname: cloud-gateway-service
              client:
                register-with-eureka: true
                fetch-registry: true
                service-url:
                  defaultZone: http://eureka7001.com:7001/eureka
    
  4. 主启动类

            @SpringBootApplication
            @EnableEurekaClient
            public class GateWayMain9527 {
                public static void main(String[] args){
                    SpringApplication.run(GateWayMain9527.class,args);
                }
            }
    
  5. 针对pay模块,设置路由,修改GateWay模块(9527)的配置文件

            spring:
              application:
                name: cloud-gateway
              cloud:
                gateway:
                  routes:
                    - id: payment_routh           # 路由的 ID,没有固定规则但要求唯一
                      uri: http://localhost:8001  # 匹配后蹄冻服务的路由地址
                      predicates:
                        - Path=/payment/get/**     # 断言,路径相匹配的进行路由
                    - id: payment_routh2           # 路由的 ID,没有固定规则但要求唯一
                      uri: http://localhost:8001  # 匹配后蹄冻服务的路由地址
                      predicates:
                        - Path=/payment/lb/**     # 断言,路径相匹配的进行路由
    
  6. 开始测试,启动7001、8001、9527

    注:如果启动GateWay报错可能是GateWay模块引入了web和监控的starter依赖,需要移除

    访问http://localhost:9527/payment/get/31

    荐
                                                        SpringCloud(5)--服务网关(GateWay)

  7. GateWay的网关配置,除了支持配置文件,还支持硬编码方式,使用硬编码配置GateWay:

    • 创建配置类

              @Configuration
              public class GateWayConfig {
                  @Bean
                  public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder){
                      RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
                      routes.route("path_route_moke",r->r.path("/guonei")
                              .uri("http://news.baidu.com/"));
                      return routes.build();
                  }
              }
      
    • 然后重启服务即可


动态路由

上面的配置虽然首先了网关,但是是在配置文件中写死了要路由的地址。我们可以修改为,从注册中心获取某组微服务的地址,然后根据微服务名字进行路由。

  1. 修改GateWay模块的配置文件

            spring:
              application:
                name: cloud-gateway
              cloud:
                gateway:
                  discovery:
                    locator:
                      enabled: true              # 开启从注册中心动态创建路由的功能,利用微服务名进行路由
                  routes:
                    - id: payment_routh           # 路由的 ID,没有固定规则但要求唯一
                      # uri: http://localhost:8001  # 匹配后蹄冻服务的路由地址
                      uri: lb://cloud-payment-service
                      predicates:
                        - Path=/payment/get/**     # 断言,路径相匹配的进行路由
                    - id: payment_routh2           # 路由的 ID,没有固定规则但要求唯一
                      # uri: http://localhost:8001   # 匹配后蹄冻服务的路由地址
                      uri: lb://cloud-payment-service
                      predicates:
                        - Path=/payment/lb/**       # 断言,路径相匹配的进行路由
    
  2. 然后就可以启动7001,8001,8002,9527服务


Pridicate断言

我们之前在配置文件中配置了断言:

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

Gateway 包括许多内置的 Route Predicate 工厂,所有这些 Predicate 都与 HTTP 请求的不同属性匹配,且多个 Route Oredicate 工厂可以进行组合。之前我们配置的Path,就是由其中一种工厂创建的。断言还有以下的类型:
荐
                                                        SpringCloud(5)--服务网关(GateWay)

  • After:可以指定,只有在指定时间后,才可以路由到指定微服务,zai 指定的时间之前访问,都会报404。
    荐
                                                        SpringCloud(5)--服务网关(GateWay)

  • before:与after类似,他说在指定时间之前的才可以访问

  • between:需要指定两个时间,在他们之间的时间才可以访问

  • cookie:只有包含某些指定cookie(key,value),的请求才可以路由
    荐
                                                        SpringCloud(5)--服务网关(GateWay)

  • Header:只有包含指定请求头的请求,才可以路由
    荐
                                                        SpringCloud(5)--服务网关(GateWay)

  • Host:只有指定主机的才可以访问

  • Method:只有指定请求才可以路由,比如get请求…
    荐
                                                        SpringCloud(5)--服务网关(GateWay)

  • Path:只有访问指定路径,才进行路由,我们已经用过了

  • Query:必须带有请求参数才可以访问
    荐
                                                        SpringCloud(5)--服务网关(GateWay)


Filter过滤器

Gateway 内置了多种路由过滤器,由 GatewayFilter 的工厂类生成,过滤器的类型可以在官网查看。
荐
                                                        SpringCloud(5)--服务网关(GateWay)

生命周期:在请求进入路由之前,和处理请求完成,再次到达路由之前

种类:

  • GatewayFilter:单一的过滤器

  • GlobalFilter:全局过滤器

自定义过滤器

  1. 实现两个接口GlobalFilter和Ordered

            @Component
            @Slf4j
            public class MyLogGateWayFilter implements GlobalFilter,Ordered{
                @Override
                public Mono<Void> filter(ServerWebExchange serverWebExchange, GatewayFilterChain gatewayFilterChain) {
                    log.info("****come in MyLogGateWayFilter:"+new Date());
                    String uname = serverWebExchange.getRequest().getQueryParams().getFirst("uname");
                    if(uname == null){
                        log.info("****用户名为空,非法用户");
                        serverWebExchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
                        return serverWebExchange.getResponse().setComplete();
                    }
                    return gatewayFilterChain.filter(serverWebExchange);
                }
    
                @Override
                public int getOrder() {
                    return 0;
                }
            }
    
  2. 然后启动服务

    • 请求带unam参数
      荐
                                                        SpringCloud(5)--服务网关(GateWay)

    • 请求不带参数
      荐
                                                        SpringCloud(5)--服务网关(GateWay)

本文地址:https://blog.csdn.net/MOKEXFDGH/article/details/107344407