springboot整合spring cloud gateway搭建网关服务

spring cloud netflix zuul、spring cloud gateway是最常见的微服务网关,通过网关,我们可以在请求到达后端指定服务之前/后端服务处理完业务响应数据之后对响应进行对请求/响应进行处理。

比如常见的参数校验、接口鉴权等等,在后端服务的拦截器和过滤器能做的事在网关都可以做。

网关的主要功能是请求的转发以及负载均衡,和nginx的功能类似,只是底层实现不同。

这篇文章就详细介绍一下spring cloud gateway的使用,包括了各种断言及过滤器的相关配置,帮助初学者更好的了解gateway的使用。


目录

一、创建项目

二、添加依赖

三、修改配置

四、配置说明

predicates断言工厂

After

Before

Between

Cookile

Header

Host

Method

Path

Query

RemoteAddr

Weight

filters过滤器工厂

AddRequestHeader

AddRequestParameter

AddResponseHeader

RemoveResponseHeader

五、动态路由

1、添加依赖

2、修改配置


一、创建项目

在IntelliJ IDEA中创建一个springboot项目springboot-gateway

二、添加依赖

修改pom.xml,添加spring cloud gateway的依赖。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.6.RELEASE</version>
        <relativePath />
    </parent>

    <groupId>cn.edu.sgu.www</groupId>
    <artifactId>springboot-gateway</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot-gateway</name>
    <description>Spring Boot整合Spring Cloud Gateway案例项目</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

三、修改配置

将配置文件application.properties重命名为application.yml,修改配置文件的内容。

server:
  port: 9091

spring:
  application:
    name: gateway
  cloud:
    gateway:
      enabled: true
      routes:
        - id: provider
          uri: http://localhost:8088
          predicates:
            - Path=/api/provider/**
          filters:
            - StripPrefix=2

logging:
  file:
    name: D:/log/gateway.log # 保存日志文件到D盘
  level:
    springfox: error
    cn.edu.sgu.www.gateway: debug

参数说明:- StripPrefix=2表示删除前两级路径(/api/provider),比如http://localhost:9091/api/provider/对应的转发地址为服务器端的地址为

http://localhost:8088


本篇文章使用之前的服务提供者项目provider来测试网关配置。


相关文章:

springboot整合feign实现RPC调用,并通过Hystrix实现服务降级icon-default.png?t=O83Ahttps://blog.csdn.net/heyl163_/article/details/131778985项目地址:

Spring Boot整合Feign服务提供者项目icon-default.png?t=O83Ahttps://gitee.com/muyu-chengfeng/provider


在IntelliJ IDEA中拉取provider项目到本地,先后启动nacos服务器和provider项目。

启动当前网关项目,在浏览器地址栏输入以下网址访问服务提供者项目的接口。

http://localhost:9091/api/provider/user/getUserInfo

如图,成功返回了接口数据~

四、配置说明

在学习gateway的配置之前,需要了解gateway中的路由这个概念,路由一般由以下几个部分组成组成。

  • id:路由ID
  • uri:目标URL
  • filters:一组过滤器,可以对请求和响应进行额外的处理
  • predicates:一组断言,只有符合断言里的条件的请求才会被转发

比如前面我们配置的路由,里面就包含了上述的四个部分。

spring:
  cloud:
    gateway:
      enabled: true
      routes:
        - id: provider
          uri: http://localhost:8088
          predicates:
            - Path=/api/provider/**
          filters:
            - StripPrefix=2

其中uri称为目标地址,也就是我们需要转发请求到uri后面配置的路径,当我们访问ip地址:端口号/api/producer/**时,请求将会被转发到http://localhost:8088/**

predicates断言工厂

断言,其实就是一组条件,熟悉java.util.function.Predicate的应该对这个概念有一定的了解,其实就是设置了一些条件,通过matches()方法的返回值来判断是否满足设置的条件。

gateway里的断言predicates指的是路由断言工厂,在predicates里可以配置各种条件,只有全部条件都满足,请求才能被正确转发。

接下来介绍gateway里都有哪些断言工厂。


指定以下时间为参考时间:

2024-12-17T19:46:35.523+08:00[Asia/Shanghai]


After

配置在指定时间之后才能转发请求,后面指定的值的格式和LocalDateTime很像,只是多了毫秒和时区信息。

2024-12-17T19:46:35.523+08:00[Asia/Shanghai]

1、前半部分:2024-12-17T19:46:35.523这是一个LocalDateTime的字符串格式。

2、后半部分:+08:00[Asia/Shanghai]表示时区:东八区-亚洲/上海

  • 东时区用+表示,如+6:00表示东6区
  • 西时区用-表示,如-5:00表示西5区

server:
  port: 9091

spring:
  application:
    name: gateway
  cloud:
    gateway:
      enabled: true
      routes:
        - id: provider
          uri: http://localhost:8088
          predicates:
            - Path=/api/provider/**
            - After=2024-12-17T19:46:35.523+08:00[Asia/Shanghai]
          filters:
            - StripPrefix=2

logging:
  file:
    name: D:/log/gateway.log # 保存日志文件到D盘
  level:
    springfox: error
    cn.edu.sgu.www.gateway: debug

Before

限制在指定时间之前才能访问,比如上面配置的After改成Before就访问不到了,因为已经过了那个时间点。

server:
  port: 9091

spring:
  application:
    name: gateway
  cloud:
    gateway:
      enabled: true
      routes:
        - id: provider
          uri: http://localhost:8088
          predicates:
            - Path=/api/provider/**
            - Before=2024-12-17T19:46:35.523+08:00[Asia/Shanghai]
          filters:
            - StripPrefix=2

logging:
  file:
    name: D:/log/gateway.log # 保存日志文件到D盘
  level:
    springfox: error
    cn.edu.sgu.www.gateway: debug

Between

配置只能在指定时间段访问,上面的时间配置后移一天,依旧能得到返回结果。

server:
  port: 9091

spring:
  application:
    name: gateway
  cloud:
    gateway:
      enabled: true
      routes:
        - id: provider
          uri: http://localhost:8088
          predicates:
            - Path=/api/provider/**
            - Between=2024-12-17T19:46:35.523+08:00[Asia/Shanghai],2024-12-18T19:46:35.523+08:00[Asia/Shanghai]
          filters:
            - StripPrefix=2

logging:
  file:
    name: D:/log/gateway.log # 保存日志文件到D盘
  level:
    springfox: error
    cn.edu.sgu.www.gateway: debug

Cookile

限制只有请求中携带了指定的cookie才能访问。

server:
  port: 9091

spring:
  application:
    name: gateway
  cloud:
    gateway:
      enabled: true
      routes:
        - id: provider
          uri: http://localhost:8088
          predicates:
            - Path=/api/provider/**
            - Cookie=JSESSIONID,831B175D25150131A3F3017116369CAE
          filters:
            - StripPrefix=2

logging:
  file:
    name: D:/log/gateway.log # 保存日志文件到D盘
  level:
    springfox: error
    cn.edu.sgu.www.gateway: debug

上面配置只有携带了JSESSIONID的cookie,并且值为831B175D25150131A3F3017116369CAE

的请求才会被转发。

只有携带指定请求头的请求会被转发,在这里配置需要携带token的请求头。

server:
  port: 9091

spring:
  application:
    name: gateway
  cloud:
    gateway:
      enabled: true
      routes:
        - id: provider
          uri: http://localhost:8088
          predicates:
            - Path=/api/provider/**
            - Header=token,mhxy1218
          filters:
            - StripPrefix=2

logging:
  file:
    name: D:/log/gateway.log # 保存日志文件到D盘
  level:
    springfox: error
    cn.edu.sgu.www.gateway: debug

为了方便测试,使用postman来测试效果

不携带请求头时,404

携带请求头,正常响应。

Host

这个是指定域名访问,如果不是指定的域名,将访问失败,这个不好测试,就跳过了。

server:
  port: 9091

spring:
  application:
    name: gateway
  cloud:
    gateway:
      enabled: true
      routes:
        - id: provider
          uri: http://localhost:8088
          predicates:
            - Path=/api/provider/**
            - Host=taobao.com
          filters:
            - StripPrefix=2

logging:
  file:
    name: D:/log/gateway.log # 保存日志文件到D盘
  level:
    springfox: error
    cn.edu.sgu.www.gateway: debug

Method

配置请求方式,只有规定的请求方式才会被转发。

由于测试的接口的请求方式为get,所以接口访问失败,返回404状态码。

server:
  port: 9091

spring:
  application:
    name: gateway
  cloud:
    gateway:
      enabled: true
      routes:
        - id: provider
          uri: http://localhost:8088
          predicates:
            - Path=/api/provider/**
            - Method=POST
          filters:
            - StripPrefix=2

logging:
  file:
    name: D:/log/gateway.log # 保存日志文件到D盘
  level:
    springfox: error
    cn.edu.sgu.www.gateway: debug

Path

这是基础的断言,将指定的路径转发到目标URL,本篇文章的localhost:9091/api/provider/user/getUserInfo会被转发到localhost:8088/user/getUserInfo

Query

限制需要携带指定参数的请求才能正常转发

server:
  port: 9091

spring:
  application:
    name: gateway
  cloud:
    gateway:
      enabled: true
      routes:
        - id: provider
          uri: http://localhost:8088
          predicates:
            - Path=/api/provider/**
            - Query=access,true
          filters:
            - StripPrefix=2

logging:
  file:
    name: D:/log/gateway.log # 保存日志文件到D盘
  level:
    springfox: error
    cn.edu.sgu.www.gateway: debug

未携带参数:返回404状态码

携带参数:正常响应

RemoteAddr

RemoteAddr用于指定IP地址,只有配置的IP地址才能访问。

server:
  port: 9091

spring:
  application:
    name: gateway
  cloud:
    gateway:
      enabled: true
      routes:
        - id: provider
          uri: http://localhost:8088
          predicates:
            - Path=/api/provider/**
            - RemoteAddr=176.176.4.127
          filters:
            - StripPrefix=2

logging:
  file:
    name: D:/log/gateway.log # 保存日志文件到D盘
  level:
    springfox: error
    cn.edu.sgu.www.gateway: debug

Weight

这个用于配置权重,同一个分组中,权重配置的越大,请求时被选择访问的概率越高。这个不方便演示,跳过。

filters过滤器工厂

网关的过滤器,网关的处理流程由一组过滤器组成的过滤器链组成,是责任链设计模式的典型应用。

为了演示过滤器效果,在mhxysy的服务添加一个切面类,通过日志在控制台打印请求信息。

接下来介绍gateway里的几种常用的过滤器,因为过滤器实在是太多了,只讲解4种,其他的过滤器使用类似,感兴趣的可以通过文章末尾的spring cloud gateway链接进一步学习。

AddRequestHeader

这个过滤器的作用是在请求转发之前为当前请求添加请求头。

然后给请求添加一个请求头

server:
  port: 9091

spring:
  application:
    name: gateway
  cloud:
    gateway:
      enabled: true
      routes:
        - id: provider
          uri: http://localhost:8088
          predicates:
            - Path=/api/provider/**
          filters:
            - StripPrefix=2
            - AddRequestHeader=header,mhxy1218

logging:
  file:
    name: D:/log/gateway.log # 保存日志文件到D盘
  level:
    springfox: error
    cn.edu.sgu.www.gateway: debug

AddRequestParameter

这个过滤器的作用是给请求添加参数,相当于在请求后面添加“?参数名=参数值”

server:
  port: 9091

spring:
  application:
    name: gateway
  cloud:
    gateway:
      enabled: true
      routes:
        - id: provider
          uri: http://localhost:8088
          predicates:
            - Path=/api/provider/**
          filters:
            - StripPrefix=2
            - AddRequestParameter=access,true

logging:
  file:
    name: D:/log/gateway.log # 保存日志文件到D盘
  level:
    springfox: error
    cn.edu.sgu.www.gateway: debug

AddResponseHeader

这个过滤器的作用是,服务端返回请求之后,在网关返回数据给客户端之前为响应添加响应头。

在这里添加一个响应头service_name,值为provider

server:
  port: 9091

spring:
  application:
    name: gateway
  cloud:
    gateway:
      enabled: true
      routes:
        - id: provider
          uri: http://localhost:8088
          predicates:
            - Path=/api/provider/**
          filters:
            - StripPrefix=2
            - AddResponseHeader=service_name,provider

logging:
  file:
    name: D:/log/gateway.log # 保存日志文件到D盘
  level:
    springfox: error
    cn.edu.sgu.www.gateway: debug

然后我们观察一下效果,返回的响应中确实有一个自定义的响应头service_name

RemoveResponseHeader

这个过滤器的作用是删除响应头,例如上面的请求中,总是会返回一个响应头Date,在这里配置移除这个响应头。

server:
  port: 9091

spring:
  application:
    name: gateway
  cloud:
    gateway:
      enabled: true
      routes:
        - id: provider
          uri: http://localhost:8088
          predicates:
            - Path=/api/provider/**
          filters:
            - StripPrefix=2
            - RemoveResponseHeader=Date

logging:
  file:
    name: D:/log/gateway.log # 保存日志文件到D盘
  level:
    springfox: error
    cn.edu.sgu.www.gateway: debug

在postman里查看响应信息,确实已经没有了Date这个响应头。

五、动态路由

1、添加依赖

添加网关负载均衡和nacos注册中心的依赖。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.6.RELEASE</version>
        <relativePath />
    </parent>

    <groupId>cn.edu.sgu.www</groupId>
    <artifactId>springboot-gateway</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot-gateway</name>
    <description>Spring Boot整合Spring Cloud Gateway案例项目</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

2、修改配置

如果像上面一样,每个应用都要写ip:端口号,也太麻烦了。gateway支持动态路由,通过配置动态路由,可以实现负载均衡的功能,只需要把上面的配置稍微修改一下。

server:
  port: 9091

spring:
  application:
    name: gateway
  cloud:
    nacos:
      discovery:
        register-enabled: true
        server-addr: ${nacos.server}
        namespace: ${nacos.namespace}
    gateway:
      enabled: true
      # 开启自动路由
      discovery:
        locator:
          enabled: true
      routes:
        - id: provider
          uri: lb://provider
          predicates:
            - Path=/api/provider/**
          filters:
            - StripPrefix=2

nacos:
  server: localhost:8848
  namespace: 21baf036-a74d-4c13-9209-dc69e7c1c1ad

logging:
  file:
    name: D:/log/gateway.log # 保存日志文件到D盘
  level:
    springfox: error
    cn.edu.sgu.www.gateway: debug

上面的配置文件对比前面的配置文件,其实就多了一个开启动态路由的配置以及注册到nacos注册中心的配置。

spring:
  cloud:
    nacos:
      discovery:
        register-enabled: true
        server-addr: ${nacos.server}
        namespace: ${nacos.namespace}
    gateway:
      discovery:
        locator:
          enabled: true

nacos:
  server: localhost:8848
  namespace: 21baf036-a74d-4c13-9209-dc69e7c1c1ad

并且断言改成了以下格式,其中lb表示load balance(负载均衡),后面加上我们注册到注册中心的服务名,也就是服务提供者的的spring.application.name配置的值。

lb://服务名称

需要确保gateway和provider都注册到了nacos


好了,文章就分享到这里了,看完不要忘了点赞+收藏哦~


文章的代码已经上传到Gitee,可按需获取~

Spring Boot整合Spring Cloud Gateway案例项目icon-default.png?t=O83Ahttps://gitee.com/muyu-chengfeng/springboot-gateway.git

如果想要更深入学习gateway,可以访问Spring官网Spring Cloud Gateway

### Spring Boot 整合 Spring Cloud Gateway 示例教程 #### 1. 创建 Spring Boot 项目并引入依赖 为了使 Spring Boot 应用程序能够利用 Spring Cloud Gateway 提供的功能,需在项目的 `pom.xml` 文件中添加必要的 Maven 依赖项。这一步骤确保应用程序可以访问到构建 API 网关所需的所有库。 ```xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <!-- 如果使用的是 Spring Cloud Alibaba --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-nacos-discovery</artifactId> </dependency> ``` 注意,在选择具体版本时应遵循官方文档中的兼容性指南[^3]。 #### 2. 配置应用属性文件 编辑 `application.yml` 或者 `application.properties` 来定义网关的行为参数,比如端口号、路由规则等: ```yaml server: port: 8080 spring: cloud: gateway: routes: - id: example_route uri: http://httpbin.org:80 predicates: - Path=/get filters: - AddRequestHeader=Example, Header ``` 这段配置创建了一个简单的路由规则,它会匹配路径 `/get` 的请求并将这些请求转发给指定的目标 URI 同时附加自定义头部信息[^2]。 #### 3. 编写启动类 最后,在主应用程序入口处启用 Spring Cloud Gateway 功能即可完成基本设置: ```java import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` 以上就是将 Spring Boot 和 Spring Cloud Gateway 结合起来的基础方法介绍。通过这种方式建立的应用不仅具备了高效的 HTTP 请求处理能力,还实现了诸如动态路由、流量控制等一系列高级特性[^5]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

沐雨橙风ιε

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

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

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

打赏作者

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

抵扣说明:

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

余额充值