跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava

微服务网关设计与实战:Spring Cloud Gateway 全解析

微服务网关作为微服务架构的核心入口,负责统一路由转发、安全防护及流量控制。基于 Spring Cloud Gateway 详解其核心架构(路由、断言、过滤器),涵盖静态与动态路由配置、JWT 统一认证、全局日志收集、跨域处理等实战功能。同时整合 Sentinel 实现限流熔断,并探讨高可用部署方案与性能优化策略,帮助开发者构建稳定高效的微服务网关系统。

云间运维发布于 2026/2/21更新于 2026/10/17102 浏览
微服务网关设计与实战:Spring Cloud Gateway 全解析

微服务网关设计与实战:Spring Cloud Gateway 全解析

架构图

学习目标与重点

学习目标
  • 理解微服务网关的核心价值、应用场景及主流网关技术对比,掌握 Spring Cloud Gateway 的核心架构与工作原理。
  • 熟练使用 Spring Cloud Gateway 实现路由转发、动态路由、统一认证、限流熔断、日志监控等核心功能。
  • 能够独立设计并搭建高可用、高性能的微服务网关,解决微服务架构中的接口统一管理、安全防护等问题。
  • 掌握网关的性能优化、故障排查方法,结合实际场景进行网关架构设计与落地。
学习重点
  • 微服务网关的核心作用与 Spring Cloud Gateway 的核心组件(路由、断言、过滤器)。
  • 路由规则配置(静态路由、动态路由)与断言工厂的实战应用。
  • 全局过滤器与局部过滤器的开发,实现统一认证、权限校验、请求改写等功能。
  • 网关与 Sentinel、Nacos 的整合,实现限流、熔断、动态配置。
  • 网关的高可用部署与性能优化方案。

微服务网关核心概念与技术选型

微服务网关的核心价值

在微服务架构中,客户端(Web/APP)需要与多个微服务直接通信,会面临接口分散、认证复杂、跨域问题、流量控制困难等挑战。微服务网关作为整个微服务架构的'入口',统一接收客户端请求,再转发到对应的微服务,相当于'流量调度中心'和'安全防护墙'。

微服务网关的核心价值体现在以下 6 个方面:

  1. 统一入口管理:客户端只需对接网关,无需记忆多个微服务的地址,简化客户端开发与维护。例如电商系统中,客户端通过 /api/user/*、/api/order/* 等统一路径访问不同服务,无需关心用户服务、订单服务的具体部署地址。
  2. 路由转发:根据请求路径、请求头、参数等规则,将请求转发到对应的微服务,支持负载均衡、路径重写等功能。
  3. 安全防护:集中处理认证授权、签名校验、防 SQL 注入、防 XSS 攻击等安全策略,避免每个微服务重复开发安全逻辑。
  4. 流量控制:对进入系统的流量进行限流、熔断、降级,保护后端微服务不被流量峰值压垮。
  5. 跨域解决方案:集中处理跨域请求(CORS),无需每个微服务单独配置跨域规则。
  6. 监控与日志:统一收集请求日志、监控请求耗时、错误率等指标,便于问题排查与系统运维。
主流微服务网关技术对比

目前 Java 生态中主流的微服务网关有 3 种:Spring Cloud Gateway、Zuul、Kong,各有优劣,需根据业务场景选型:

技术选型核心优势不足之处适用场景
Spring Cloud Gateway1. 基于 Spring 生态,与 Spring Cloud 无缝整合;
2. 基于 Netty 异步非阻塞,性能优异(吞吐量是 Zuul 的 2-3 倍);
3. 支持动态路由、灵活的断言与过滤器;
4. 原生支持 WebSocket、限流、熔断等功能
1. 仅支持 Spring Boot/Spring Cloud 项目;
2. 学习成本略高于 Zuul
Spring Cloud 生态的微服务项目,对性能要求较高的场景
Zuul(1.x/2.x)1. 简单易用,与 Spring Cloud 整合成熟;
2. 社区成熟,文档丰富;
3. Zuul 2.x 支持异步非阻塞
1. Zuul 1.x 基于 Servlet 同步阻塞,性能较差;
2. 功能扩展性不如 Spring Cloud Gateway
小型微服务项目,对性能要求不高,追求开发效率
Kong1. 基于 Nginx,性能极高,支持高并发;
2. 支持多语言微服务(不局限于 Java);
3. 丰富的插件生态(认证、限流、监控等)
1. 与 Spring Cloud 生态整合不够紧密;
2. 配置复杂,二次开发成本高
多语言混合开发的微服务项目,对性能和并发要求极高的场景

推荐选型:Spring Cloud Gateway 是目前 Spring Cloud 生态的首选网关,兼顾性能、易用性与扩展性,本章重点讲解其设计与实战。

Spring Cloud Gateway 核心架构

Spring Cloud Gateway 基于异步非阻塞模型(Netty+Reactor)实现,核心架构包含 3 个核心组件,流程如下:

客户端请求 → 网关接收请求 → 路由匹配(断言 Predicate) → 过滤器链执行(Filter) → 转发到微服务 → 微服务响应 → 过滤器链反向执行 → 响应客户端
核心组件详解
  1. 路由(Route):网关的基本转发规则,包含 3 个关键信息:
    • 路由 ID(Route ID):唯一标识路由的字符串(如 user-service-route)。
    • 目标 URI(URI):请求最终转发到的微服务地址(如 lb://user-service,lb 表示负载均衡)。
    • 断言集合(Predicate):判断请求是否匹配该路由的条件(如路径匹配 /api/user/**、请求方法为 GET)。
    • 过滤器集合(Filter):请求转发前后执行的逻辑(如添加请求头、权限校验)。
  2. 断言(Predicate):本质是'条件判断函数',Spring Cloud Gateway 内置了多种断言工厂(如路径断言、请求头断言、时间断言),支持组合使用。只有当所有断言都满足时,请求才会匹配对应的路由。
  3. 过滤器(Filter):分为全局过滤器(Global Filter)和局部过滤器(Gateway Filter):
    • 局部过滤器:仅对特定路由生效,需在路由配置中显式引用。
    • 全局过滤器:对所有路由生效,无需配置,常用于统一认证、日志收集等全局功能。
    • 过滤器执行顺序:请求转发前执行'pre'逻辑(如认证、参数校验),微服务响应后执行'post'逻辑(如响应改写、日志记录)。

Spring Cloud Gateway 环境搭建与基础路由配置

环境准备
技术栈选型
  • 开发语言:Java 11
  • 构建工具:Maven 3.6+
  • 框架:Spring Boot 2.7.x、Spring Cloud 2021.0.4、Spring Cloud Gateway 3.1.4
  • 依赖组件:Nacos Discovery(服务发现)、Sentinel(限流熔断)、Spring Security(认证)
  • 开发工具:IntelliJ IDEA、Postman(接口测试)
项目初始化

① 创建 Maven 项目,命名为 gateway-service,引入核心依赖:

<!-- Spring Boot 父依赖 -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.15</version>
    <relativePath/>
</parent>
<!-- Spring Cloud 依赖管理 -->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>2021.0.4</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>
    <!-- Spring Cloud Gateway 核心依赖(注意:排除 spring-boot-starter-web,避免冲突) -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <!-- Nacos 服务发现(用于动态路由,从 Nacos 获取微服务地址) -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        <version>2021.0.4.0</version>
    </dependency>
    <!-- Lombok -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <!-- 日志依赖(SLF4J+Logback) -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-logging</artifactId>
    </dependency>
</dependencies>

⚠️ 注意:Spring Cloud Gateway 基于 Netty 实现,与 Spring MVC 的 spring-boot-starter-web 存在冲突,必须排除 spring-boot-starter-web 依赖,否则启动报错。

② 编写启动类:

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

@SpringBootApplication
@EnableDiscoveryClient // 开启服务发现(从 Nacos 获取微服务列表)
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}

③ 编写基础配置文件 application.yml:

spring:
  application:
    name: gateway-service # 网关服务名称(注册到 Nacos)
  cloud:
    # Nacos 服务发现配置
    nacos:
      discovery:
        server-addr: localhost:8848 # Nacos 地址
    # Gateway 配置
    gateway:
      # 启用服务发现路由(自动从 Nacos 获取微服务,生成路由规则)
      discovery:
        locator:
          enabled: true # 开启服务发现路由
          lower-case-service-id: true # 微服务名称转为小写(如 USER-SERVICE→user-service)
      # 路由规则配置(静态路由,优先级高于服务发现路由)
      routes:
        # 路由 1:用户服务路由
        - id: user-service-route # 路由唯一 ID(自定义,建议与服务名一致)
          uri: lb://user-service # 目标微服务地址(lb 表示负载均衡)
          predicates:
            - Path=/api/user/** # 路径断言:匹配以/api/user/开头的请求
          filters:
            - RewritePath=/api/user/(?<segment>.*), /${segment} # 路径重写:/api/user/1 → /1
        # 路由 2:订单服务路由
        - id: order-service-route
          uri: lb://order-service
          predicates:
            - Path=/api/order/**
          filters:
            - RewritePath=/api/order/(?<segment>.*), /${segment}
server:
  port: 8080 # 网关端口(客户端统一访问 8080 端口)
# 日志配置(打印请求详细日志,便于调试)
logging:
  level:
    org.springframework.cloud.gateway: DEBUG
    org.springframework.web.reactive: INFO
基础路由测试
启动依赖服务

① 启动 Nacos Server(确保 user-service、order-service 已注册到 Nacos)。 ② 启动 user-service(端口 8081)、order-service(端口 8082)。 ③ 启动 gateway-service(端口 8080)。

测试路由转发

使用 Postman 发送请求,验证路由转发功能:

  • 请求地址:http://localhost:8080/api/user/1
  • 预期结果:网关将请求转发到 user-service 的 /1 接口,返回用户信息:
  • 请求地址:http://localhost:8080/api/order/1
  • 预期结果:网关将请求转发到 order-service 的 /1 接口,返回订单信息:

访问订单服务接口:

{"orderId":1695888888888,"userId":1,"username":"张三 1","productName":"Java 编程思想","price":89.0,"count":1,"totalAmount":89.0,"status":"已创建"}

访问用户服务接口:

{"id":1,"username":"张三 1","phone":"13800138001","address":"北京市朝阳区"}

服务发现路由测试:

  • 由于开启了 discovery.locator.enabled=true,网关会自动生成路由:http://localhost:8080/服务名/接口路径
  • 测试地址:http://localhost:8080/user-service/user/1(直接通过服务名访问),返回结果与步骤 1 一致。
核心断言工厂实战

Spring Cloud Gateway 内置了 11 种断言工厂(Predicate Factory),支持根据路径、请求头、请求参数、时间、Cookie 等条件匹配路由。断言工厂的命名格式为 XXXRoutePredicateFactory,配置时只需写前缀(如 Path 对应 PathRoutePredicateFactory)。

常用断言工厂示例

修改 application.yml 中的路由断言配置,演示常用断言的使用:

spring:
  cloud:
    gateway:
      routes:
        - id: user-service-route
          uri: lb://user-service
          predicates:
            # 1. 路径断言(必选,匹配/api/user/**或/user/**)
            - Path=/api/user/**, /user/**
            # 2. 方法断言(仅允许 GET 请求)
            - Method=GET
            # 3. 请求头断言(必须包含 X-Request-Id 请求头)
            - Header=X-Request-Id, \d+ # 正则表达式:X-Request-Id 的值为数字
            # 4. 请求参数断言(可选参数 token,值包含"auth")
            - Query=token, auth.*
            # 5. 时间断言(请求时间在 2024-01-01 之后)
            - After=2024-01-01T00:00:00+08:00[Asia/Shanghai]
          filters:
            - RewritePath=/api/user/(?<segment>.*), /${segment}
            - RewritePath=/user/(?<segment>.*), /${segment}
断言测试

使用 Postman 发送请求,验证断言效果:

  1. 符合所有断言的请求:
    • 请求地址:http://localhost:8080/api/user/1?token=auth123
    • 请求头:X-Request-Id: 123456
    • 请求方法:GET
    • 预期结果:路由匹配成功,返回用户信息。
  2. 不符合断言的请求:
    • 缺少 X-Request-Id 请求头 → 路由不匹配,返回 404。
    • 请求方法为 POST → 路由不匹配,返回 404。
    • token 参数值为 test123(不包含 auth) → 路由不匹配,返回 404。
自定义断言工厂(可选)

若内置断言无法满足需求,可自定义断言工厂。例如,实现一个'IP 白名单'断言,仅允许指定 IP 访问:

① 编写自定义断言工厂:

import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.cloud.gateway.handler.predicate.GatewayPredicate;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.server.ServerWebExchange;
import javax.validation.constraints.NotEmpty;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

// 断言工厂名称:IpWhiteListRoutePredicateFactory → 配置时使用 IpWhiteList
@Component
public class IpWhiteListRoutePredicateFactory extends AbstractRoutePredicateFactory<IpWhiteListRoutePredicateFactory.Config> {
    // 配置类(接收 yaml 中的配置参数)
    @Validated
    public static class Config {
        @NotEmpty(message = "IP 白名单不能为空")
        private List<String> allowedIps;

        public List<String> getAllowedIps() { return allowedIps; }
        public void setAllowedIps(List<String> allowedIps) { this.allowedIps = allowedIps; }
    }

    // 构造方法:指定配置类
    public IpWhiteListRoutePredicateFactory() {
        super(Config.class);
    }

    // 配置参数解析(将 yaml 中的 allowedIps 转为 List<String>)
    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("allowedIps");
    }

    // 断言逻辑:判断请求 IP 是否在白名单中
    @Override
    public GatewayPredicate apply(Config config) {
        return new GatewayPredicate() {
            @Override
            public boolean test(ServerWebExchange exchange) {
                // 获取客户端 IP(实际开发中需处理反向代理场景,如 Nginx 转发)
                ServerHttpRequest request = exchange.getRequest();
                String clientIp = request.getRemoteAddress().getAddress().getHostAddress();
                // 判断 IP 是否在白名单中
                return config.getAllowedIps().contains(clientIp);
            }

            @Override
            public String toString() {
                return "IpWhiteList: " + config.getAllowedIps();
            }
        };
    }
}

② 配置自定义断言:

spring:
  cloud:
    gateway:
      routes:
        - id: user-service-route
          uri: lb://user-service
          predicates:
            - Path=/api/user/**
            - IpWhiteList=127.0.0.1, 192.168.1.100 # 仅允许本地和 192.168.1.100 访问
          filters:
            - RewritePath=/api/user/(?<segment>.*), /${segment}

③ 测试效果:

  • 本地 IP(127.0.0.1)访问 → 正常返回。
  • 其他 IP(如 192.168.1.101)访问 → 路由不匹配,返回 404。

过滤器开发实战:全局功能与局部定制

过滤器分类与执行顺序

Spring Cloud Gateway 的过滤器分为局部过滤器和全局过滤器,核心区别在于作用范围和配置方式:

过滤器类型作用范围配置方式典型场景
局部过滤器特定路由在路由的 filters 节点中配置路径重写、局部限流、特定路由的参数处理
全局过滤器所有路由实现 GlobalFilter 接口,无需配置统一认证、日志收集、跨域处理、全局限流
过滤器执行顺序
  • 局部过滤器:按配置文件中 filters 的顺序执行。
  • 全局过滤器:按 Ordered 接口的 getOrder() 方法返回值排序(值越小,执行优先级越高)。
  • 整体顺序:所有过滤器按优先级排序,'pre'逻辑按顺序执行,'post'逻辑按逆序执行。
局部过滤器实战:路径重写与参数处理

局部过滤器仅对当前路由生效,Spring Cloud Gateway 内置了多种局部过滤器(如路径重写、请求头添加、参数添加等),以下是常用场景实战:

路径重写(RewritePath)

已在基础配置中演示,核心作用是将客户端请求路径改写为微服务的实际路径。例如:

  • 客户端请求:/api/user/1 → 改写为 /1 → 转发到 user-service 的 /1 接口。
  • 配置格式:RewritePath=原始路径正则,目标路径(使用 ${segment} 引用正则分组)。
添加请求头(AddRequestHeader)

为转发到微服务的请求添加固定请求头,例如添加 X-Gateway-Version 标识网关版本:

spring:
  cloud:
    gateway:
      routes:
        - id: user-service-route
          uri: lb://user-service
          predicates:
            - Path=/api/user/**
          filters:
            - RewritePath=/api/user/(?<segment>.*), /${segment}
            - AddRequestHeader=X-Gateway-Version, v1.0.0 # 添加请求头
添加请求参数(AddRequestParameter)

为请求添加固定参数,例如添加 source=gateway 标识请求来源:

filters:
  - AddRequestParameter=source, gateway # 所有转发到 user-service 的请求都会携带 source=gateway 参数
自定义局部过滤器

实现一个局部过滤器,为特定路由的响应添加 X-Response-Time 头,记录请求处理耗时:

① 编写自定义局部过滤器:

import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.Arrays;
import java.util.List;

// 局部过滤器工厂名称:ResponseTimeGatewayFilterFactory → 配置时使用 ResponseTime
@Component
public class ResponseTimeGatewayFilterFactory extends AbstractGatewayFilterFactory<ResponseTimeGatewayFilterFactory.Config> {
    // 配置类(无参数,仅作为标识)
    public static class Config {}

    public ResponseTimeGatewayFilterFactory() {
        super(Config.class);
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList(); // 无配置参数,返回空列表
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            // 1. pre 逻辑:记录请求开始时间
            long startTime = System.currentTimeMillis();
            // 2. 转发请求到微服务
            return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                // 3. post 逻辑:计算耗时,添加响应头
                long duration = System.currentTimeMillis() - startTime;
                exchange.getResponse().getHeaders().add("X-Response-Time", duration + "ms");
            }));
        };
    }
}

② 配置局部过滤器:

spring:
  cloud:
    gateway:
      routes:
        - id: user-service-route
          uri: lb://user-service
          predicates:
            - Path=/api/user/**
          filters:
            - RewritePath=/api/user/(?<segment>.*), /${segment}
            - ResponseTime # 引用自定义局部过滤器

③ 测试效果:

  • 访问 http://localhost:8080/api/user/1,查看响应头,会新增 X-Response-Time: 20ms(耗时根据实际情况变化)。
全局过滤器实战:统一认证与日志收集

全局过滤器对所有路由生效,是实现统一功能的核心手段。以下是两个最常用的全局过滤器实战:

统一认证过滤器(JWT 令牌校验)

微服务架构中,客户端登录成功后获取 JWT 令牌,后续所有请求都需在请求头中携带 Authorization: Bearer {token},网关统一校验令牌有效性,无效则直接返回 401,避免每个微服务重复开发认证逻辑。

① 引入 JWT 依赖:

<!-- JWT 依赖 -->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>0.11.5</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-impl</artifactId>
    <version>0.11.5</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <version>0.11.5</version>
    <scope>runtime</scope>
</dependency>

② 编写 JWT 工具类:

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.crypto.SecretKey;
import java.util.Date;

@Component
public class JwtUtil {
    // JWT 密钥(实际开发中需配置在 Nacos,避免硬编码)
    @Value("${jwt.secret:abcdefghijklmnopqrstuvwxyz1234567890}")
    private String secret;

    // 令牌过期时间(2 小时)
    @Value("${jwt.expire:7200000}")
    private long expire;

    // 生成密钥(HMAC-SHA256 算法要求密钥长度至少 256 位)
    private SecretKey getSecretKey() {
        return Keys.hmacShaKeyFor(secret.getBytes());
    }

    // 生成 JWT 令牌
    public String generateToken(Long userId, String username) {
        return Jwts.builder()
                .setSubject(userId.toString()) // 主题(存储用户 ID)
                .claim("username", username) // 自定义声明(存储用户名)
                .setIssuedAt(new Date()) // 签发时间
                .setExpiration(new Date(System.currentTimeMillis() + expire)) // 过期时间
                .signWith(getSecretKey()) // 签名
                .compact();
    }

    // 校验令牌有效性
    public boolean validateToken(String token) {
        try {
            Jwts.parserBuilder().setSigningKey(getSecretKey()).build().parseClaimsJws(token);
            return true;
        } catch (Exception e) {
            // 令牌过期、签名错误等都会抛出异常
            return false;
        }
    }

    // 解析令牌中的声明
    public Claims parseClaims(String token) {
        return Jwts.parserBuilder().setSigningKey(getSecretKey()).build().parseClaimsJws(token).getBody();
    }
}

③ 编写统一认证全局过滤器:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
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.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {
    @Autowired
    private JwtUtil jwtUtil;

    // 不需要认证的接口(白名单)
    private static final String[] WHITE_LIST = {
        "/api/user/login", // 登录接口
        "/api/user/register", // 注册接口
        "/actuator/health" // 健康检查接口
    };

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, org.springframework.cloud.gateway.filter.GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();

        // 1. 判断请求路径是否在白名单中,若在则直接放行
        String path = request.getPath().value();
        for (String whitePath : WHITE_LIST) {
            if (path.startsWith(whitePath)) {
                return chain.filter(exchange);
            }
        }

        // 2. 从请求头中获取 Authorization 令牌
        String authHeader = request.getHeaders().getFirst("Authorization");
        if (!StringUtils.hasText(authHeader) || !authHeader.startsWith("Bearer ")) {
            // 3. 无令牌或令牌格式错误,返回 401
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }

        // 4. 提取令牌(去掉"Bearer "前缀)
        String token = authHeader.substring(7);
        if (!jwtUtil.validateToken(token)) {
            // 5. 令牌无效,返回 401
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }

        // 6. 令牌有效,解析用户信息,添加到请求头(供微服务使用)
        try {
            String userId = jwtUtil.parseClaims(token).getSubject();
            String username = jwtUtil.parseClaims(token).get("username", String.class);
            // 向请求头添加用户信息(微服务可通过请求头获取,无需再次解析 JWT)
            ServerHttpRequest newRequest = request.mutate()
                    .header("X-User-Id", userId)
                    .header("X-User-Name", username)
                    .build();
            // 替换请求对象
            return chain.filter(exchange.mutate().request(newRequest).build());
        } catch (Exception e) {
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }
    }

    // 过滤器优先级:值越小越先执行(认证过滤器需优先执行)
    @Override
    public int getOrder() {
        return -100;
    }
}

④ 测试认证功能:

  • 假设 user-service 提供登录接口 /api/user/login,传入用户名密码,返回令牌:

获取 JWT 令牌(模拟登录接口,实际开发中由 user-service 实现):

{"code":200,"msg":"登录成功","data":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}
  • 携带令牌访问受保护接口:
    • 请求地址:http://localhost:8080/api/user/1
    • 请求头:Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
    • 预期结果:令牌有效,正常返回用户信息。
  • 不携带令牌或令牌无效:
    • 直接访问 http://localhost:8080/api/user/1 → 返回 401 Unauthorized。
全局日志过滤器

收集所有请求的日志(请求路径、方法、IP、耗时、响应状态等),便于问题排查与系统监控:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
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.UUID;

@Component
public class LogGlobalFilter implements GlobalFilter, Ordered {
    private static final Logger logger = LoggerFactory.getLogger(LogGlobalFilter.class);

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, org.springframework.cloud.gateway.filter.GatewayFilterChain chain) {
        // 1. 生成请求唯一 ID(用于追踪请求链路)
        String requestId = UUID.randomUUID().toString();
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();

        // 2. pre 逻辑:记录请求信息
        long startTime = System.currentTimeMillis();
        String method = request.getMethodValue();
        String path = request.getPath().value();
        String clientIp = request.getRemoteAddress().getAddress().getHostAddress();
        logger.info("【请求开始】requestId: {}, 客户端 IP: {}, 方法:{}, 路径:{}, 请求头:{}", requestId, clientIp, method, path, request.getHeaders());

        // 3. 转发请求,监听响应完成事件
        return chain.filter(exchange).then(Mono.fromRunnable(() -> {
            // 4. post 逻辑:记录响应信息
            long duration = System.currentTimeMillis() - startTime;
            int statusCode = response.getStatusCode().value();
            logger.info("【请求结束】requestId: {}, 响应状态:{}, 耗时:{}ms", requestId, statusCode, duration);
        }));
    }

    // 日志过滤器优先级低于认证过滤器(先认证,再记录日志)
    @Override
    public int getOrder() {
        return -90;
    }
}

启动网关后,访问任意接口,控制台会输出类似日志:

【请求开始】requestId: 550e8400-e29b-41d4-a716-446655440000, 客户端 IP: 127.0.0.1, 方法:GET, 路径:/api/user/1, 请求头:[Authorization:"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", X-Request-Id:"123456"] 【请求结束】requestId: 550e8400-e29b-41d4-a716-446655440000, 响应状态:200, 耗时:35ms
跨域处理(CORS)

当客户端(如前端 Vue 项目)与网关不在同一域名时,会出现跨域请求问题。Spring Cloud Gateway 支持全局配置 CORS,无需每个微服务单独配置:

spring:
  cloud:
    gateway:
      globalcors:
        cors-configurations:
          '[/**]': # 对所有路径生效
            allowed-origins: "*" # 允许所有来源(生产环境建议指定具体域名,如 https://www.example.com)
            allowed-methods: "*" # 允许所有 HTTP 方法(GET、POST、PUT、DELETE 等)
            allowed-headers: "*" # 允许所有请求头
            allow-credentials: true # 允许携带 Cookie
            max-age: 3600 # 预检请求缓存时间(1 小时)

网关高级功能:动态路由、限流熔断与高可用

动态路由(基于 Nacos 配置)

基础路由配置写在 application.yml 中,修改后需重启网关才能生效,无法满足生产环境的动态调整需求。基于 Nacos 实现动态路由,可通过 Nacos 控制台修改路由配置,网关实时感知并生效,无需重启。

集成 Nacos Config

① 引入 Nacos Config 依赖:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    <version>2021.0.4.0</version>
</dependency>

② 创建 bootstrap.yml 文件(加载 Nacos 配置):

spring:
  application:
    name: gateway-service
  cloud:
    nacos:
      config:
        server-addr: localhost:8848 # Nacos 配置中心地址
        file-extension: yaml # 配置文件格式
        namespace: public # 命名空间
        group: DEFAULT_GROUP # 配置分组
        profiles:
          active: dev # 环境标识

③ 在 Nacos 控制台创建配置:

  • Data ID:gateway-service-dev.yaml(格式:服务名 - 环境名。文件扩展名)。
  • 配置格式:YAML。
  • 配置内容(路由规则):
spring:
  cloud:
    gateway:
      routes:
        - id: user-service-route
          uri: lb://user-service
          predicates:
            - Path=/api/user/**
          filters:
            - RewritePath=/api/user/(?<segment>.*), /${segment}
        - id: order-service-route
          uri: lb://order-service
          predicates:
            - Path=/api/order/**
          filters:
            - RewritePath=/api/order/(?<segment>.*), /${segment}
实现动态路由刷新

Spring Cloud Gateway 与 Nacos Config 整合后,默认支持配置动态刷新,但路由规则的刷新需要自定义逻辑(监听 Nacos 配置变更,重新加载路由):

① 编写动态路由配置类:

import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;
import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.Executor;

@Component
public class DynamicRouteConfig implements ApplicationEventPublisherAware {
    @Value("${spring.cloud.nacos.config.server-addr}")
    private String serverAddr;
    @Value("${spring.cloud.nacos.config.namespace}")
    private String namespace;
    @Value("${spring.cloud.nacos.config.group}")
    private String group;
    @Value("${spring.application.name}")
    private String serviceName;
    @Value("${spring.profiles.active}")
    private String activeProfile;

    // 路由定义写入器(用于更新路由)
    @Autowired
    private RouteDefinitionWriter routeDefinitionWriter;

    // 事件发布器(用于发布路由刷新事件)
    private ApplicationEventPublisher applicationEventPublisher;

    // Nacos 配置服务
    private ConfigService configService;

    // 配置 Data ID
    private String dataId;

    @PostConstruct
    public void init() throws NacosException {
        // 初始化 Data ID
        dataId = serviceName + "-" + activeProfile + ".yaml";
        // 初始化 Nacos ConfigService
        Properties properties = new Properties();
        properties.put("serverAddr", serverAddr);
        properties.put("namespace", namespace);
        configService = NacosFactory.createConfigService(properties);
        // 加载初始路由配置
        loadRouteConfig();
        // 注册 Nacos 配置监听器(监听配置变更)
        configService.addListener(dataId, group, new Listener() {
            @Override
            public void receiveConfigInfo(String configInfo) {
                // 配置变更时,重新加载路由
                loadRouteConfig();
            }

            @Override
            public Executor getExecutor() {
                return null;
            }
        });
    }

    // 加载路由配置(简化版:实际开发中需解析 YAML 为 RouteDefinition 列表)
    private void loadRouteConfig() {
        try {
            // 从 Nacos 获取配置
            String config = configService.getConfig(dataId, group, 5000);
            if (org.springframework.util.StringUtils.hasText(config)) {
                // 解析 YAML 配置为 RouteDefinition 列表(此处省略解析逻辑,推荐使用 SnakeYAML)
                // 假设解析后得到 List<RouteDefinition> routeDefinitionsList
                List<RouteDefinition> routeDefinitions = parseYamlToRouteDefinitions(config);
                // 1. 删除所有现有路由
                routeDefinitionWriter.delete(Mono.just("user-service-route")).subscribe();
                routeDefinitionWriter.delete(Mono.just("order-service-route")).subscribe();
                // 2. 添加新路由
                for (RouteDefinition routeDefinition : routeDefinitions) {
                    routeDefinitionWriter.save(Mono.just(routeDefinition)).subscribe();
                }
                // 3. 发布路由刷新事件
                applicationEventPublisher.publishEvent(new RefreshRoutesEvent(this));
                System.out.println("动态路由更新成功!");
            }
        } catch (Exception e) {
            System.err.println("动态路由更新失败:" + e.getMessage());
        }
    }

    // 解析 YAML 配置为 RouteDefinition 列表(实际开发中需实现)
    private List<RouteDefinition> parseYamlToRouteDefinitions(String config) {
        // 此处使用 Spring 的 YamlPropertiesFactoryBean 解析 YAML,转换为 RouteDefinition
        // 简化示例,实际需根据配置结构编写解析逻辑
        return null;
    }

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }
}

⚠️ 注意:实际开发中,parseYamlToRouteDefinitions 方法需使用 SnakeYAML 或 Spring 的 YamlPropertiesFactoryBean 解析 Nacos 中的 YAML 配置,将其转换为 List<RouteDefinition> 对象,确保路由规则正确加载。

测试动态路由
  1. 在 Nacos 控制台修改 gateway-service-dev.yaml,新增一个商品服务路由:
- id: product-service-route
  uri: lb://product-service
  predicates:
    - Path=/api/product/**
  filters:
    - RewritePath=/api/product/(?<segment>.*), /${segment}
  1. 点击'发布',网关控制台输出'动态路由更新成功!'。
  2. 访问 http://localhost:8080/api/product/1,网关会自动转发到 product-service,无需重启网关。
网关限流与熔断(整合 Sentinel)

网关作为流量入口,需要对进入系统的流量进行限流,避免后端微服务被压垮;同时,当后端微服务故障时,网关需要实现熔断,直接返回降级响应,避免故障扩散。Spring Cloud Gateway 与 Sentinel 整合,可快速实现限流与熔断功能。

集成 Sentinel 依赖
<!-- Sentinel 核心依赖 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    <version>2021.0.4.0</version>
</dependency>
<!-- Sentinel 与 Gateway 整合依赖 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
    <version>2021.0.4.0</version>
</dependency>
<!-- Sentinel 控制台通信依赖 -->
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-transport-simple-http</artifactId>
    <version>1.8.6</version>
</dependency>
配置 Sentinel
spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080 # Sentinel 控制台地址(注意:与网关端口冲突时需修改 Sentinel 端口)
        port: 8720 # 与 Sentinel 控制台通信的端口(默认 8719,避免冲突)
      # 网关限流配置
      scg:
        fallback:
          mode: response # 降级模式:返回自定义响应
          response-status: 429 # 降级响应状态码
          response-body: '{"code":429,"msg":"当前请求过于频繁,请稍后再试!"}' # 降级响应体

⚠️ 注意:Sentinel 控制台默认端口为 8080,与网关端口冲突,需修改 Sentinel 启动命令:

java -jar sentinel-dashboard-1.8.6.jar --server.port=8083

修改后 Sentinel 控制台地址为 http://localhost:8083,网关配置中的 spring.cloud.sentinel.transport.dashboard 需同步修改为 localhost:8083。

配置网关限流规则(Sentinel 控制台)
  1. 启动网关、Sentinel 控制台,访问网关接口(如 http://localhost:8080/api/user/1),触发 Sentinel 监控。
  2. 访问 Sentinel 控制台→网关限流→新增网关流控规则:
    • 资源名称:/api/user/**(路由路径)。
    • 限流指标:QPS。
    • 单机阈值:5(每秒最多允许 5 个请求)。
    • 其他默认,点击'新增'。
测试限流效果

快速访问 http://localhost:8080/api/user/1(每秒超过 5 次),网关返回自定义降级响应:

{"code":429,"msg":"当前请求过于频繁,请稍后再试!"}
配置网关熔断规则

当后端微服务(如 user-service)故障时,网关熔断,避免频繁调用失败:

  1. 在 Sentinel 控制台→熔断规则→新增熔断规则:
    • 资源名称:lb://user-service(微服务名称)。
    • 熔断策略:慢调用比例。
    • 最大 RT:1000ms(超过 1 秒视为慢调用)。
    • 慢调用比例阈值:0.5(慢调用占比超过 50%)。
    • 熔断时长:10s。
    • 最小请求数:5。
  2. 故意修改 user-service 的接口,添加 2 秒延迟:
@GetMapping("/user/{id}")
public User getUserById(@PathVariable Long id) throws InterruptedException {
    Thread.sleep(2000); // 模拟慢调用
    // 其余逻辑不变
}
  1. 快速访问 http://localhost:8080/api/user/1(超过 5 次),触发熔断,网关返回降级响应。
网关高可用部署

网关作为微服务架构的入口,一旦单点故障,整个系统将无法对外提供服务。因此,生产环境必须部署多个网关实例,配合负载均衡器(如 Nginx)实现高可用。

高可用架构图
客户端 → Nginx(负载均衡) → 网关实例 1(8080) → 微服务集群
                      → 网关实例 2(8081) → 微服务集群
                      → 网关实例 3(8082) → 微服务集群
部署步骤
  1. 启动多个网关实例:
    • 实例 1:java -jar gateway-service.jar --server.port=8080
    • 实例 2:java -jar gateway-service.jar --server.port=8081
    • 实例 3:java -jar gateway-service.jar --server.port=8082
    • 所有实例注册到 Nacos,自动实现服务发现与负载均衡。
  2. 配置 Nginx 负载均衡: 编辑 Nginx 配置文件 nginx.conf:
http {
    # 网关集群配置
    upstream gateway_cluster {
        server 127.0.0.1:8080 weight=1; # 权重 1
        server 127.0.0.1:8081 weight=1; # 权重 1
        server 127.0.0.1:8082 weight=1; # 权重 1
    }
    server {
        listen 80; # Nginx 监听 80 端口(客户端统一访问 80 端口)
        server_name localhost;
        location / {
            # 转发请求到网关集群
            proxy_pass http://gateway_cluster;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }
}
  1. 测试高可用:
    • 客户端访问 http://localhost/api/user/1(Nginx 端口 80),Nginx 会将请求转发到任意一个网关实例。
    • 关闭其中一个网关实例(如 8080),客户端请求仍能正常响应(Nginx 自动转发到其他实例)。

网关性能优化与故障排查

性能优化方案
基础优化
  1. 使用异步非阻塞模型:Spring Cloud Gateway 默认基于 Netty 异步非阻塞,无需额外配置,避免使用同步过滤器(如依赖 Spring MVC 的组件)。
  2. 调整 Netty 参数:
spring:
  cloud:
    gateway:
      httpclient:
        pool:
          max-idle-time: 60000 # 连接池最大空闲时间(60 秒)
          max-connections: 1000 # 每个路由的最大连接数
        response-timeout: 5000 # 响应超时时间(5 秒)
  1. 启用连接复用:开启 HTTP/2 协议,支持连接复用,提升并发性能:
server:
  http2:
    enabled: true # 启用 HTTP/2
  1. 减少不必要的过滤器:仅保留核心功能过滤器(如认证、日志),避免过滤器链过长导致性能损耗。
缓存优化
  • 对高频访问的静态资源(如图片、文档)或查询接口,在网关层添加缓存(如使用 Redis),减少对后端微服务的请求。
  • 示例:使用 spring-cloud-gateway-cache 组件实现网关缓存(需额外引入依赖)。
限流优化
  • 限流规则优先使用 Sentinel 的本地限流,避免分布式限流带来的网络开销。
  • 对不同路由配置不同的限流阈值,根据微服务的处理能力动态调整。
故障排查方法
日志排查
  • 开启 Gateway DEBUG 日志,打印请求转发细节:
logging:
  level:
    org.springframework.cloud.gateway: DEBUG
    org.springframework.http.server.reactive: DEBUG
    reactor.netty: DEBUG
  • 关键日志包括:路由匹配过程、过滤器执行顺序、请求转发地址、响应状态等。
监控排查
  • 集成 Spring Boot Actuator,暴露网关监控指标:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
management:
  endpoints:
    web:
      exposure:
        include: gateway, health, info # 暴露 gateway 监控端点
  endpoint:
    gateway:
      enabled: true # 启用网关监控
  • 访问 http://localhost:8080/actuator/gateway/routes,查看当前路由配置;访问 http://localhost:8080/actuator/gateway/globalfilters,查看全局过滤器。
常见问题与解决方案
常见问题解决方案
路由匹配失败(404)1. 检查路由 Path 断言是否正确;
2. 检查微服务是否已注册到 Nacos;
3. 开启 discovery.locator.enabled=true,测试服务名路由
跨域请求失败(CORS)检查网关全局 CORS 配置,确保 allowed-origins、allowed-methods 配置正确
认证失败(401)1. 检查 JWT 令牌是否有效;
2. 检查请求头 Authorization 格式是否正确(Bearer + 空格 + 令牌);
3. 检查白名单配置是否包含当前路径
限流熔断不生效1. 检查 Sentinel 依赖是否完整;
2. 确认已访问网关接口触发 Sentinel 监控;
3. 检查 Sentinel 控制台规则配置是否正确
网关响应缓慢1. 排查后端微服务响应时间;
2. 检查过滤器链是否过长;
3. 调整 Netty 连接池参数

本章总结

✅ 本章详细讲解了微服务网关的核心价值、Spring Cloud Gateway 的核心架构与实战应用,从基础路由配置到高级功能(动态路由、统一认证、限流熔断、高可用部署),完整覆盖了网关的设计与落地流程。

通过本章学习,读者应掌握:

  1. 微服务网关的核心作用与 Spring Cloud Gateway 的三大核心组件(路由、断言、过滤器)。
  2. 局部过滤器与全局过滤器的开发,实现路径重写、统一认证、日志收集等功能。
  3. 基于 Nacos 的动态路由与基于 Sentinel 的限流熔断实现。
  4. 网关的高可用部署、性能优化与故障排查方法。

网关作为微服务架构的'入口',是系统安全防护、流量控制的关键环节。下一章将讲解微服务监控与运维体系,包括 Prometheus + Grafana 监控指标收集、ELK 日志分析、SkyWalking 链路追踪等内容,帮助读者构建完整的微服务运维体系。

目录

  1. 微服务网关设计与实战:Spring Cloud Gateway 全解析
  2. 学习目标与重点
  3. 学习目标
  4. 学习重点
  5. 微服务网关核心概念与技术选型
  6. 微服务网关的核心价值
  7. 主流微服务网关技术对比
  8. Spring Cloud Gateway 核心架构
  9. 核心组件详解
  10. Spring Cloud Gateway 环境搭建与基础路由配置
  11. 环境准备
  12. 技术栈选型
  13. 项目初始化
  14. 日志配置(打印请求详细日志,便于调试)
  15. 基础路由测试
  16. 启动依赖服务
  17. 测试路由转发
  18. 核心断言工厂实战
  19. 常用断言工厂示例
  20. 断言测试
  21. 自定义断言工厂(可选)
  22. 过滤器开发实战:全局功能与局部定制
  23. 过滤器分类与执行顺序
  24. 过滤器执行顺序
  25. 局部过滤器实战:路径重写与参数处理
  26. 路径重写(RewritePath)
  27. 添加请求头(AddRequestHeader)
  28. 添加请求参数(AddRequestParameter)
  29. 自定义局部过滤器
  30. 全局过滤器实战:统一认证与日志收集
  31. 统一认证过滤器(JWT 令牌校验)
  32. 全局日志过滤器
  33. 跨域处理(CORS)
  34. 网关高级功能:动态路由、限流熔断与高可用
  35. 动态路由(基于 Nacos 配置)
  36. 集成 Nacos Config
  37. 实现动态路由刷新
  38. 测试动态路由
  39. 网关限流与熔断(整合 Sentinel)
  40. 集成 Sentinel 依赖
  41. 配置 Sentinel
  42. 配置网关限流规则(Sentinel 控制台)
  43. 测试限流效果
  44. 配置网关熔断规则
  45. 网关高可用部署
  46. 高可用架构图
  47. 部署步骤
  48. 网关性能优化与故障排查
  49. 性能优化方案
  50. 基础优化
  51. 缓存优化
  52. 限流优化
  53. 故障排查方法
  54. 日志排查
  55. 监控排查
  56. 常见问题与解决方案
  57. 本章总结

更多推荐文章

查看全部
  • Python 内置函数 range、repr、reversed、round 用法详解
  • MySQL 联合查询实战:多表关联与子查询详解
  • HomeAssistant 接入海尔智家设备的实操笔记
  • Prompt Engineering 入门与实战:基于 Node.js 的 LLM 应用开发
  • Ubuntu 24.04 安装 OpenClaw 时 systemctl is-enabled 报错解决
  • 2026 年主流 AI 新模型及国内中转 API 价格对比
  • Vue3 项目实战:Axios 基础封装与接口调用
  • Qwen2.5-7B 与 Stable Diffusion 多模态协同部署实战
  • PromptWizard 自动优化框架与 Level-Navi Agent 搜索代理实现思路
  • Taipy:基于 Python 的数据科学应用开发框架
  • 微信小程序从 0 到 1 开发部署全流程指南
  • 大模型集成演进:从 Function Calling 到 MCP
  • 使用 llama.cpp 在本地运行大模型:Mac 和 Linux 实操记录
  • Python 之父 Guido Van Rossum 宣布从 Dropbox 退休
  • 配置 Obsidian Git 插件实现笔记数据同步到 GitHub 仓库
  • Python 调用百度智能云 API 进行文本情感分析
  • 昇腾 CANN 学习路径指南:Python、C++ 与算子开发选型
  • Web 后端安全系列:PHP 基础语法与序列化
  • JAVAXXIX17 编码规则解析与 Java 实现
  • Mac M系列芯片适配:mlc-llm与llama.cpp对比

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online