【Spring Cloud Gateway 实战系列】进阶篇:过滤器高级用法、动态路由配置与性能优化

一、过滤器高级用法:从基础到复杂场景

1.1 过滤器执行顺序深度解析

Spring Cloud Gateway的过滤器执行顺序由Order接口控制,数值越小优先级越高。全局过滤器(GlobalFilter)需通过GatewayFilterAdapter适配为局部过滤器,默认过滤器(default-filters)优先级高于局部过滤器。

1.1.1 顺序控制示例
java 复制代码
@Component
@Order(1) // 优先级高于默认过滤器
public class AuthFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 鉴权逻辑
        return chain.filter(exchange);
    }
}
1.1.2 异步处理优化

利用WebFlux的异步特性,避免阻塞线程:事件驱动 + 非阻塞

java 复制代码
@Component
public class AsyncLogFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        return chain.filter(exchange)   // ① 把请求继续往后传递
        .then(Mono.fromRunnable(() -> {
            //  ② 在响应已经发送给客户端之后,再异步记日志
        }));
    }
}
  • ① 把请求交给下游 Filter / 微服务,这一步只是注册回调,EventLoop 立即返回。
  • ② then(...) 的语义是:等 ①的 Mono 完成(onComplete) 后,再执行日志任务。 如果日志是磁盘 IO,这个 Runnable 会被提交到 Reactor的 boundedElastic Scheduler(自带线程池),不会占用宝贵的 EventLoop。

一句话总结:WebFlux 用"事件回调 + 少量 EventLoop 线程"取代"一条请求独占一条线程"的模型,任何耗时操作都被异步化,从而避免线程被阻塞,提升吞吐量和资源利用率。


这里解释一下WebFlux(基于 Reactor 的响应式编程模型)的由来:

  • 由来:"WebFlux"这个名字其实是两部分拼成的:
    • Web:表示它是一个Web 框架,用来处理HTTP、WebSocket、SSE(服务器推送事件)等网络通信。
    • Flux:来自 Reactor 项目 中的核心类 Flux(还有Mono),Reactor 是 Spring 5 中引入的响应式编程库,专门用来支持非阻塞、异步、事件驱动的编程模型。
  • 换句话说,Spring 给这个新模块起名 spring-webflux,是为了强调它基于 Reactor 的响应式编程模型,区别于传统的Spring MVC(基于 Servlet 的同步阻塞模型)。 所以,"WebFlux"其实就是"Web +Flux",既表达了用途(Web),也点明了底层技术(Reactor Flux)。

与传统的 Spring MVC(基于 Servlet的同步阻塞模型)有啥区别?

  • 传统 Servlet(SpringMVC)为什么会被"阻塞"
    • 每个请求进来,容器(Tomcat 等)会 从线程池里拿一条工作线程去跑整个 Filter→Servlet→Controller→Service→DAO 的调用链。
    • 只要业务代码里出现一次Thread.sleep()、一次 JDBC 查询、一次 HTTP 调用,这条线程就一直被占用,直到方法返回。
    • 线程被卡住期间,它既不能服务别的请求,也无法被回收,于是:
      • 并发量受线程池上限限制(几百条就到顶了)。
      • CPU 空转,资源利用率低。
  • WebFlux(Reactor-Netty)如何做到"不阻塞 "?
    • 事件循环 + 少量线程
      • Netty 启动 数量 = CPU 核数 的一组 EventLoop 线程,每条线程维护一个 Selector,不断轮询 IO 事件(连接、可读、可写)
      • 当业务代码需要读写网络、文件、数据库时,Reactor 会注册一个回调;当前线程立即返回 EventLoop ,去处理别的 IO 事件,不等人。
    • 链式异步(Mono/Flux)
      • Mono.fromRunnable(...) 只是把"记日志"这个动作包装成一个Runnable 任务 ,Reactor 会把它提交给 调度器(Scheduler) 里的某个线程池。
      • 这样,主 EventLoop 线程不会被日志 IO 卡住,日志任务在后台慢慢写即可。

1.2 自定义过滤器链设计

1.2.1 组合过滤器实现复杂逻辑
yaml 复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: complex-route
          uri: lb://service		#1️⃣
          predicates:
            - Path=/api/**		 #2️⃣
          filters:
            - AddRequestHeader=X-Request-Id,${random.uuid}#3️⃣
            - RequestRateLimiter # 限流 4️⃣
            - CircuitBreaker # 熔断	5️⃣
编号 说明
1️⃣ lb://service ------ 把"去哪儿"这件事交给 Spring Cloud LoadBalancer 。Gateway 不会写死 IP 端口,而是拿着服务名 service 去注册中心拉实例,再按负载均衡算法挑一个真正的目标地址。这样下游扩缩容、节点上下线对网关完全透明。
2️⃣ 只有命中 /api/** 的请求才会走进这条路由;其余请求会被其他 route 处理或者直接 404。
3️⃣ AddRequestHeader 是一个 内置局部过滤器 ,给向下游转发的 HTTP 请求头里塞一个 UUID 作为 X-Request-Id。整个调用链(网关→微服务→日志系统→链路追踪)都能拿到同一份 requestId,排查问题时按 ID 一搜到底。
4️⃣ RequestRateLimiter(内置)对接 Redis,实现 令牌桶限流
5️⃣ CircuitBreaker(内置)用的是 Resilience4j。当下游实例异常比例或响应时间超过阈值时自动熔断,快速失败,保护后端。熔断结束后自动半开探测,恢复流量。

小结:一条路由把「加标→限流→熔断→转发」串成了一个 可观测、可保护、可弹性伸缩 的完整链路。

1.2.2 多维度限流策略
yaml 复制代码
filters:
  - name: RequestRateLimiter
    args:
      key-resolver: "#{@ipAndPathKeyResolver}"   # 1️⃣
      redis-rate-limiter.replenishRate: 10       # 2️⃣
      redis-rate-limiter.burstCapacity: 20       # 3️⃣
编号 说明
1️⃣ 把限流的 Key 从默认的「单一 IP」升级成「IP + 请求路径」。同一个 IP 访问不同接口互不干扰,比粗暴的全局限流更精细。
2️⃣ replenishRate = 10:令牌桶每秒匀速补充 10 个令牌,也就是 平均 QPS 上限 10
3️⃣ burstCapacity = 20:桶里最多攒 20 个令牌,允许突发流量一次性拿走 20 个,随后被匀速 10/s 限住。既能抗小尖峰,又不会把后端打挂。
java 复制代码
@Component
public class IpAndPathKeyResolver implements KeyResolver {
    @Override
    public Mono<String> resolve(ServerWebExchange exchange) {
        String ip = exchange.getRequest().getRemoteAddress().getHostString();
        String path = exchange.getRequest().getPath().value();
        return Mono.just(ip + path);
    }
}
  • 为什么是 Mono?
    • Gateway 运行时完全基于 Reactor;KeyResolver 接口设计为Mono,天然支持异步场景。例如后续你如果想把 IP 换成调用方 ID(需要查 Redis 或数据库),直接返回Mono.fromFuture(...) 即可,不会阻塞 EventLoop 线程。
  • 返回值格式
    • 这里简单地 ip + path,生产里可以拼成 ip:path 或 ip#path,只要保证 唯一且可读 即可。Redis 会拿这个字符串做key,过期时间与令牌桶窗口对齐。

落地效果

  • 每个 /api/** 请求都会带上 X-Request-Id,日志、链路追踪、灰度回滚都靠它。
  • 同一 IP 访问 /api/order 和/api/user 分别计数,互不抢占配额。
  • 瞬时并发 20 以内秒过,超过 10/s 的持续流量会被匀速放行,后端不会被打穿。
  • 下游实例故障时,熔断器 5 秒内打开,直接返回 503 / 自定义降级,保护系统。

二、动态路由配置:从静态到动态管理

2.1 基于Nacos的动态路由

2.1.1 动态路由配置示例
  1. Nacos配置文件(gateway-routes.yaml)
yaml 复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: product-service           # 1️⃣
          uri: lb://product-service     # 2️⃣
          predicates:
            - Path=/api/product/**      # 3️⃣
          filters:
            - StripPrefix=1             # 4️⃣
编号 说明
1️⃣ 路由的唯一身份证,Gateway 内部用 id 做索引;以后想改这条路由,只需改同 id 的配置即可。
2️⃣ 目标写成 lb://product-service,Gateway 会拿服务名去 Nacos/Consul/Eureka 查实例,再按负载均衡挑一个真实 IP:Port。下游扩缩容无感知。
3️⃣ 只有 URI 以 /api/product/ 开头的请求才会命中本路由;例如 /api/product/123 会被选中,而 /api/order/456 不会。
4️⃣ StripPrefix=1 表示把路径里第一级 /api 去掉再转发,所以下游收到的是 /product/123,而不是 /api/product/123

把这段文件单独丢进 Nacos 配置中心,而不是写在本地 application.yml,是实现 "配置与代码分离" 的第一步。

  • 网关服务加载配置
yaml 复制代码
spring:
  cloud:
    config:
      import: "optional:nacos:gateway-routes.yaml"
  • optional:nacos: 前缀告诉 Spring Cloud Config:
    • "启动时去 Nacos 拉一个叫gateway-routes.yaml 的配置文件,如果拉不到也不报错(optional),继续启动。
  • " 拉取成功后,Gateway 会把文件里的 spring.cloud.gateway.routes 覆盖/合并 到内存中的路由表,效果等同本地写死,但后期改路由无需重启网关。
  • 动态刷新路由(手动触发)
bash 复制代码
curl -X POST http://localhost:8080/actuator/gateway/refresh
  • Gateway 内置的 Actuator Endpoint。
  • 当你在 Nacos 控制台改了gateway-routes.yaml(增删改路由)并发布后,执行这条命令即可让网关 秒级重新加载 路由表,无需重启进程
  • 生产环境可配合Nacos 的监听器自动调用此接口,实现 完全无人工介入 的热更新。

关于:【生产环境可配合Nacos 的监听器自动调用此接口,实现 完全无人工介入 的热更新】

最简单、最偷懒的做法:Nacos SDK 自带的「配置监听」+ 一行 HTTP 调用,10 行代码就能跑。

示例(Java,放在网关里即可):

java 复制代码
@Component
public class NacosRouteRefreshListener {

    @Value("${spring.cloud.nacos.config.server-addr}")
    private String serverAddr;

    @Value("${spring.cloud.nacos.config.group:DEFAULT_GROUP}")
    private String group;

    @PostConstruct
    public void startListen() throws NacosException {
        Properties p = new Properties();
        p.put(PropertyKeyConst.SERVER_ADDR, serverAddr);
        ConfigService configService = NacosFactory.createConfigService(p);

        // 1. dataId 与你在 Nacos 控制台里保持一致
        String dataId = "gateway-routes.yaml";

        // 2. 注册监听器
        configService.addListener(dataId, group, new Listener() {
            @Override
            public Executor getExecutor() {
                return null;   // 同步回调即可
            }

            @Override
            public void receiveConfigInfo(String configInfo) {
                // 3. 配置变更时,自动刷新 Gateway 路由
                RestTemplate rest = new RestTemplate();
                rest.postForObject(
                    "http://localhost:8080/actuator/gateway/refresh",
                    null,
                    Void.class
                );
                log.info("路由已热刷新");
            }
        });
    }
}

效果: 在 Nacos 控制台改完 gateway-routes.yaml → 点击发布 → 监听器收到变更 → 自动 POST /actuator/gateway/refresh → 路由秒级生效,全程无人工介入。

2.2 动态路由优先级与冲突处理

2.2.1 路由优先级配置
yaml 复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: high-priority-route
          uri: lb://service1
          predicates:
            - Path=/api/admin/**
          order: 0 # 优先级最高  1️⃣
        - id: low-priority-route
          uri: lb://service2
          predicates:
            - Path=/api/**
          order: 100 		 # 2️⃣
编号 说明
1️⃣ order 值越小越优先。0 是最高优先级,因此凡是以 /api/admin/** 开头的请求都会先命中 high-priority-route,直接转发到 service1;即使两条路由的 Path 有重叠,也不会落到第二条。
2️⃣ order 默认是 2147483647(int 最大值),这里显式写成 100 只是为了可读性:数字越大,优先级越低。

一句话总结:通过 order 字段可以像防火墙规则一样"插队",保证管理后台、支付接口等关键路径永远先被匹配。

2.2.2 冲突处理策略
  • 路径优先级 :精确路径匹配优先于模糊匹配。
    • 精确 > 前缀 > 通配。举例: /api/user/exact 同时满足
      • Route A:Path=/api/user/exact(精确)
      • Route B:Path=/api/**(前缀)
      • → Gateway 会选Route A,因为它更精确。
  • 谓词组合 :使用Host谓词区分不同域名的路由,若路径本身无法区分,可再加其他谓词做"联合主键"
java 复制代码
predicates:
  - Path=/api/** 
  - Host=admin.xxx.com

这样:

admin.xxx.com/api/** → 管理后台

www.xxx.com/api/** → 用户前台

两条路由即使 Path 相同,也能通过域名隔离,互不影响。

一句话总结:先按 order 决定谁先被比较,再按"精确匹配 > 谓词组合"逐级兜底,确保任何情况下 只有一条路由真正生效,不会出现请求被"随机"转发的问题。

三、性能优化:从线程池到响应式编程

3.1 Netty线程池调优

3.1.1 线程池参数配置
  • Gateway 底层是 Reactor-Netty,线程模型只有两类:
    • Boss/Selector 线程:专门做连接事件轮询,不处理读写。
    • Worker 线程:负责 真正的 I/O 读写、编解码、用户业务回调。
  • 默认策略对网关这种 纯 I/O、轻业务场景过于保守,因此需要手动放大 Worker 池。
java 复制代码
@Bean
public ReactorResourceFactory reactorResourceFactory() {
    ReactorResourceFactory factory = new ReactorResourceFactory();
    // ① 选择器线程:1 条即可管理上万并发,CPU 消耗极低
    System.setProperty("reactor.netty.ioSelectCount", "1");
    // ② Worker 线程:CPU 核数 × 3,充分利用多核做并行读写
    int worker = Runtime.getRuntime().availableProcessors() * 3;
    System.setProperty("reactor.netty.ioWorkerCount", String.valueOf(worker));
    return factory;
}
  • 必须在首次使用 Netty 前调用,否则默认值(核数)已生效,再改无效。
  • 选择器线程 不要多开,多开会带来上下文切换损耗; Worker 线程 也不要无上限,经验值 ≤ 核数×3,可避免线程饥饿且 CPU 不空转。
3.1.2 压测结果对比
配置 QPS 错误率
默认配置 8000 5%
优化后配置 12000 0.5%
  • QPS ↑ 50 %:Worker 数量翻倍后,I/O 任务并行度提升,CPU 利用率从 60 % → 90 %。
  • 错误率 ↓ 90%:队列和等待时间缩短,超时/拒绝大幅减少。

结论: 在 Gateway 这种 I/O 密集、业务极轻 的场景下,把 Worker 线程调到 CPU 核数 × 3 是最具性价比的优化手段,只需两行系统属性即可带来 吞吐量 + 稳定性 的双提升。

3.2 响应式编程优化

3.2.1 异步非阻塞处理
java 复制代码
@Component
public class AsyncFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        return Mono.fromSupplier(() -> {
            // 非阻塞业务逻辑
            return exchange;
        }).flatMap(chain::filter);
    }
}
关键点 说明
Mono.fromSupplier 把可能耗时的 初始化/校验/日志 逻辑封装成 Supplier,Reactor 会在 弹性线程池 中异步执行,不占用 Netty 的 IO Worker。
flatMap 结果返回后 再衔接 后续过滤器链,全程 无阻塞 ,整个链路始终保持在 事件驱动 模式。

任何 CPU 密集或第三方调用,都可以用 fromSupplier/fromCallable 扔进弹性线程,让 IO Worker 继续处理下一个连接

3.3 缓存与压缩

3.3.1 Redis缓存响应
java 复制代码
@Component
public class CacheResponseFilter implements GlobalFilter {
    private final ReactiveRedisTemplate<String, String> redisTemplate;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String key = exchange.getRequest().getPath().value();
        return redisTemplate.opsForValue().get(key).flatMap(response -> {
            if (response != null) {
                exchange.getResponse().setStatusCode(HttpStatus.OK);
                return exchange.getResponse().writeWith(Mono.just(DataBufferUtils.wrap(response.getBytes())));
            }
            return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                // 缓存响应
                redisTemplate.opsForValue().set(key, responseBody);
            }));
        });
    }
}
关键点 说明
缓存 Key 请求路径 当 key,简单暴力;生产可再加 Accept-Language/version 等维度防止串包。
读缓存 get(key)非阻塞 Reactive 操作,命中则直接回写响应,后端 0 调用
写缓存 then() 中异步 回填 Redis,写操作同样不阻塞当前线程。
效果 命中率 50 % 就能把后端 QPS 打对折,RT 从 120 ms → 5 ms。

把「读多写少」且「变化不频繁」的接口直接 边缘缓存,网关自己扛流量,后端安心睡觉。

3.3.2 Gzip压缩配置
yaml 复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: gzip-route
          uri: lb://service
          predicates:
            - Path=/api/large-data
          filters:
            - Gzip
关键点 说明
Gzip 过滤器 网关内置,自动检测 Accept-Encoding: gzip,对响应体进行 流式压缩;浏览器收到后自动解压。
适用场景 返回大 JSON / CSV / 静态文本 的接口,压缩率通常 70 % 以上,带宽省一半
代价 CPU 消耗增长 2 %~5 %,但现代 CPU 压缩速度 > 1 GB/s,基本可以忽略。

省带宽就是省钱。对 /api/large-data 这类接口,上线 Gzip 后出口流量瞬间腰斩,用户首包时间也能快一倍。

  • 终极三连击顺序
    • AsyncFilter 让业务逻辑不卡 IO 线程。
    • CacheResponseFilter 把热点数据拦在Redis,后端 QPS 直接打骨折。
    • Gzip Filter 再把剩余流量压成压缩包,出口带宽腰斩。
  • 三步下来,单机 QPS 可提升 2~3 倍,带宽成本下降 50 % 以上。

四、分布式追踪与监控集成

4.1 分布式追踪实现-让请求留下"脚印"

4.1.1 集成Spring Cloud Sleuth

在 pom.xml 加一行依赖:

xml 复制代码
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>

再yaml文件配两个参数:

yaml 复制代码
spring:
  sleuth:
    sampler:
      probability: 1.0 # 全量采样
  zipkin:
    base-url: http://localhost:9411
  • Sleuth 做了什么?
    • 每进来一个请求,它就自动生成一个 TraceId(全链路唯一),并把这个 ID 一路往下传。
  • Zipkin又是什么?
    • 一个"脚印收集站",把 TraceId、耗时、服务名都存起来,供你搜索、画图、定位慢接口。
4.1.2 追踪日志关联(防丢脚印)
java 复制代码
@Component
public class TraceFilter implements GlobalFilter {
    private static final String TRACE_ID_HEADER = "X-B3-TraceId";

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String traceId = exchange.getRequest().getHeaders().getFirst(TRACE_ID_HEADER);
        if (traceId == null) {
            traceId = UUID.randomUUID().toString();
            exchange.getRequest().mutate().header(TRACE_ID_HEADER, traceId).build();
        }
        return chain.filter(exchange);
    }
}
  • 如果外部系统(如前端或老系统)没传 TraceId,我们就在网关给它补一个,保证 "从网关开始,整条链路都有脚印"。
  • 以后排查问题,只需把这个 TraceId 粘进 Zipkin 搜索框,就能看到 请求在网关→A→B→C 各花了多少毫秒。

4.2 监控指标暴露

4.2.1 集成Prometheus

再加一个依赖:

xml 复制代码
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-core</artifactId>
</dependency>

配置:

yaml 复制代码
management:
  endpoints:
    web:
      exposure:
        include: "*"
  metrics:
    export:
      prometheus:
        enabled: true
  • Micrometer 是"翻译官",把网关的运行数据(QPS、RT、错误率、线程数...)翻译成 Prometheus 能看懂的格式。
  • Prometheus 每 15 秒来拉一次数据,存成时间序列,方便后续画图或报警。
4.2.2 Grafana可视化
  • 添加Prometheus数据源:配置Prometheus地址。

  • 导入Gateway监控模板 :使用ID为12345的模板展示QPS、错误率等指标。

    a. 红色折线:每秒请求量

    b. 黄色折线:平均响应时间

    c. 绿色/红色方块:成功率/失败率

  • 小白看图口诀:

    • 折线往上飙 → 流量来了
    • 黄色线变长 → 接口变慢
    • 红色方块出现 → 有错误,一键跳 Zipkin 看具体 TraceId

一句话总结 Sleuth 负责"画脚印",Zipkin 负责"存脚印",Prometheus + Grafana 负责"体检表"。把这三件套配好,以后任何请求变慢或报错,都能在 30 秒内定位到是哪台机器的哪一行代码在拖后腿。

五、熔断与限流:服务稳定性保障

5.1 Resilience4j熔断配置

5.1.1 依赖添加
xml 复制代码
<dependency>
    <groupId>io.github.resilience4j</groupId>
    <artifactId>resilience4j-spring-boot2</artifactId>
</dependency>

Resilience4j 就是官方推荐的"轻量级保险丝",比老牌的 Hystrix 更简单、更快。

5.1.2 熔断策略配置

保险丝参数:

yaml 复制代码
resilience4j:
  circuitbreaker:
    instances:
      service:                 # 给下游服务取个名字
        failureRateThreshold: 50       # 1️⃣
        waitDurationInOpenState: 10s   # 2️⃣
        permittedNumberOfCallsInHalfOpenState: 5  # 3️⃣
参数 大白话
1️⃣ failureRateThreshold: 50 最近 N 次调用里,失败率 ≥ 50 % 就跳闸(保险丝烧断)。
2️⃣ waitDurationInOpenState: 10s 跳闸后等 10 秒,再进入「半开」状态:允许 5 个探针请求去试试水。
3️⃣ permittedNumberOfCallsInHalfOpenState: 5 半开时最多放 5 只"小白鼠"进去,如果都成功就恢复通车,否则继续跳闸。

把保险丝绑到路由上:

yaml 复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: service-route
          uri: lb://service
          predicates:
            - Path=/api/service
          filters:
            - name: CircuitBreaker
              args:
                name: service          # 对应上面配置里的 service
                fallbackUri: forward:/fallback  # 4️⃣

4️⃣ 一旦保险丝跳闸,Gateway 不会傻傻地继续转发,而是 直接把请求转到

/fallback(你可以返回"服务繁忙,请稍后重试"或缓存数据),保护后端也保护用户体验。

5.2 限流与熔断结合

yaml 复制代码
filters:
 - name: RequestRateLimiter
    args:
      key-resolver: "#{@ipKeyResolver}"   # 按 IP 限流
      redis-rate-limiter.replenishRate: 10  # 每秒 10 个令牌
 - name: CircuitBreaker
    args:
      name: service
  • 限流是「水龙头」:每个 IP 最多 10 次/秒,先把洪峰削掉;
  • 熔断是「保险丝」:如果后端已经生病(超时/异常),就算流量不超也会立刻跳闸,防止雪崩。

一句话总结:限流先把大流量挡住,熔断再把坏服务隔离;两者一起上,后端想挂都难,用户看到的永远是"要么秒回,要么友好提示"。

相关推荐
拾光拾趣录7 小时前
一张 8K 海报差点把首屏拖垮
前端·性能优化
拾光拾趣录8 小时前
为什么我们要亲手“捏”一个 Vue 项目?
前端·vue.js·性能优化
鼠鼠我捏,要死了捏9 小时前
Apache Flink 实时流处理性能优化实践指南
性能优化·apache flink·实时流处理
回家路上绕了弯10 小时前
Java 代码优化实战:从规范到性能的全方位提升指南
后端·性能优化
凉祈12 小时前
IO密集型、CPU密集型、负载、负载均衡
运维·负载均衡
十间fish12 小时前
性能分析工具vmstat
性能优化
subuq15 小时前
分布式电商系统:缓存策略、负载均衡与容灾方案
分布式·缓存·负载均衡
sanggou17 小时前
微服务-springcloud-springboot-Skywalking详解(下载安装)
spring boot·spring cloud·微服务
侑虎科技17 小时前
Unity中利用遗传算法训练MLP
性能优化·游戏开发
apocelipes18 小时前
使用uint64_t批量比较字符串
c++·性能优化·go