Gateway详解使用

为了保障文章的流畅性(文章穿插大量的环境搭建没意思,会干扰文章的主题,无聊的很),将环境的搭建与测试,工具的版本说明放了文末: 五、环境搭建。

一、概述

https://spring.io/projects/spring-cloud-gateway

该项目提供了在 Spring WebFlux 或 Spring WebMVC 之上构建 API 网关的库。Spring Cloud Gateway 旨在提供一种简单而有效的方法来路由到 API 并为它们提供跨切关注点,例如:安全性、监控

image-20240825182333720

Cloud全家桶中有个很重要的组件就是网关,在1.x版本中都是采用的Zuul网关;

但在2.x版本中,zuul的升级一直跳票,SpringCloud最后自己研发了一个网关SpringCloud Gateway替代Zuul,

那就是SpringCloud Gateway一句话:gateway是原zuul1.x版的替代

image-20240825182605116

作用:

  • 反向代理
  • 鉴权
  • 流量控制
  • 熔断
  • 日志监控

总结:

Spring Cloud Gateway组件的核心是一系列的过滤器,通过这些过滤器可以将客户端发送的请求转发(路由)到对应的微服务。 Spring Cloud Gateway是加在整个微服务最前沿的防火墙和代理器,隐藏微服务结点IP端口信息,从而加强安全保护。Spring Cloud Gateway本身也是一个微服务,需要注册进服务注册中心。

1.1、三大核心

https://cloud.spring.io/spring-cloud-gateway/reference/html/#glossary

image-20240825183330624

image-20240825183515827

  • Route(路由):路由是构建网关的基本模块,它由ID,目标URI,一系列的断言和过滤器组成,如果断言为true则匹配该路由
  • Predicate(断言):参考的是Java8的java.util.function.Predicate开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由
  • Filter(过滤):指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改。

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

1.2、工作流程

https://cloud.spring.io/spring-cloud-gateway/reference/html/#gateway-how-it-works

image-20240825183902181

image-20240825183944859

下图提供了 Spring Cloud Gateway 工作原理的高级概述:

Spring Cloud Gateway Diagram

客户端向 Spring Cloud Gateway 发出请求。如果 Gateway Handler Mapping 确定请求与路由匹配,则将其发送到 Gateway Web Handler。此处理程序通过特定于请求的过滤器链运行请求。过滤器被虚线分开的原因是过滤器可以在发送代理请求之前和之后运行逻辑。所有“前”过滤器逻辑都会执行。然后发出代理请求。发出代理请求后,将运行“后”过滤器逻辑。

在没有端口的路由中定义的 URI 分别获得 HTTP 和 HTTPS URI 的默认端口值 80 和 443。

核心逻辑:路由转发+断言判断+执行过滤器链

二、实战:基本使用

2.1、改POM

  <!--gateway-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

image-20240825184953615

2.2、写YML

server:
  port: 8763
spring:
  application:
    #对应consu控制台的实例名称
    name: gateway
  cloud:
    consul:
      host: 192.168.200.129
      port: 8500
      discovery:
        #节点检查的时候默认使用hostname报错,建议true通过ip访问
        prefer-ip-address: true
        #对应consu控制台的servcie名称(restTemplate调用)
        serviceName: gateway

image-20240825185203096

2.3、主启动

package com.gateway;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

/**
 * @Author: 史小创
 * @Time: 2024/8/25 下午6:52
 * @Description:
 */

@SpringBootApplication
@EnableDiscoveryClient
public class GatewayApplication {
    public static void main(String[] args) {
        org.springframework.boot.SpringApplication.run(GatewayApplication.class, args);
    }
}

image-20240825185351621

http://192.168.200.129:8500/ui/dc1/services

image-20240825190330517

三、网关如何做路由映射

诉求:我们不想暴漏服务的提供者的端口,想在外部包一层网关

3.1、正常访问

image-20240825194317970

http://localhost:8886/provider/gateway/getnumber/8886
http://localhost:8886/provider/gateway/getname/shixiaochuang

image-20240825194425813

image-20240825194433514

3.2、配置网关

image-20240825194648949

    gateway:
      routes:
        - id: provider_routh1             #路由的ID(类似mysql主键ID),没有固定规则但要求唯一,建议配合服务名
          uri: http://localhost:8886                #匹配后提供服务的路由地址
          predicates:
            - Path=/provider/gateway/getnumber/**              # 断言,路径相匹配的进行路由
        - id: provider_routh2 #pay_routh2                #路由的ID(类似mysql主键ID),没有固定规则但要求唯一,建议配合服务名
          uri: http://localhost:8886              #匹配后提供服务的路由地址
          predicates:
            - Path=/provider/gateway/getname/**              # 断言,路径相匹配的进行路由
http://localhost:8888/provider/gateway/getnumber/8888
http://localhost:8888/provider/gateway/getname/shixiaochuang

image-20240825194802046

image-20240825194808892

3.3、启动的服务的消费者,网关是否起作用呢

image-20240825202039563

http://localhost:8889/consumer/gateway/getnumber/8889
http://localhost:8889/consumer/gateway/getname/shixiaochuang

image-20240825202110882

image-20240825202118286

image-20240825202200280

http://localhost:8889/consumer/gateway/getnumber/8889
http://localhost:8889/consumer/gateway/getname/shixiaochuang

image-20240825202110882

image-20240825202118286

网关貌似没有任何作用,怎么办呢??

3.4、配置接口

@FeignClient(value = "gateway")

image-20240825202745257

重启测试:

http://localhost:8889/consumer/gateway/getname/shixiaochuang
http://localhost:8889/consumer/gateway/getnumber/8889

image-20240825202845158

image-20240825202853732

那么停止掉网关呢??

image-20240825202952920

http://localhost:8889/consumer/gateway/getname/shixiaochuang
http://localhost:8889/consumer/gateway/getnumber/8889

image-20240825203015297

image-20240825203021376

3.5、问题

image-20240825203201653

四、实战:进阶使用

4.1、Route以微服务名-动态获取服务URI

https://cloud.spring.io/spring-cloud-gateway/reference/html/#reactive-loadbalancer-client-filter

image-20240825203545380

image-20240825203703195

    gateway:
      routes:
        - id: provider_routh1             #路由的ID(类似mysql主键ID),没有固定规则但要求唯一,建议配合服务名
          #uri: http://localhost:8886                #匹配后提供服务的路由地址
          uri: lb://gateway-provider              #匹配后提供服务的路由地址
          predicates:
            - Path=/provider/gateway/getnumber/**              # 断言,路径相匹配的进行路由
        - id: provider_routh2 #pay_routh2                #路由的ID(类似mysql主键ID),没有固定规则但要求唯一,建议配合服务名
          #uri: http://localhost:8886              #匹配后提供服务的路由地址
          uri: lb://gateway-provider              #匹配后提供服务的路由地址
          predicates:
            - Path=/provider/gateway/getname/**         

image-20240825204042820

image-20240825204234537

http://localhost:8889/consumer/gateway/getnumber/8889
http://localhost:8889/consumer/gateway/getname/shixiaochuang

image-20240825204443440

image-20240825204450409

4.2、Predicate断言(谓词)

4.2.1、概述

https://cloud.spring.io/spring-cloud-gateway/reference/html/#gateway-request-predicates-factories

image-20240826171513153

Spring Cloud Gateway 作为 Spring WebFlux HandlerMapping 基础架构的一部分匹配路由。Spring Cloud Gateway 包含许多内置路由谓词工厂。所有这些谓词都匹配 HTTP 请求的不同属性。您可以使用逻辑 and 语句组合多个路由谓词工厂。

我们在配置文件中写的断言规则只是字符串,这些字符串会被Predicate Factory读取并处理,转变为路由判断的条件

例如Path=/user/**是按照路径匹配,这个规则是由

org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory类来

处理的,像这样的断言工厂在SpringCloudGateway还有十几个:

名称说明示例
After是某个时间点后的请求- After=2037-01-20T17:42:47.789-07:00[America/Denver]
Before是某个时间点之前的请求- Before=2031-04-13T15:14:47.433+08:00[Asia/Shanghai]
Between是某两个时间点之前的请求- Between=2037-01-20T17:42:47.789-07:00[America/Denver], 2037-01-21T17:42:47.789-07:00[America/Denver]
Cookie请求必须包含某些cookie- Cookie=chocolate, ch.p
Header请求必须包含某些header- Header=X-Request-Id, \d+
Host请求必须是访问某个host(域名)- Host=.somehost.org,.anotherhost.org
Method请求方式必须是指定方式- Method=GET,POST
Path请求路径必须符合指定规则- Path=/red/{segment},/blue/**
Query请求参数必须包含指定参数- Query=name, Jack或者- Query=name
RemoteAddr请求者的ip必须是指定范围- RemoteAddr=192.168.1.1/24
Weight权重处理

我们只需要掌握Path这种路由工程就可以了。

image-20240825205211744

4.2.2、常用的内置Route Predicate

Spring Cloud Gateway的12个断言工厂用于基于时间、请求属性(如Cookie、Header、Host、Method、Path、Query)、远程地址和流量权重等条件对请求进行路由匹配。

断言工厂参数匹配条件示例
Afterdatetime匹配在指定时间之后的请求After=2017-01-20T17:42:47.789-07:00[America/Denver]
Beforedatetime匹配在指定时间之前的请求Before=2017-01-20T17:42:47.789-07:00[America/Denver]
Betweendatetime1, datetime2匹配在两个指定时间之间的请求Between=2017-01-20T17:42:47.789-07:00,2017-01-21T17:42:47.789-07:00
Cookiecookie name, regexp匹配指定名称的cookie,并且cookie值符合正则表达式Cookie=chocolate, ch.p
Headerheader name, regexp匹配指定名称的header,并且header值符合正则表达式Header=X-Request-Id, \d+
Hosthost name patterns匹配Host头与指定模式的请求Host=**.somehost.org,**.anotherhost.org
MethodHTTP methods匹配指定HTTP方法的请求Method=GET,POST
PathSpring PathMatcher patterns, matchTrailingSlash匹配指定路径模式的请求Path=/red/{segment},/blue/{segment}
Queryparam, regexp (optional)匹配指定的查询参数,并且参数值符合正则表达式Query=green, Query=red, gree.
RemoteAddrCIDR-notation (IP addresses)匹配请求的远程地址(支持CIDR格式)RemoteAddr=192.168.1.1/24
Weightgroup, weight根据权重将流量分配到不同的路由Weight=group1, 8, Weight=group1, 2
XForwardedRemoteAddrCIDR-notation (IP addresses)匹配基于X-Forwarded-For头的远程地址(支持CIDR格式)XForwardedRemoteAddr=192.168.1.1/24

在配置的时候就像这样添加响应的参数即可,并且官网上边的写的很清楚,这里就不再一个一个的向下配置了

image-20240826171843249

4.3、Filter过滤

4.3.1、概述

https://docs.spring.io/spring-cloud-gateway/docs/4.0.4/reference/html/#gatewayfilter-factories

SpringMVC里面的的拦截器Interceptor,Servlet的过滤器

https://cloud.spring.io/spring-cloud-gateway/reference/html/#gateway-how-it-works

"pre”和"post"分别会在请求被执行前调用和被执行后调用,用来修改请求和响应信息

客户端向 Spring Cloud Gateway 发出请求。如果 Gateway Handler Mapping 确定请求与路由匹配,则将其发送到 Gateway Web Handler。此处理程序通过特定于请求的过滤器链运行请求。过滤器被虚线分开的原因是过滤器可以在发送代理请求之前和之后运行逻辑。所有“前”过滤器逻辑都会执行。然后发出代理请求。发出代理请求后,运行“后”过滤器逻辑。

image-20240825224447251

作用:

  • 请求鉴权
  • 异常处理
  • 记录接口调用时长统计

类型:

  1. 全局默认过滤器Global Filters
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#global-filters

gateway出厂默认已有的,直接用即可,主要作用于所有的路由

不需要在配置文件中配置,作用在所有的路由上,实现GlobalFilter接口即可

  1. 单一内置过滤器GatewayFilter
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories

也可以称为网关过滤器,这种过滤器主要是作用于单一路由或者某个路由分组

  1. 自定义过滤器

4.3.2、Gateway内置的过滤器

https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories

路由过滤器允许以某种方式修改传入的 HTTP 请求或传出的 HTTP 响应。路由过滤器的作用域是特定的路由。Spring Cloud Gateway 包含许多内置的 GatewayFilter 工厂。

image-20240825225610377

4.3.3、常用的内置过滤器详解

Spring Cloud Gateway内置过滤器分为请求头、请求参数、响应头、路径操作及默认过滤器等,支持对请求和响应的头部、参数、路径进行添加、删除、修改及重定向等操作。

  • 请求头相关过滤器:处理请求头的添加、删除或替换操作,支持使用URI变量。
  • 请求参数相关过滤器:处理请求参数的添加或删除操作,支持使用URI变量。
  • 响应头相关过滤器:处理响应头的添加或删除操作,支持使用URI变量。
  • 前缀和路径相关过滤器:处理请求路径的前缀添加、路径修改或重定向操作。
  • 其他过滤器:允许为所有路由配置默认的过滤器。
过滤器类别过滤器名称说明示例
请求头相关AddRequestHeader添加请求头,支持URI变量。X-Request-red: blue添加到下游请求的头部。
RemoveRequestHeader移除指定的请求头。移除X-Request-Foo头。
SetRequestHeader替换指定的请求头,支持URI变量。X-Request-Red替换为Blue
请求参数相关AddRequestParameter添加请求参数,支持URI变量。red=blue添加到下游请求的查询字符串。
RemoveRequestParameter移除指定的请求参数。移除red参数。
响应头相关AddResponseHeader添加响应头,支持URI变量。X-Response-Red: Blue添加到下游响应的头部。
RemoveResponseHeader移除指定的响应头。移除X-Response-Foo头。
前缀和路径相关PrefixPath为请求路径添加前缀。为路径/hello添加前缀/mypath,结果为/mypath/hello
RedirectTo执行重定向操作,支持包含请求参数。将请求重定向到https://acme.org,状态码为302。
SetPath修改请求路径,支持URI模板。将路径/red/blue修改为/blue
其他Default Filters为所有路由设置默认过滤器。为所有路由添加X-Response-Default-Red响应头,并前缀路径为/httpbin

与断言一样,这里就不在一一的向下列举了,配置的方法都类似

image-20240826172018491

五、环境搭建

SpringBoot+SpringCloud的版本:

<spring.boot.version>3.2.0</spring.boot.version>
<spring.cloud.version>2023.0.0</spring.cloud.version>

注册中心:

  <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-discovery</artifactId>
        </dependency>

远程调用:

   <!--openfeign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

Consul

image-20240823181110455

docker pull consul:1.9.6
docker run -d -p 8500:8500 --restart=always --name=consul -v /opt/consul:/consul/data consul:1.9.6 agent -server -bootstrap -ui -node=1 -client='0.0.0.0'
http://192.168.200.129:8500/ui/dc1/services

image-20240823180526926

jdk:

image-20240824171950942

Maven

image-20240823181810973

IDEA

image-20240823181906302

代码汇总:

https://github.com/shixiaochuangjob/markdownfile/tree/main/20240826

image-20240826175748659

https://mp.weixin.qq.com/s?__biz=MzkwOTczNzUxMQ==&mid=2247484774&idx=1&sn=2bedb98dc89c07a37f181c0473e85496&chksm=c1376e2ef640e738eab81b5d85d20e88c8a5773524e66eb4364eac5e5d3d03f18531d6c517a0#rd

在这里插入图片描述

  • 14
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Cloud Gateway是一个基于Spring Cloud的微服务网关,用于构建高效、可靠的微服务架构。它提供了一种简单而强大的方式来路由、过滤和转换请求,帮助开发者构建弹性、可扩展的微服务应用。 Spring Cloud Gateway的功能和工作原理可以通过以下几点来详解: 1. 网关功能:Spring Cloud Gateway作为一个API网关,具有路由、过滤和转发请求的功能。它可以根据请求的URL、请求头、请求参数等信息,将请求转发到不同的微服务实例上。 2. 网关路由:Spring Cloud Gateway支持基于路由规则的请求转发。开发者可以通过配置路由规则,将特定的请求路径映射到相应的微服务实例上。这样可以实现负载均衡、服务发现等功能。 3. 网关过滤:Spring Cloud Gateway支持请求过滤器,可以在请求到达网关之前或之后对请求进行一系列操作。开发者可以根据需要添加自定义的过滤器,实现请求认证、请求转换、请求限流等功能。 4. 响应式框架:Spring Cloud Gateway基于Spring WebFlux框架,采用异步非阻塞的方式处理请求。这使得网关在高并发场景下具备更好的性能和吞吐量。 总之,Spring Cloud Gateway是一个功能强大的微服务网关,可以作为微服务架构的入口,实现请求的路由、过滤和转发。它采用响应式框架来处理请求,具备高并发和可扩展性。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [【SpringCloud】SpringCloud原理之Gateway网关](https://blog.csdn.net/twotwo22222/article/details/129428040)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [SpringCloud Gateway 详解](https://blog.csdn.net/m0_51111980/article/details/128022758)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值