Spring Cloud Gateway高并发场景下的性能优化与架构设计:从路由配置到熔断降级全链路优化

Rose807
Rose807 2026-01-18T15:09:01+08:00
0 0 1

引言

在微服务架构日益普及的今天,API网关作为整个系统的重要入口,承担着请求路由、负载均衡、安全认证、限流熔断等关键职责。Spring Cloud Gateway作为Spring Cloud生态中的核心组件,凭借其基于Netty的异步非阻塞特性,在高并发场景下展现出了强大的性能优势。然而,面对海量请求和复杂业务场景时,如果不进行针对性的优化,仍然可能出现性能瓶颈。

本文将深入分析Spring Cloud Gateway在高并发场景下的性能瓶颈,并从路由配置优化、连接池调优、熔断降级策略等多个维度,提供完整的性能优化方案和高可用架构设计实践经验。

一、Spring Cloud Gateway核心架构与性能瓶颈分析

1.1 核心架构解析

Spring Cloud Gateway基于WebFlux框架构建,采用响应式编程模型,底层使用Netty作为网络通信组件。其核心架构包含以下几个关键组件:

  • Route Predicate Factory:路由断言工厂,用于匹配请求条件
  • GatewayFilter:网关过滤器,用于处理请求和响应
  • RouteLocator:路由定位器,负责动态路由配置
  • GatewayWebHandler:网关处理器,协调整个请求处理流程

1.2 高并发场景下的性能瓶颈

在高并发场景下,Spring Cloud Gateway可能面临以下性能瓶颈:

# 常见的性能问题配置示例
spring:
  cloud:
    gateway:
      # 默认连接池配置可能不够优化
      httpclient:
        connection-timeout: 5000
        response-timeout: 10000
        max-in-memory-size: 1048576

主要瓶颈分析:

  1. 线程阻塞:虽然基于响应式编程,但在某些同步操作中仍可能出现阻塞
  2. 连接池配置不当:默认连接池参数可能无法满足高并发需求
  3. 路由匹配效率:复杂的路由规则可能导致匹配性能下降
  4. 内存使用:大请求体处理时内存占用过高

二、路由配置优化策略

2.1 路由匹配性能优化

在高并发场景下,路由匹配的效率直接影响网关性能。我们需要避免过于复杂的路由规则和不必要的匹配操作。

# 优化前的路由配置
spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/user/**
            - Method=GET
            - Header=X-User-ID, \d+
          filters:
            - name: RequestRateLimiter
              args:
                key-resolver: "#{@userKeyResolver}"
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/api/order/**
            - Method=POST
            - Header=X-Order-ID, \d+
          filters:
            - name: RequestRateLimiter
              args:
                key-resolver: "#{@orderKeyResolver}"

# 优化后的路由配置
spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            # 使用更精确的路径匹配
            - Path=/api/user/{id}
            # 合并相同的请求头条件
            - Header=X-User-ID
          filters:
            - name: RequestRateLimiter
              args:
                key-resolver: "#{@userKeyResolver}"
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/api/order/{id}
            - Method=POST
          filters:
            - name: RequestRateLimiter
              args:
                key-resolver: "#{@orderKeyResolver}"

2.2 动态路由配置优化

@Component
public class DynamicRouteConfig {
    
    @Autowired
    private RouteDefinitionLocator routeDefinitionLocator;
    
    @Autowired
    private RouteDefinitionWriter routeDefinitionWriter;
    
    // 动态更新路由配置,避免频繁创建新的路由对象
    public void updateRoute(RouteDefinition routeDefinition) {
        try {
            routeDefinitionWriter.delete(Mono.just(routeDefinition.getId()));
            Thread.sleep(100); // 等待删除完成
            routeDefinitionWriter.save(Mono.just(routeDefinition)).subscribe();
        } catch (Exception e) {
            log.error("更新路由失败", e);
        }
    }
    
    // 批量处理路由配置
    public void batchUpdateRoutes(List<RouteDefinition> routeDefinitions) {
        routeDefinitions.forEach(this::updateRoute);
    }
}

2.3 路由缓存机制

@Component
public class RouteCacheManager {
    
    private final Map<String, RouteDefinition> routeCache = new ConcurrentHashMap<>();
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    
    public RouteDefinition getRoute(String routeId) {
        return routeCache.get(routeId);
    }
    
    public void putRoute(String routeId, RouteDefinition routeDefinition) {
        routeCache.put(routeId, routeDefinition);
    }
    
    // 定期清理过期路由
    @PostConstruct
    public void init() {
        scheduler.scheduleAtFixedRate(() -> {
            routeCache.entrySet().removeIf(entry -> 
                entry.getValue().getPredicates() == null || 
                entry.getValue().getFilters() == null
            );
        }, 30, 30, TimeUnit.SECONDS);
    }
}

三、连接池调优配置

3.1 HTTP客户端连接池优化

# Spring Cloud Gateway连接池优化配置
spring:
  cloud:
    gateway:
      httpclient:
        # 连接超时时间
        connection-timeout: 5000
        # 响应超时时间
        response-timeout: 15000
        # 最大内存大小
        max-in-memory-size: 2097152
        # 连接池配置
        pool:
          # 连接池类型
          type: FIXED
          # 最大连接数
          max-connections: 2000
          # 连接空闲超时时间
          acquire-timeout: 2000
          # 最小空闲连接数
          max-idle-time: 30000
          # 最大生命周期
          max-life-time: 60000
        # DNS解析缓存
        dns-resolver:
          cache:
            max-time-to-live: 300

3.2 Netty连接池配置

@Configuration
public class NettyPoolConfiguration {
    
    @Bean
    public ReactorResourceFactory resourceFactory() {
        ReactorResourceFactory factory = new ReactorResourceFactory();
        // 配置Netty资源工厂
        factory.setBufferSize(1024 * 1024); // 1MB缓冲区
        factory.setLoopResources(new DefaultLoopResources());
        return factory;
    }
    
    @Bean
    public HttpClient httpClient() {
        return HttpClient.create()
            .option(ChannelOption.SO_KEEPALIVE, true)
            .option(ChannelOption.TCP_NODELAY, true)
            .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000)
            .doOnConnected(conn -> 
                conn.addHandlerLast(new ReadTimeoutHandler(10))
                    .addHandlerLast(new WriteTimeoutHandler(10))
            )
            .responseTimeout(Duration.ofSeconds(15))
            .maxInMemorySize(2 * 1024 * 1024); // 2MB
    }
}

3.3 连接池监控与调优

@Component
public class ConnectionPoolMonitor {
    
    private final MeterRegistry meterRegistry;
    private final AtomicLong activeConnections = new AtomicLong(0);
    private final AtomicLong idleConnections = new AtomicLong(0);
    
    public ConnectionPoolMonitor(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
        
        // 注册监控指标
        Gauge.builder("gateway.connections.active")
            .register(meterRegistry, activeConnections, AtomicLong::get);
            
        Gauge.builder("gateway.connections.idle")
            .register(meterRegistry, idleConnections, AtomicLong::get);
    }
    
    public void updateActiveConnections(long count) {
        activeConnections.set(count);
    }
    
    public void updateIdleConnections(long count) {
        idleConnections.set(count);
    }
}

四、响应式编程优化

4.1 异步处理优化

@Component
public class AsyncProcessingOptimization {
    
    // 使用Flux进行批量处理,避免阻塞
    public Flux<ServerHttpResponse> processBatchRequests(List<ServerWebExchange> exchanges) {
        return Flux.fromIterable(exchanges)
            .flatMap(this::processRequestAsync)
            .onErrorContinue((throwable, o) -> 
                log.error("处理请求时发生错误", throwable)
            );
    }
    
    private Mono<ServerHttpResponse> processRequestAsync(ServerWebExchange exchange) {
        return Mono.fromCallable(() -> {
            // 异步处理逻辑
            return exchange.getResponse();
        })
        .subscribeOn(Schedulers.boundedElastic());
    }
    
    // 避免在响应式链中使用阻塞操作
    public Mono<String> safeAsyncOperation(String input) {
        return Mono.fromCallable(() -> {
            // 模拟异步操作
            Thread.sleep(100);
            return "processed_" + input;
        })
        .subscribeOn(Schedulers.boundedElastic())
        .timeout(Duration.ofSeconds(5));
    }
}

4.2 背压处理优化

@Component
public class BackpressureHandling {
    
    public Flux<String> handleHighVolumeData(Flux<String> source) {
        return source
            // 使用背压策略
            .onBackpressureBuffer(1000, 
                () -> log.warn("背压缓冲区已满"),
                BackpressureOverflowStrategy.DROP_OLDEST)
            // 限流处理
            .limitRate(1000, Duration.ofSeconds(1))
            // 错误处理
            .onErrorContinue((throwable, o) -> 
                log.error("数据处理错误", throwable)
            );
    }
    
    // 自定义背压策略
    public Flux<String> customBackpressureHandling(Flux<String> source) {
        return source
            .publishOn(Schedulers.boundedElastic())
            .windowTimeout(100, Duration.ofSeconds(1))
            .flatMap(window -> 
                window.bufferTimeout(50, Duration.ofMillis(100))
                    .flatMap(buffer -> 
                        Flux.fromIterable(buffer)
                            .delayElements(Duration.ofMillis(10))
                            .subscribeOn(Schedulers.boundedElastic())
                    )
            );
    }
}

五、熔断降级策略设计

5.1 Hystrix熔断器配置

# Hystrix熔断器配置
hystrix:
  command:
    default:
      # 熔断时间窗口
      circuitBreaker:
        sleepWindowInMilliseconds: 5000
        # 熔断触发阈值
        errorThresholdPercentage: 50
        # 最小请求数
        requestVolumeThreshold: 20
      # 超时时间
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 10000
      # 熔断器状态监控
      metrics:
        rollingStats:
          timeInMilliseconds: 10000
        rollingPercentile:
          timeInMilliseconds: 60000

5.2 自定义熔断降级逻辑

@Component
public class CustomCircuitBreaker {
    
    private final CircuitBreaker circuitBreaker;
    private final MeterRegistry meterRegistry;
    
    public CustomCircuitBreaker(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
        
        // 创建自定义熔断器
        this.circuitBreaker = CircuitBreaker.ofDefaults("api-gateway");
        
        // 配置熔断器监控
        circuitBreaker.getEventPublisher()
            .onStateChange((from, to) -> 
                log.info("熔断器状态变化: {} -> {}", from, to)
            );
    }
    
    public <T> T executeWithCircuitBreaker(Supplier<T> supplier, 
                                         Function<Throwable, T> fallback) {
        return circuitBreaker.executeSupplier(
            () -> {
                try {
                    return supplier.get();
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            },
            fallback
        );
    }
    
    // 带有自定义统计的熔断器
    public <T> T executeWithCustomMetrics(Supplier<T> supplier, 
                                        Function<Throwable, T> fallback) {
        return circuitBreaker.executeSupplier(
            () -> {
                long startTime = System.currentTimeMillis();
                try {
                    T result = supplier.get();
                    // 记录成功请求
                    Timer.Sample sample = Timer.start(meterRegistry);
                    sample.stop(Timer.builder("gateway.request.duration")
                        .tag("status", "success")
                        .register(meterRegistry));
                    return result;
                } catch (Exception e) {
                    // 记录失败请求
                    Timer.Sample sample = Timer.start(meterRegistry);
                    sample.stop(Timer.builder("gateway.request.duration")
                        .tag("status", "error")
                        .register(meterRegistry));
                    throw e;
                }
            },
            throwable -> {
                log.error("熔断降级处理", throwable);
                return fallback.apply(throwable);
            }
        );
    }
}

5.3 服务降级策略实现

@Component
public class ServiceFallbackHandler {
    
    private final Map<String, String> fallbackCache = new ConcurrentHashMap<>();
    
    // 缓存降级响应
    public Mono<ServerHttpResponse> handleFallback(String serviceId, 
                                                  Throwable throwable) {
        return Mono.fromCallable(() -> {
            // 构造降级响应
            ServerHttpResponse response = createErrorResponse(throwable);
            
            // 缓存降级响应,避免重复计算
            String cacheKey = serviceId + "_" + System.currentTimeMillis();
            fallbackCache.put(cacheKey, response.toString());
            
            return response;
        })
        .subscribeOn(Schedulers.boundedElastic());
    }
    
    private ServerHttpResponse createErrorResponse(Throwable throwable) {
        // 创建标准的降级响应格式
        ServerHttpResponse response = new DefaultServerHttpResponse();
        response.setStatusCode(HttpStatus.SERVICE_UNAVAILABLE);
        
        // 设置响应头
        response.getHeaders().add("X-Fallback-Reason", 
            "Service unavailable due to circuit breaker");
        
        return response;
    }
    
    // 降级策略配置
    @Bean
    public GlobalFilter fallbackFilter() {
        return (exchange, chain) -> {
            return chain.filter(exchange)
                .onErrorResume(throwable -> {
                    if (throwable instanceof CircuitBreakerException) {
                        log.warn("触发熔断降级", throwable);
                        return handleCircuitBreakerFallback(exchange, throwable);
                    }
                    return Mono.error(throwable);
                });
        };
    }
    
    private Mono<Void> handleCircuitBreakerFallback(ServerWebExchange exchange, 
                                                   Throwable throwable) {
        ServerHttpResponse response = exchange.getResponse();
        response.setStatusCode(HttpStatus.SERVICE_UNAVAILABLE);
        response.getHeaders().add("X-Fallback", "true");
        
        // 返回降级响应体
        DataBuffer buffer = response.bufferFactory()
            .wrap("{\"error\":\"Service temporarily unavailable\",\"timestamp\":" + 
                  System.currentTimeMillis() + "}".getBytes());
        
        return response.writeWith(Mono.just(buffer));
    }
}

六、限流与负载均衡优化

6.1 请求限流策略

# Redis限流配置
spring:
  cloud:
    gateway:
      routes:
        - id: rate-limited-service
          uri: lb://service-a
          predicates:
            - Path=/api/service-a/**
          filters:
            # 基于Redis的令牌桶限流
            - name: RequestRateLimiter
              args:
                key-resolver: "#{@userKeyResolver}"
                redis-rate-limiter.replenishRate: 10
                redis-rate-limiter.burstCapacity: 20
            # 基于内存的限流(适用于测试环境)
            - name: RequestRateLimiter
              args:
                key-resolver: "#{@ipKeyResolver}"
                redis-rate-limiter.replenishRate: 5
                redis-rate-limiter.burstCapacity: 10

6.2 自定义限流器实现

@Component
public class CustomRateLimiter {
    
    private final RedisTemplate<String, String> redisTemplate;
    private final MeterRegistry meterRegistry;
    
    public CustomRateLimiter(RedisTemplate<String, String> redisTemplate, 
                           MeterRegistry meterRegistry) {
        this.redisTemplate = redisTemplate;
        this.meterRegistry = meterRegistry;
    }
    
    // 基于Redis的令牌桶算法
    public Mono<Boolean> isAllowed(String key, int replenishRate, int burstCapacity) {
        return Mono.fromCallable(() -> {
            String luaScript = 
                "local key = KEYS[1] " +
                "local limit = tonumber(ARGV[1]) " +
                "local rate = tonumber(ARGV[2]) " +
                "local now = tonumber(ARGV[3]) " +
                "local last_refill_time = redis.call('HGET', key, 'last_refill_time') " +
                "local tokens = redis.call('HGET', key, 'tokens') " +
                "if not last_refill_time then " +
                "  redis.call('HSET', key, 'last_refill_time', now) " +
                "  redis.call('HSET', key, 'tokens', limit) " +
                "  return true " +
                "end " +
                "local elapsed = now - last_refill_time " +
                "local refill_tokens = math.floor(elapsed * rate) " +
                "if refill_tokens > 0 then " +
                "  local new_tokens = math.min(limit, tonumber(tokens) + refill_tokens) " +
                "  redis.call('HSET', key, 'tokens', new_tokens) " +
                "  redis.call('HSET', key, 'last_refill_time', now) " +
                "end " +
                "local current_tokens = redis.call('HGET', key, 'tokens') " +
                "if tonumber(current_tokens) >= 1 then " +
                "  redis.call('HSET', key, 'tokens', tonumber(current_tokens) - 1) " +
                "  return true " +
                "else " +
                "  return false " +
                "end";
            
            Object result = redisTemplate.execute(
                new DefaultRedisScript<>(luaScript, Boolean.class),
                Collections.singletonList("rate_limit:" + key),
                String.valueOf(burstCapacity),
                String.valueOf(replenishRate),
                String.valueOf(System.currentTimeMillis() / 1000)
            );
            
            return (Boolean) result;
        })
        .subscribeOn(Schedulers.boundedElastic());
    }
    
    // 限流监控
    public void registerRateLimitMetrics(String key, int replenishRate, int burstCapacity) {
        Gauge.builder("gateway.rate_limit.replenish_rate")
            .tag("key", key)
            .register(meterRegistry, () -> replenishRate);
            
        Gauge.builder("gateway.rate_limit.burst_capacity")
            .tag("key", key)
            .register(meterRegistry, () -> burstCapacity);
    }
}

6.3 负载均衡策略优化

@Configuration
public class LoadBalancerConfiguration {
    
    @Bean
    public ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(
            Environment environment, 
            ServiceInstanceListSupplier serviceInstanceListSupplier) {
        String name = environment.getProperty("spring.cloud.loadbalancer.configurations", 
            "random");
        return new RandomLoadBalancer(serviceInstanceListSupplier, name);
    }
    
    // 自定义负载均衡策略
    @Bean
    public ReactorLoadBalancer<ServiceInstance> customLoadBalancer(
            Environment environment,
            ServiceInstanceListSupplier serviceInstanceListSupplier) {
        
        String strategy = environment.getProperty("gateway.loadbalancer.strategy", 
            "round-robin");
        
        switch (strategy) {
            case "weighted-round-robin":
                return new WeightedRoundRobinLoadBalancer(serviceInstanceListSupplier);
            case "least-connections":
                return new LeastConnectionsLoadBalancer(serviceInstanceListSupplier);
            default:
                return new RoundRobinLoadBalancer(serviceInstanceListSupplier);
        }
    }
}

// 自定义权重轮询负载均衡器
@Component
public class WeightedRoundRobinLoadBalancer implements ReactorLoadBalancer<ServiceInstance> {
    
    private final ServiceInstanceListSupplier serviceInstanceListSupplier;
    private final AtomicReference<List<ServiceInstance>> instancesRef = 
        new AtomicReference<>();
    
    public WeightedRoundRobinLoadBalancer(ServiceInstanceListSupplier serviceInstanceListSupplier) {
        this.serviceInstanceListSupplier = serviceInstanceListSupplier;
    }
    
    @Override
    public Mono<Response<ServiceInstance>> choose(Request request) {
        return serviceInstanceListSupplier.get()
            .filter(instances -> !instances.isEmpty())
            .map(instances -> {
                // 基于权重选择服务实例
                List<ServiceInstance> weightedInstances = 
                    calculateWeightedInstances(instances);
                ServiceInstance selected = selectByWeight(weightedInstances);
                return new DefaultResponse<>(selected);
            })
            .switchIfEmpty(Mono.error(new IllegalStateException(
                "No servers available for service: " + 
                request.getContext().get("serviceId"))));
    }
    
    private List<ServiceInstance> calculateWeightedInstances(List<ServiceInstance> instances) {
        // 根据实例的健康状态、负载等信息计算权重
        return instances.stream()
            .filter(this::isHealthy)
            .sorted(Comparator.comparing(this::getInstanceScore))
            .collect(Collectors.toList());
    }
    
    private boolean isHealthy(ServiceInstance instance) {
        // 检查服务实例健康状态
        return true; // 简化示例,实际应该检查具体的健康指标
    }
    
    private double getInstanceScore(ServiceInstance instance) {
        // 计算实例评分(可以基于CPU、内存、响应时间等指标)
        return Math.random(); // 随机评分作为示例
    }
    
    private ServiceInstance selectByWeight(List<ServiceInstance> instances) {
        // 基于权重选择实例
        if (instances.isEmpty()) return null;
        
        int totalWeight = instances.stream()
            .mapToInt(instance -> (int) (Math.random() * 100))
            .sum();
            
        int randomWeight = new Random().nextInt(totalWeight);
        int currentWeight = 0;
        
        for (ServiceInstance instance : instances) {
            currentWeight += (int) (Math.random() * 100);
            if (randomWeight < currentWeight) {
                return instance;
            }
        }
        
        return instances.get(0);
    }
}

七、监控与调优实践

7.1 全链路监控配置

# 监控配置
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus
  endpoint:
    metrics:
      enabled: true
    prometheus:
      enabled: true
  metrics:
    web:
      server:
        request:
          autotime:
            enabled: true
    distribution:
      percentiles-histogram:
        http:
          server.requests: true
    enable:
      http:
        client: true
        server: true

7.2 自定义监控指标

@Component
public class GatewayMetricsCollector {
    
    private final MeterRegistry meterRegistry;
    private final Counter requestCounter;
    private final Timer responseTimer;
    private final Gauge activeRequestsGauge;
    
    public GatewayMetricsCollector(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
        
        // 请求计数器
        this.requestCounter = Counter.builder("gateway.requests")
            .description("网关请求总数")
            .register(meterRegistry);
            
        // 响应时间计时器
        this.responseTimer = Timer.builder("gateway.response.time")
            .description("网关响应时间")
            .register(meterRegistry);
            
        // 活跃请求数
        this.activeRequestsGauge = Gauge.builder("gateway.active.requests")
            .description("当前活跃请求数")
            .register(meterRegistry, new AtomicInteger(0));
    }
    
    public void recordRequest(String method, String path, int statusCode) {
        requestCounter.increment(
            Tag.of("method", method),
            Tag.of("path", path),
            Tag.of("status", String.valueOf(statusCode))
        );
    }
    
    public Timer.Sample startTimer() {
        return Timer.start(meterRegistry);
    }
    
    public void recordResponseTime(Timer.Sample sample, String method, 
                                 String path, int statusCode) {
        sample.stop(
            Timer.builder("gateway.response.time")
                .tag("method", method)
                .tag("path", path)
                .tag("status", String.valueOf(statusCode))
                .register(meterRegistry)
        );
    }
    
    public void updateActiveRequests(int count) {
        ((AtomicInteger) activeRequestsGauge.value()).set(count);
    }
}

7.3 性能调优建议

@Component
public class PerformanceOptimizationTips {
    
    // JVM参数优化建议
    /*
     * JVM启动参数优化:
     * -Xms2g -Xmx4g
     * -XX:+UseG1GC
     * -XX:MaxGCPauseMillis=200
     * -XX:+HeapDumpOnOutOfMemoryError
     * -XX:HeapDumpPath=/tmp/gateway-heapdump.hprof
     */
    
    // 网络调优配置
    @Bean
    public WebServerFactoryCustomizer<NettyReactiveWebServerFactory> nettyCustomizer() {
        return factory -> {
            factory.addServerCustomizers(server -> 
                server.option(ChannelOption.SO_REUSEADDR, true)
                    .option(ChannelOption.SO_KEEPALIVE, true)
                    .option(ChannelOption.TCP_NODELAY, true)
                    .childOption(ChannelOption.SO_KEEPALIVE, true)
                    .childOption(ChannelOption.TCP_NODELAY, true)
            );
        };
    }
    
    // 线程池优化
    @Bean
    public TaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(50);
        executor.setQueueCapacity(1000);
        executor.setThreadNamePrefix("gateway-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }
    
    // 缓存优化
    @Bean
    public CacheManager cacheManager() {
        CaffeineCacheManager cacheManager = new CaffeineCacheManager();
        cacheManager.setCaffeine(Caffeine.newBuilder()
            .maximumSize(1000)
            .expireAfterWrite(Duration.ofMinutes(30))
            .recordStats());
        return cacheManager;
    }
}

八、高可用架构设计

8.1 集群部署架构

# 高
相关推荐
广告位招租

相似文章

    评论 (0)

    0/2000