SpringCloud Gateway路由组件详解

 更新时间:2023年02月22日 08:46:34   作者:尚少  
SpringCloud Gateway 是 Spring Cloud 的一个全新项目,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。这篇文章主要介绍了SpringCloud Gateway网关作用,需要的朋友可以参考下

简介

  Gateway是SpringCloud Alibaba中的路由组件(前身是Zuul),作为浏览器端请求的统一入口。当项目采用微服务模式时,若包含了路由模块,浏览器端的请求都不会直接请求含有业务逻辑的各个业务模块,而是请求这个路由模块,然后再由它来转发到各个业务模块去。

核心概念

  Gateway中的三个核心概念:路由、断言(Predicate)、过滤器。

  路由:由唯一id、目的url、断言和过滤组成

  断言:即路由规则,用来判断哪些请求符合规则,符合的请求进行转发

  过滤器:分为GatewayFilter和GlobalFilter,前者作用于单一路由,后者作用于所有路由。过滤器可以对请求或者返回进行处理,如增加请求头、删除请求头

  配置文件如下:

spring:
  cloud:
    gateway:
      # 网关路由配置
      routes:
        # 路由id,自定义,只要唯一即可
        - id: user-service
          # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址
          # 路由的目标地址 lb就是负载均衡,后面跟服务名称,要和nacos的注册中心结合
          uri: lb://userservice
          # 断言
          predicates:
              # 这个是按照路径匹配,只要以/user/开头就符合要求
            - Path=/user/**
          # 过滤器
          filters:
              # 添加请求头
            - AddRequestHeader=sign, xn2001.com is eternal

  上面写到了根据路径匹配的断言,Gateway提供了十几种内置的断言:

名称说明示例
After是某个时间点之后的请求- After=2022-08-26T18:34:10.475+08:00[Asia/Shanghai]
Before是某个时间点之前的请求- Before=2022-11-26T18:34:10.475+08:00[Asia/Shanghai]
Between是某两个时间点之前的请求- Between=2022-10-26T18:35:15.093+08:00[Asia/Shanghai], 2022-11-26T18:35:15.093+08:00[Asia/Shanghai]
Cookie请求必须包含某些cookie- Cookie=chocolate, ch.p
Header请求必须包含某些header- Header=sign, internal
Host请求必须是访问某个host(域名)- Host=**.somehost.org, **.anotherhost.org
Method请求方式必须是指定方式- Method=GET,POST
Path请求路径必须符合指定规则- Path=/blue/**
Query请求参数必须包含指定参数- Query=name, Jack或- Query=name
RemoteAddr请求者的ip必须是指定范围- RemoteAddr=192.168.1.1/24
Weight权重处理

  配置中的AddRequestHeader就是其中一种Gateway Filter,还有其余的内置的:

名称说明
AddRequestHeader给当前请求添加一个请求头
RemoveRequestHeader移除请求中的一个请求头
AddResponseHeader给响应结果中添加一个响应头
RemoveResponseHeader从响应结果中移除一个响应头
RequestRateLimiter限制请求的流量

  全局过滤器,后面的示例给出具体用法

具体示例

  这里新建2个模块,路由模块和用户模块

  用户模块,引入依赖spring-boot-starter-web、spring-cloud-starter-alibaba-nacos-discovery,bootstrap.yml配置端口号、nacos注册中心的地址,并提供接口:

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/user")
public class UserController {
    @ResponseBody
    @RequestMapping("/sayHello")
    public String sayHello(@RequestHeader(value = "sign", 
    required = false) String sign) {
        return "这是好吃的:" + sign;
    }
}

  路由模块,引入依赖:

<dependencies>                                                               
    <dependency>                                                             
        <groupId>com.alibaba.cloud</groupId>                                 
        <artifactId>spring-cloud-starter-alibaba-nacos-config
        </artifactId>   
        <version>2.2.0.RELEASE</version>                                     
    </dependency>                                                            
    <dependency>                                                             
        <groupId>com.alibaba.cloud</groupId>                                 
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery
        </artifactId>
        <version>2.2.0.RELEASE</version>                                     
    </dependency>                                                            
    <dependency>                                                             
        <groupId>org.springframework.cloud</groupId>                         
        <artifactId>spring-cloud-starter-gateway</artifactId>                
        <version>2.2.0.RELEASE</version>                                     
    </dependency>                                                            
    <dependency>                                                             
        <groupId>org.projectlombok</groupId>                                 
        <artifactId>lombok</artifactId>                                      
    </dependency>                                                            
</dependencies>                                                              

  bootstrap.yml的配置:

server:
  port: 8086
  servlet:
    context-path: /gateway

spring:
  application:
    name: gateway
  profiles:
    active: dev
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848
        file-extension: yml
      discovery:
        server-addr: 127.0.0.1:8848

  2个模块都启动后,nacos的服务列表显示:

  nacos中新建名为gateway-dev.yml的配置,内容为:

spring:
  cloud:
    gateway:
      discovery:
        locator:
          # 通过服务名称转发,默认false
          enabled: true
          # 服务名称不用大写
          lower-case-service-id: true
      # routes:
      #   - id: user-service
      #     uri: lb://supplier
      #     predicates:
      #       - Path=/provider/**
      #     filters:
      #       - AddRequestHeader=sign, big JavaCoder

  此时,请求路径:http://localhost:8086/supplier/provider/user/sayHello

  注:supplier是服务名称,provider是模块访问路径(server.servlet.context-path)

但这种配置不是很推荐

  把spring.cloud.gateway.discovery及子配置注释掉,把spring.cloud.gateway.routes及子配置取消注释,重启路由模块,这时访问路径:

http://localhost:8086/provider/user/sayHello

  注:这是访问的路径,经过gateway处理后,实际访问的是lb://supplier/provider/user/sayHello(见RouteToRequestUrlFilter的filter方法);provider是模块访问路径(server.servlet.context-path),如果用户模块没有设置的话,filters下添加- StripPrefix=1,这时访问路径不变,实际的访问路径是lb://supplier/user/sayHello。

GlobalFilter

  处理一切进入网关的请求和响应,并且也是可以编写代码自定义逻辑;在执行顺序上,GatewayFilter先执行,GlobalFilter后执行。

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.List;
@Component
public class AuthorizeFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, 
    GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        HttpHeaders headers = request.getHeaders();
        List<String> sign = headers.get("sign");
        if(sign.size() < 1) {
            ServerHttpResponse response = exchange.getResponse();
            response.setStatusCode(HttpStatus.BAD_REQUEST);
            //被拦截,请求不到对应模块了
            return exchange.getResponse().setComplete();
        }
        headers = HttpHeaders.writableHttpHeaders(headers);
        headers.set("sign1", "bigAAA");
        //放行
        return chain.filter(exchange);
    }
}

到此这篇关于SpringCloud Gateway路由组件详解的文章就介绍到这了,更多相关SpringCloud Gateway内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • spring boot实现在request里解密参数返回

    spring boot实现在request里解密参数返回

    这篇文章主要介绍了Spring Boot实现在request里解密参数返回操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • SpringSecurityOAuth2实现微信授权登录

    SpringSecurityOAuth2实现微信授权登录

    微信的登录功能是用户注册和使用微信的必经之路之一,而微信授权登录更是方便了用户的登录操作,本文主要介绍了SpringSecurityOAuth2实现微信授权登录,感兴趣的可以了解一下
    2023-09-09
  • Java使用Hutool实现AES、DES加密解密的方法

    Java使用Hutool实现AES、DES加密解密的方法

    本篇文章主要介绍了Java使用Hutool实现AES、DES加密解密的方法,具有一定的参考价值,有兴趣的可以了解一下
    2017-08-08
  • 详解Java如何实现企业微信审批流程

    详解Java如何实现企业微信审批流程

    这篇文章主要使用了一个Java示例代码,来向大家展示如何在企业微信中实现审批流程,文中的示例代码简洁易懂,有需要的小伙伴可以参考下
    2024-11-11
  • Java中超高频常见字符操作合集(建议收藏)

    Java中超高频常见字符操作合集(建议收藏)

    这篇文章主要为大家详细介绍了Java中超高频常见字符操作合集,文中的示例代码讲解详细,对我们学习java有一定的帮助,需要的小伙伴可以参考下
    2023-10-10
  • Spring时间戳(日期)格式转换方式

    Spring时间戳(日期)格式转换方式

    这篇文章主要介绍了Spring时间戳(日期)格式转换方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-03-03
  • Java中处理金额计算之使用Long还是BigDecimal详解

    Java中处理金额计算之使用Long还是BigDecimal详解

    在Java后端开发中处理与钱有关的业务时,确保金额计算的准确性和避免错误非常重要,这篇文章主要给大家介绍了关于Java中处理金额计算之使用Long还是BigDecimal的相关资料,需要的朋友可以参考下
    2024-07-07
  • mybatis如何实现saveOrUpdate

    mybatis如何实现saveOrUpdate

    这篇文章主要介绍了mybatis如何实现saveOrUpdate问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • Java 实现一个汉诺塔实战练习

    Java 实现一个汉诺塔实战练习

    汉诺塔是源于印度一个古老传说的益智玩具。大梵天创造世界时做了三根石柱,在一根柱子上从下往上按大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,三根柱子之间一次只能移动一个圆盘
    2021-10-10
  • 详解Java线程中断知识点

    详解Java线程中断知识点

    在本篇文章中我们给大家分享了关于Java线程中断的相关知识点内容以及相关代码实例,有兴趣的朋友们可以学习下。
    2018-09-09

最新评论