spring cloud gateway一些相关概念

在云架构中运行着众多客户端和服务端,API网关的存在提供了保护和路由消息,隐藏服务,限制负载等等功能。下图是spring cloud gateway所处的位置。

它有三大概念:

路由:路由是构建网关的基本模块,它由ID,目标URI,一系列的断言Predicates和过滤器Filters组成,如果断言为true,则匹配该路由。

断言:参考Java8的java.util.function.Predicate,开发人员可以匹配HTTP请求中的所有内容,例如请求头或请求参数,如果请求与断言相匹配则进行路由。

过滤:Spring框架中GatewayFilter的实例,使用过滤器,可以载请求被路由前或者后对请求进行修改。

工作流程图如下:

SpringCloud Gateway 和nginx 都在流量进入服务前做一些处理, 那谁先执行呢,他们之间有联系吗 ?

在微服务架构中,SpringCloud Gateway和Nginx的执行顺序和它们之间的联系主要取决于你的具体配置和架构设计。

  1. 执行顺序

    • 如果你将Nginx用作反向代理服务器,并且将所有入站流量都首先路由到Nginx,那么Nginx将首先执行。Nginx可以根据其配置将请求转发到后端的SpringCloud Gateway或其他微服务。
    • 如果SpringCloud Gateway是直接暴露给外部用户的,那么它将首先执行。但是,你仍然可以在SpringCloud Gateway之前使用Nginx作为反向代理,以增加额外的安全性、负载均衡或其他功能。
  2. 联系

    • 反向代理:Nginx经常被用作反向代理服务器,将外部请求转发到后端的SpringCloud Gateway或其他微服务。这可以为你的架构提供额外的安全性、负载均衡和缓存功能。
    • 负载均衡:Nginx和SpringCloud Gateway都支持负载均衡功能。Nginx可以在其配置中定义负载均衡规则,将请求分发到多个SpringCloud Gateway实例或其他微服务实例上。同样,SpringCloud Gateway也可以配置负载均衡策略,将请求路由到后端的微服务实例。
    • 安全性:Nginx和SpringCloud Gateway都可以提供安全性功能,如SSL终止、IP白名单、基本身份验证等。但是,它们的安全性功能可能有所不同,具体取决于你的配置和需求。
    • 解耦和细分:在某些情况下,Nginx可能不再承担服务的路由分发和负载均衡的角色,而是将这些功能转交给更专业的工具(如SpringCloud Gateway)来处理。这是一种解耦和细分的表现,可以使你的架构更加灵活和可扩展。

Nginx和SpringCloud Gateway之间可以存在紧密的联系,但也可以完全独立地运行。需要根据你的具体需求和架构设计来决定如何配置和使用它们。

那SpringCloud Gateway 和spring security谁先执行呢?

在Spring Cloud微服务架构中,SpringCloud GatewaySpring Security的执行顺序取决于它们是如何配置和集成的。但通常来说,SpringCloud Gateway作为API网关,会首先接收到来自客户端的请求,并在处理这些请求时可能会涉及到Spring Security的安全检查。

以下是它们之间可能的工作流程:

  1. 客户端发起请求:客户端(如Web浏览器、移动应用或其他服务)向API网关(即SpringCloud Gateway)发起HTTP请求。
  2. SpringCloud Gateway接收请求:SpringCloud Gateway作为API网关,会首先接收到这些请求。它会根据配置的路由规则来确定将请求转发到哪个微服务。
  3. SpringCloud Gateway的安全检查(如果配置):在转发请求之前,SpringCloud Gateway可能会执行一些安全检查。这些检查可能包括验证请求头、请求参数或JWT令牌等。这些安全检查可以通过自定义的过滤器(Filter)来实现,这些过滤器可以在请求被转发到微服务之前对请求进行拦截和处理。
  4. 转发请求到微服务:如果请求通过了SpringCloud Gateway的安全检查(如果有的话),那么它就会被转发到相应的微服务。
  5. Spring Security在微服务中的执行:当请求到达微服务时,如果微服务配置了Spring Security,那么Spring Security就会执行相应的安全检查。这些检查可能包括验证用户的身份(如用户名和密码登录、OAuth令牌等)、检查用户是否有权访问请求的资源等。
  6. 微服务处理请求并返回响应:如果请求通过了Spring Security的安全检查,那么微服务就会处理该请求并返回响应。这个响应会经过SpringCloud Gateway返回给客户端。

SpringCloud Gateway和Spring Security的安全检查是独立的,它们可以分别配置和执行。在某些情况下,你可能需要在SpringCloud Gateway中执行一些安全检查(如验证JWT令牌),然后在微服务中执行更细粒度的安全检查(如基于角色的访问控制)。这取决于具体需求和架构设计。

spring cloud gateway 断言配置:

java 复制代码
        predicates:
        - Before=2017-01-20T17:42:47.789-07:00[America/Denver]  # 在..之前可以匹配
        - After=2017-01-20T17:42:47.789-07:00[America/Denver]   # 在..之后可以匹配
        - Between=xxx,xxx										# 在..之间可以匹配
        - Cookie=chocolate, ch.p								# 带cookie
        - Header=X-Request-Id, \d+								# 规定header
        - Host=**.somehost.org,**.anotherhost.org				# 规定host
        - Method=GET,POST										# 规定请求方法
        - Path=/red/{segment},/blue/{segment}					# 规定请求路径
        - Query=green											# 规定请求参数
        - RemoteAddr=192.168.1.1/24								# 规定remoteAddr
        
        # 将80%的流量转到weighthigh.org,20%转到weightlow.org
      - id: weight_high
        uri: https://weighthigh.org
        predicates:
        - Weight=group1, 8
      - id: weight_low
        uri: https://weightlow.org
        predicates:
        - Weight=group1, 2

例子:假如有两个相同的服务实例cloud-payment-service(即它们提供相同的功能和API),并且你希望它们能够共同分担负载(即实现负载均衡,端口分别为8001和8002),现在通过gateway的断言设置分别请求这两个服务里的/payment/hello方法。

gateway的yml配置:

XML 复制代码
server:
  port: 9527

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=/payment1/**         # 断言,路径相匹配的进行路由
            - After=2020-11-26T21:27:26.256+08:00[Asia/Shanghai]

        - id: payment_routh2 #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名
          #uri: http://localhost:8001          #匹配后提供服务的路由地址
          uri: lb://cloud-payment-service #匹配后提供服务的路由地址
          predicates:
            - Path=/payment2/lb/**         # 断言,路径相匹配的进行路由
            - After=2020-11-25T22:42:23.608+08:00[Asia/Shanghai]
            - Cookie=username,hyh
            #- Header=X-Request-Id, \d+  # 请求头要有X-Request-Id属性并且值为整数的正则表达式
#            - Host=**.somehost.org,**.anotherhost.org  # 匹配hostname
#            - Method=GET,POST
#            - Path=/red/{segment},/blue/{segment}
#            - Query=green
#            - RemoteAddr=192.168.1.1/24
#            - Weight=group1, 2
        - id: payment_routh3 #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名
          #uri: http://localhost:8001          #匹配后提供服务的路由地址
          uri: lb://cloud-payment-service #匹配后提供服务的路由地址
          predicates:
            - Path=/payment/hello         # 断言,路径相匹配的进行路由
            - After=2020-11-25T22:42:23.608+08:00[Asia/Shanghai]
            - Cookie=username,hyh
            - Header=X-Request-Num, \d+
eureka:
  instance:
    hostname: cloud-gateway-service
    instance-id: gateway9527
    prefer-ip-address: true
  client: #服务提供者provider注册进eureka服务列表内
    service-url:
      register-with-eureka: true
      fetch-registry: true
      defaultZone: http://eureka7001.com:7001/eureka

8001的服务的方法:

java 复制代码
 @GetMapping("/payment/hello")
 public String helloNum() {
        log.info("(8001)/payment/hello 执行了");
        return serverPort + "/payment/hello 执行了";
 }

8002的服务的方法:

java 复制代码
@GetMapping("/payment/hello")
public String helloNum() {
        log.info("(8001)/payment/hello 执行了");
        return serverPort + "/payment/hello 执行了";
}

设置请求参数:

连点两次发送请求gateway服务,发现两次分别调用了两个服务的同一个方法:

如果将请求头header或者cookies设置为错误的值,不满足断言,gateway则不转发这个请求:

相关推荐
懒大王爱吃狼23 分钟前
Python教程:python枚举类定义和使用
开发语言·前端·javascript·python·python基础·python编程·python书籍
秃头佛爷1 小时前
Python学习大纲总结及注意事项
开发语言·python·学习
阿伟*rui1 小时前
配置管理,雪崩问题分析,sentinel的使用
java·spring boot·sentinel
待磨的钝刨1 小时前
【格式化查看JSON文件】coco的json文件内容都在一行如何按照json格式查看
开发语言·javascript·json
XiaoLeisj3 小时前
【JavaEE初阶 — 多线程】单例模式 & 指令重排序问题
java·开发语言·java-ee
paopaokaka_luck3 小时前
【360】基于springboot的志愿服务管理系统
java·spring boot·后端·spring·毕业设计
dayouziei3 小时前
java的类加载机制的学习
java·学习
励志成为嵌入式工程师4 小时前
c语言简单编程练习9
c语言·开发语言·算法·vim
捕鲸叉5 小时前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer5 小时前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法