微服务网关SpringCloud Gateway

微服务网关简介


Introduce

当我们实现了各种微服务后,我们的各种微服务又要如何提供给外部应用调用呢??
当然,因为是Rest API 接口 ,外部客户端直接调用微服务是没有问题的。但是出于种种原因,这并不是一个很好的选择。让客户端直接与各个微服务进行通讯,会存在以下问题。

  • 客户端会多次请求不同的微服务,增加了客户端的复杂性
  • 存在跨域请求,在一定场景下处理会变得相对比较复杂
  • 实现认证复杂,每个微服务都需要独立认证
  • 难以重构,项目迭代,可能导致微服务重新划分,如果客户端直接与微服务通讯,那么重构将会很难实施
  • 如果某些微服务使用了防火墙、浏览器不友好的协议,直接访问会有一定的困难

对于上述的问题我们应该如何解决?通过服务网关即可解决。在微服务系统中 微服务资源一般不直接暴露给外部客户端访问,这样的好处是将内部的服务隐藏起来,从而解决上述问题。网关有很多重要的意义,具体体现在下面几个方面:

  1. 网关可以做一些身份认证、权限管理、防止非法请求操作权限等,对服务起一定保护作用
  2. 网关将所有的微服务统一管理,对外统一暴露,外界系统不需要知道微服务架构相互调用的复杂性,同时也避免了内部服务一些敏感信息的泄露问题。
  3. 易于监控,可在微服务网关收集监控数据并将其推送到外部系统进行分析
  4. 客户端只跟服务网关打交道,减少了客户端与各个微服务之间的交互次数
  5. 多渠道支持,可以根据不同客户端(WEB端、移动端、桌面端、。。)提供不同的API网关
  6. 网关可以用来做流量监控。在高并发下,对服务进行限流、降级
  7. 网关把服务从内部分离出来,方便测试

微服务网关能够实现,路由、负载均衡等多种功能。类似Nginx、反向代理的功能。在微服务架构中,后端服务往往不直接开放给调用端,而是通过一个API网关根据请求的URL,路由到相应的服务,当添加API网关后,在第三方调用端和服务提供之间创建了一面墙,在API网关中进行权限控制,同时API网关以负载均衡的方式发送给后端服务。微服务网关架构:
在这里插入图片描述


一、SpringCloud Gateway 简介

springCloud 是spring Cloud 的一个全新的项目,该项目是基于Spring 5.0,spring Boot 2.0 和 Project Reactor 等技术开发的网关,它旨在 为微服务架构提供一种简单有效的统一的API管理方式

SpringCloud Gateway 作为Spring Cloud 生态系统中的网关,目标是代替Zuul,在Spring Cloud 2.0 以上版本中,没有对新版本的Zuul 2.0最新高性能版本进行集成,仍然还是使用Zuul 2.0之前的Reactor 模式的老版本,而为了提升网关的性能,Spring Cloud Gateway 是基于WebFlux框架实现的,而WebFlux框架底层使用了高性能的Reactor 模式通信框架Netty

Spring Cloud Gateway 的目标,不仅提供了统一的路由方式,并且基于Filter 链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流


二、特征

SpringCloud官方,对SpringCloud Gateway 特征介绍如下:

  • 基于 Spring Framework 5,Project Reactor 和 Spring Boot 2.0
  • 集成 Spring Cloud DiscoveryClient
  • predicate 和 Filters 作用于特定路由,易于编写的Predicates 和 Filters
  • 具备一些网关的高级功能,动态路由、限流、路径重写
  • 集成熔断器 CircuitBreaker

从以上特征来说和Zuul 的差别不大,Spring Cloud Gateway 和 Zuul 的主要差别在于底层的通信框架上。

简单说明一下,上文中的三个术语:

  • Filter(过滤器)
    和Zuul 的过滤器在概念 上类似,可以用它拦截和修改请求,并且对下游的响应进行二次处理,过滤器为 org.springframework.cloud.gateway.filter.GatewayFilter 类的实例

  • Route(路由)
    网关配置的基本组成模块,和Zuul 的路由配置模块类似。一个Route 模块由一个ID,一个目标URI,一组断言和一组过滤器定义。如果断言为真,则路由匹配,目标URI就会被访问。

  • Predicate(断言)
    这是一个Java8 的Predicate, 可以使用它来匹配来自HTTP 请求的任何内容,例如headers 或参数,断言的输入类型是一个 ServerWebExchange

三、配置路由的方式

路由是网关配置的基本组成模块,和Zuul 的路由配置模块类似。一个Route 模块由一个ID ,一个目标URI,一组断言和一组过滤器定义。如果断言为真,则路由匹配,目标URI就会被访问。

1.基础路由配置方式:
如果请求的地址,是单个的URI资源路径,配置文件如下:

spring:
   application:
     name: api-gateway
   cloud:
     gateway:
       routes:
          - id: service1
            uri: https://blog.csdn.net
            predicates:
              - Path=/csdn

各字段含义如下。
● id:我们自定义的路由 ID,保持唯一
● uri:目标服务地址
● predicates:路由条件,Predicate 接受一个输入参数,返回一个布尔值结果。该接口包含多种默认方法来将 Predicate 组合成其他复杂的逻辑(比如:与,或,非)。
上面这段配置的意思是,配置了一个 id 为 url-proxy-1的URI代理规则,路由的规则为,当访问地址http://localhost:8080/csdn/1.jsp时,会路由到上游地址https://blog.csdn.net/1.jsp。

2.基于代码的路由配置方式

转发功能同样可以通过代码来实现,我们可以在启动类 GateWayApplication 中添加方法 customRouteLocator() 来定制转发规则

@SpringBootApplication
@EnableDiscoveryClient
public class GatewayApplication {
    
    

    public static void main(String[] args) {
    
    
        SpringApplication.run(GatewayApplication.class, args);
    }

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
    
    
        return builder.routes()
                .route("path_route", r -> r.path("/csdn")
                        .uri("https://blog.csdn.net"))
                .build();
    }
}

3.和注册中心相结合的路由配置方式

在uri的schema协议部分为自定义的lb:类型,表示从微服务注册中心(如Eureka)订阅服务,并且通过负载均衡进行服务的路由。代码如下。

server:
  port: 9005
spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
        - id: service1
          uri: https://blog.csdn.net
          predicates:
            - Path=/csdn
        - id: service2
#          uri: http://127.0.0.1:9001
          uri: lb://cloud-payment-service
          predicates:
            - Path=/payment/**
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:9004/eureka

四、路由匹配规则

Spring Cloud Gateway 的主要功能是转发请求,转发规则的定义主要包含三个部分:

  • Route(路由):路由是网关的基本单元,有ID、URI、一组Predicate、一组 Filter 组成,根据Predicate 进行匹配转发
  • Predicate(谓语、断言):路由转发的判断条件,目前SpringCloud Gateway 支持多种形式,常见如:Path、Query、Method、Header 等,写法必须遵循 key = value 的形式
  • Filter(过滤器):过滤器是由请求转发时所经过的过滤逻辑,可用于修改请求和响应内容

五、高级特性

  • 熔断降级
    在分布式系统中,网关作为流量的入口,因此会有大量的请求进入网关,向其他服务发起调用,其他服务不可避免的出现调用失败(超时、异常),失败时不能让请求堆积在网关上,需要快速失败并返回给客户端,想要实现这个要求,就必须在网关上做熔断、降级操作。
    为什么在网关上请求失败需要快速返回给客户端?因为当一个客户端请求发生故障的时候,这个请求会一直堆积在网关上,当然只有一个这种请求,网关肯定没有问题(如果一个请求就能造成整个系统瘫痪,那这个系统可以下架了),但是网关上堆积了就会给网关乃至整个服务器都造成巨大的压力,以保证核心业务的正常运行,同时也保持了客户和大部分客户得到正确的响应,所以需要网关上请求失败需要快速返回给客户端。
    CircuitBreaker 过滤器使用 Spring Cloud CircuitBreaker API 将网关路由包装在断路器中。Spring Cloud CircuitBreaker 支持多个可与 Spring Cloud Gateway 一起使用熔断器库。比如Spring Cloud 支持开箱即用的 Resilience4j。

猜你喜欢

转载自blog.csdn.net/CXgeng/article/details/123011412