Spring Cloud Gateway网关性能优化深度实践:路由配置、限流策略、安全防护全链路优化方案

逍遥自在
逍遥自在 2026-01-07T10:20:01+08:00
0 0 0

引言

在微服务架构日益普及的今天,API网关作为整个系统的重要入口,承担着路由转发、请求过滤、安全控制、限流降级等多重职责。Spring Cloud Gateway作为Spring Cloud生态中的核心组件,为构建现代化的API网关提供了强大的支持。然而,随着业务规模的增长和用户访问量的增加,网关的性能问题逐渐凸显,如何进行有效的性能优化成为每个微服务架构团队必须面对的挑战。

本文将深入探讨Spring Cloud Gateway网关的性能优化技术实践,从路由配置优化、请求过滤器设计、限流降级策略到安全防护机制等多个维度,提供一套完整的性能调优解决方案。通过实际的技术细节和最佳实践,帮助开发者构建高可用、高性能的API网关系统。

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

1.1 Spring Cloud Gateway架构概览

Spring Cloud Gateway基于Netty异步非阻塞I/O模型构建,采用响应式编程范式,能够高效处理大量并发请求。其核心组件包括:

  • Route: 定义路由规则,包含匹配条件和转发地址
  • Predicate: 断言条件,用于匹配请求
  • Filter: 过滤器,对请求和响应进行处理
  • GatewayWebHandler: 网关处理器,负责请求的分发和处理

1.2 常见性能瓶颈分析

在实际应用中,Spring Cloud Gateway的性能瓶颈主要体现在以下几个方面:

  1. 路由匹配效率: 当路由规则过多时,匹配过程会消耗大量CPU资源
  2. 过滤器执行开销: 过多的过滤器会增加请求处理时间
  3. 内存占用: 高并发场景下,网关的内存使用量会显著增加
  4. 网络IO瓶颈: 网关作为流量入口,容易成为网络传输的瓶颈

二、路由配置优化策略

2.1 路由规则优化原则

合理的路由配置是提升网关性能的基础。首先需要遵循以下优化原则:

  • 避免冗余路由: 清理无用的路由规则
  • 合理设置匹配顺序: 将高频访问的路由规则放在前面
  • 使用精确匹配: 避免过于宽泛的路径匹配

2.2 路由配置最佳实践

spring:
  cloud:
    gateway:
      routes:
        # 优化前:模糊匹配
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/users/**
          
        # 优化后:精确匹配
        - id: user-service-detail
          uri: lb://user-service
          predicates:
            - Path=/api/users/{id}
            
        # 优化后:复合条件匹配
        - id: admin-service
          uri: lb://admin-service
          predicates:
            - Method=GET,POST
            - Path=/admin/**
            - Header=X-Admin-Token

2.3 路由缓存机制

为了提高路由匹配效率,可以通过自定义路由缓存来优化性能:

@Component
public class OptimizedRouteLocator implements RouteLocator {
    
    private final RouteLocator delegate;
    private final Map<String, Route> routeCache = new ConcurrentHashMap<>();
    private final LoadingCache<String, Route> cache = 
        Caffeine.newBuilder()
            .maximumSize(1000)
            .expireAfterWrite(30, TimeUnit.MINUTES)
            .build(this::loadRoute);
    
    public OptimizedRouteLocator(RouteLocator delegate) {
        this.delegate = delegate;
    }
    
    @Override
    public Publisher<Route> getRoutes() {
        return delegate.getRoutes()
            .map(route -> {
                // 将路由信息缓存到本地
                routeCache.put(route.getId(), route);
                return route;
            });
    }
    
    private Route loadRoute(String routeId) {
        // 从缓存中获取路由信息
        return routeCache.get(routeId);
    }
}

2.4 动态路由配置

对于需要频繁变更的路由规则,可以采用动态配置的方式:

@RestController
@RequestMapping("/gateway/route")
public class RouteManagementController {
    
    @Autowired
    private RouteDefinitionLocator routeDefinitionLocator;
    
    @Autowired
    private RouteDefinitionWriter routeDefinitionWriter;
    
    @PostMapping("/add")
    public ResponseEntity<String> addRoute(@RequestBody RouteDefinition routeDefinition) {
        try {
            routeDefinitionWriter.save(Mono.just(routeDefinition)).subscribe();
            return ResponseEntity.ok("路由添加成功");
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body("路由添加失败: " + e.getMessage());
        }
    }
    
    @DeleteMapping("/delete/{id}")
    public ResponseEntity<String> deleteRoute(@PathVariable String id) {
        try {
            routeDefinitionWriter.delete(Mono.just(id)).subscribe();
            return ResponseEntity.ok("路由删除成功");
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body("路由删除失败: " + e.getMessage());
        }
    }
}

三、请求过滤器设计与优化

3.1 过滤器类型与执行顺序

Spring Cloud Gateway支持多种类型的过滤器:

  • GatewayFilter: 网关过滤器,可对请求和响应进行处理
  • GlobalFilter: 全局过滤器,对所有请求生效
  • Pre Filter: 前置过滤器,在请求路由前执行
  • Post Filter: 后置过滤器,在响应返回后执行

3.2 高效的过滤器实现

@Component
@Order(-1) // 设置优先级,确保在其他过滤器之前执行
public class RequestTimeFilter implements GlobalFilter {
    
    private static final Logger logger = LoggerFactory.getLogger(RequestTimeFilter.class);
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        long startTime = System.currentTimeMillis();
        
        // 记录请求开始时间
        exchange.getAttributes().put("startTime", startTime);
        
        return chain.filter(exchange).then(
            Mono.fromRunnable(() -> {
                long endTime = System.currentTimeMillis();
                long duration = endTime - startTime;
                
                // 记录请求耗时
                logger.info("Request completed in {}ms for path: {}", 
                    duration, exchange.getRequest().getURI().getPath());
                
                // 如果请求耗时超过阈值,记录警告日志
                if (duration > 5000) {
                    logger.warn("Slow request detected: {}ms for path: {}", 
                        duration, exchange.getRequest().getURI().getPath());
                }
            })
        );
    }
}

3.3 过滤器性能监控

@Component
public class FilterMetricsCollector {
    
    private final MeterRegistry meterRegistry;
    private final Timer requestTimer;
    private final Counter filterCounter;
    
    public FilterMetricsCollector(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
        
        // 创建请求处理时间监控指标
        this.requestTimer = Timer.builder("gateway.requests")
            .description("Gateway request processing time")
            .register(meterRegistry);
            
        // 创建过滤器执行次数统计
        this.filterCounter = Counter.builder("gateway.filters")
            .description("Gateway filter execution count")
            .register(meterRegistry);
    }
    
    public void recordRequestTime(String path, long duration) {
        requestTimer.record(duration, TimeUnit.MILLISECONDS);
    }
    
    public void incrementFilterCount() {
        filterCounter.increment();
    }
}

3.4 异步过滤器优化

对于需要耗时操作的过滤器,建议使用异步处理方式:

@Component
public class AsyncValidationFilter implements GatewayFilter {
    
    private final ExecutorService executor = Executors.newFixedThreadPool(10);
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 异步执行验证逻辑
        return Mono.fromFuture(CompletableFuture.supplyAsync(() -> {
            try {
                validateRequest(exchange);
                return true;
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }, executor))
        .then(chain.filter(exchange))
        .onErrorMap(throwable -> {
            // 统一异常处理
            return new GatewayException("Request validation failed", throwable);
        });
    }
    
    private void validateRequest(ServerWebExchange exchange) {
        // 实现具体的验证逻辑
        ServerHttpRequest request = exchange.getRequest();
        
        // 验证请求头
        String userAgent = request.getHeaders().getFirst("User-Agent");
        if (userAgent == null || userAgent.isEmpty()) {
            throw new IllegalArgumentException("Missing User-Agent header");
        }
        
        // 验证请求参数
        Map<String, String> params = exchange.getRequest().getQueryParams().toSingleValueMap();
        if (params.containsKey("timestamp") && !isValidTimestamp(params.get("timestamp"))) {
            throw new IllegalArgumentException("Invalid timestamp parameter");
        }
    }
    
    private boolean isValidTimestamp(String timestamp) {
        try {
            long time = Long.parseLong(timestamp);
            long current = System.currentTimeMillis();
            return Math.abs(current - time) < 300000; // 5分钟内有效
        } catch (NumberFormatException e) {
            return false;
        }
    }
}

四、限流降级策略设计

4.1 基于令牌桶算法的限流实现

@Component
public class TokenBucketRateLimiter {
    
    private final Map<String, TokenBucket> buckets = new ConcurrentHashMap<>();
    private final ScheduledExecutorService scheduler = 
        Executors.newScheduledThreadPool(2);
    
    public TokenBucketRateLimiter() {
        // 定期清理过期的桶
        scheduler.scheduleAtFixedRate(() -> {
            long now = System.currentTimeMillis();
            buckets.entrySet().removeIf(entry -> 
                entry.getValue().getCreateTime() + 3600000 < now);
        }, 1, 1, TimeUnit.HOURS);
    }
    
    public boolean tryAcquire(String key, int permits, long timeout) {
        TokenBucket bucket = buckets.computeIfAbsent(key, this::createBucket);
        return bucket.tryConsume(permits, timeout);
    }
    
    private TokenBucket createBucket(String key) {
        // 创建令牌桶,每秒生成10个令牌
        return new TokenBucket(10, 100, 1000);
    }
    
    static class TokenBucket {
        private final int capacity;
        private final int rate;
        private final long interval;
        private volatile int tokens;
        private volatile long lastRefillTime;
        private final Object lock = new Object();
        
        public TokenBucket(int rate, int capacity, long interval) {
            this.rate = rate;
            this.capacity = capacity;
            this.interval = interval;
            this.tokens = capacity;
            this.lastRefillTime = System.currentTimeMillis();
        }
        
        public boolean tryConsume(int permits, long timeout) {
            long startTime = System.currentTimeMillis();
            
            while (System.currentTimeMillis() - startTime < timeout) {
                synchronized (lock) {
                    refill();
                    if (tokens >= permits) {
                        tokens -= permits;
                        return true;
                    }
                }
                
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    return false;
                }
            }
            
            return false;
        }
        
        private void refill() {
            long now = System.currentTimeMillis();
            long elapsed = now - lastRefillTime;
            
            if (elapsed >= interval) {
                int newTokens = (int) (elapsed / interval) * rate;
                tokens = Math.min(capacity, tokens + newTokens);
                lastRefillTime = now;
            }
        }
        
        public long getCreateTime() {
            return lastRefillTime;
        }
    }
}

4.2 基于Redis的分布式限流

@Component
public class RedisRateLimiter {
    
    private final RedisTemplate<String, String> redisTemplate;
    private final ObjectMapper objectMapper;
    
    public RedisRateLimiter(RedisTemplate<String, String> redisTemplate, 
                           ObjectMapper objectMapper) {
        this.redisTemplate = redisTemplate;
        this.objectMapper = objectMapper;
    }
    
    public boolean tryAcquire(String key, int limit, int windowSeconds) {
        String script = "local key = KEYS[1] " +
                       "local limit = tonumber(ARGV[1]) " +
                       "local window = tonumber(ARGV[2]) " +
                       "local current = redis.call('GET', key) " +
                       "if current == false then " +
                       "  redis.call('SET', key, 1) " +
                       "  redis.call('EXPIRE', key, window) " +
                       "  return true " +
                       "else " +
                       "  local count = tonumber(current) " +
                       "  if count < limit then " +
                       "    redis.call('INCR', key) " +
                       "    return true " +
                       "  else " +
                       "    return false " +
                       "  end " +
                       "end";
        
        try {
            Object result = redisTemplate.execute(
                new DefaultRedisScript<>(script, Long.class),
                Collections.singletonList(key),
                String.valueOf(limit),
                String.valueOf(windowSeconds)
            );
            
            return Boolean.TRUE.equals(result);
        } catch (Exception e) {
            // 降级处理,允许请求通过
            return true;
        }
    }
    
    public void rateLimitWithResponse(ServerWebExchange exchange, 
                                    ServerHttpResponse response) {
        response.setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
        response.getHeaders().set("Retry-After", "60");
        
        // 返回限流错误信息
        Map<String, Object> error = new HashMap<>();
        error.put("timestamp", System.currentTimeMillis());
        error.put("status", 429);
        error.put("error", "Too Many Requests");
        error.put("message", "Rate limit exceeded");
        
        try {
            String json = objectMapper.writeValueAsString(error);
            DataBuffer buffer = response.bufferFactory().wrap(json.getBytes());
            response.getHeaders().add("Content-Type", "application/json");
            response.writeWith(Mono.just(buffer));
        } catch (Exception e) {
            // 处理序列化异常
            exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
        }
    }
}

4.3 熔断降级机制

@Component
public class CircuitBreakerFilter implements GatewayFilter {
    
    private final Map<String, CircuitBreaker> circuitBreakers = new ConcurrentHashMap<>();
    private final MeterRegistry meterRegistry;
    
    public CircuitBreakerFilter(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
    }
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String routeId = getRouteId(exchange);
        CircuitBreaker circuitBreaker = circuitBreakers.computeIfAbsent(
            routeId, this::createCircuitBreaker);
            
        return circuitBreaker.run(
            chain.filter(exchange),
            throwable -> {
                // 熔断器打开时的降级处理
                ServerHttpResponse response = exchange.getResponse();
                response.setStatusCode(HttpStatus.SERVICE_UNAVAILABLE);
                
                return Mono.empty();
            }
        );
    }
    
    private CircuitBreaker createCircuitBreaker(String routeId) {
        return CircuitBreaker.of(routeId, CircuitBreakerConfig.custom()
            .failureRateThreshold(50) // 失败率阈值
            .slowCallRateThreshold(100) // 慢调用阈值
            .slidingWindowSize(100) // 滑动窗口大小
            .permittedNumberOfCallsInHalfOpenState(10) // 半开状态允许的调用次数
            .waitDurationInOpenState(Duration.ofSeconds(30)) // 开放状态持续时间
            .build());
    }
    
    private String getRouteId(ServerWebExchange exchange) {
        return exchange.getAttribute(GatewayFilterChain.GATEWAY_ROUTE_ATTR);
    }
}

五、安全防护机制构建

5.1 请求签名验证

@Component
public class RequestSignatureFilter implements GatewayFilter {
    
    private static final String SIGNATURE_HEADER = "X-Signature";
    private static final String TIMESTAMP_HEADER = "X-Timestamp";
    private static final String APP_ID_HEADER = "X-App-Id";
    
    private final String secretKey;
    private final Set<String> whiteList;
    
    public RequestSignatureFilter(@Value("${gateway.security.secret-key}") String secretKey,
                                @Value("${gateway.security.whitelist:}") String whitelist) {
        this.secretKey = secretKey;
        this.whiteList = Arrays.stream(whitelist.split(","))
            .map(String::trim)
            .filter(s -> !s.isEmpty())
            .collect(Collectors.toSet());
    }
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        
        // 检查是否在白名单中
        String appId = request.getHeaders().getFirst(APP_ID_HEADER);
        if (whiteList.contains(appId)) {
            return chain.filter(exchange);
        }
        
        // 验证签名
        String signature = request.getHeaders().getFirst(SIGNATURE_HEADER);
        String timestamp = request.getHeaders().getFirst(TIMESTAMP_HEADER);
        String method = request.getMethodValue();
        String path = request.getURI().getPath();
        String query = request.getURI().getQuery();
        
        if (!validateSignature(signature, timestamp, method, path, query)) {
            return handleInvalidSignature(exchange);
        }
        
        return chain.filter(exchange);
    }
    
    private boolean validateSignature(String signature, String timestamp, 
                                    String method, String path, String query) {
        try {
            long time = Long.parseLong(timestamp);
            long currentTime = System.currentTimeMillis();
            
            // 时间戳验证(5分钟内有效)
            if (Math.abs(currentTime - time) > 300000) {
                return false;
            }
            
            // 构造签名字符串
            String signString = method + path + query + timestamp + secretKey;
            String expectedSignature = DigestUtils.md5Hex(signString);
            
            return signature != null && signature.equals(expectedSignature);
        } catch (Exception e) {
            return false;
        }
    }
    
    private Mono<Void> handleInvalidSignature(ServerWebExchange exchange) {
        ServerHttpResponse response = exchange.getResponse();
        response.setStatusCode(HttpStatus.UNAUTHORIZED);
        
        Map<String, Object> error = new HashMap<>();
        error.put("timestamp", System.currentTimeMillis());
        error.put("status", 401);
        error.put("error", "Unauthorized");
        error.put("message", "Invalid signature");
        
        try {
            String json = new ObjectMapper().writeValueAsString(error);
            DataBuffer buffer = response.bufferFactory().wrap(json.getBytes());
            response.getHeaders().add("Content-Type", "application/json");
            return response.writeWith(Mono.just(buffer));
        } catch (Exception e) {
            return Mono.empty();
        }
    }
}

5.2 XSS防护机制

@Component
public class XssProtectionFilter implements GatewayFilter {
    
    private static final Set<String> ALLOWED_TAGS = Set.of(
        "a", "abbr", "acronym", "address", "applet", "area", "article", 
        "aside", "audio", "b", "basefont", "bdo", "big", "blink", "blockquote",
        "body", "br", "button", "canvas", "caption", "center", "cite", "code",
        "col", "colgroup", "command", "content", "data", "datalist", "dd",
        "del", "details", "dfn", "dialog", "dir", "div", "dl", "dt", "em"
    );
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        
        // 处理请求体中的XSS攻击
        if (isRequestBodyRequired(request)) {
            return processRequestBody(exchange, chain);
        }
        
        return chain.filter(exchange);
    }
    
    private boolean isRequestBodyRequired(ServerHttpRequest request) {
        String contentType = request.getHeaders().getFirst("Content-Type");
        return contentType != null && 
               (contentType.contains("application/json") || 
                contentType.contains("text/html"));
    }
    
    private Mono<Void> processRequestBody(ServerWebExchange exchange, 
                                        GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        
        return DataBufferUtils.join(request.getBody())
            .map(dataBuffer -> {
                try {
                    String bodyContent = bufferToString(dataBuffer);
                    String cleanContent = sanitizeHtml(bodyContent);
                    
                    // 创建新的请求体
                    DataBuffer newBuffer = exchange.getResponse().bufferFactory()
                        .wrap(cleanContent.getBytes());
                    
                    return newBuffer;
                } catch (Exception e) {
                    throw new RuntimeException("Failed to process request body", e);
                }
            })
            .flatMap(buffer -> chain.filter(exchange));
    }
    
    private String sanitizeHtml(String input) {
        if (input == null || input.isEmpty()) {
            return input;
        }
        
        // 移除危险标签和属性
        return input.replaceAll("<script[^>]*>.*?</script>", "")
                   .replaceAll("javascript:", "")
                   .replaceAll("vbscript:", "")
                   .replaceAll("on\\w+\\s*=\\s*[^\\s>]*", "");
    }
    
    private String bufferToString(DataBuffer dataBuffer) throws IOException {
        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
            DataBufferUtils.write(Mono.just(dataBuffer), outputStream)
                .block();
            return outputStream.toString(StandardCharsets.UTF_8.name());
        }
    }
}

5.3 防止SQL注入攻击

@Component
public class SqlInjectionProtectionFilter implements GatewayFilter {
    
    private static final Set<String> SQL_KEYWORDS = Set.of(
        "select", "insert", "update", "delete", "drop", "create", 
        "alter", "exec", "execute", "union", "or", "and", "having",
        "order by", "group by", "limit", "offset"
    );
    
    private static final Set<String> SQL_FUNCTIONS = Set.of(
        "concat", "substring", "length", "char", "ascii", "ord", 
        "hex", "unhex", "md5", "sha1", "crypt", "password"
    );
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        
        // 检查查询参数中的SQL注入
        MultiValueMap<String, String> queryParams = request.getQueryParams();
        if (hasSqlInjection(queryParams)) {
            return handleSqlInjection(exchange);
        }
        
        // 检查请求头中的SQL注入
        HttpHeaders headers = request.getHeaders();
        if (hasSqlInjection(headers)) {
            return handleSqlInjection(exchange);
        }
        
        return chain.filter(exchange);
    }
    
    private boolean hasSqlInjection(MultiValueMap<String, String> queryParams) {
        for (String key : queryParams.keySet()) {
            List<String> values = queryParams.get(key);
            if (values != null) {
                for (String value : values) {
                    if (isSqlInjection(value)) {
                        return true;
                    }
                }
            }
        }
        return false;
    }
    
    private boolean hasSqlInjection(HttpHeaders headers) {
        for (String key : headers.keySet()) {
            List<String> values = headers.get(key);
            if (values != null) {
                for (String value : values) {
                    if (isSqlInjection(value)) {
                        return true;
                    }
                }
            }
        }
        return false;
    }
    
    private boolean isSqlInjection(String input) {
        if (input == null || input.isEmpty()) {
            return false;
        }
        
        String lowerInput = input.toLowerCase();
        
        // 检查SQL关键字
        for (String keyword : SQL_KEYWORDS) {
            if (lowerInput.contains(keyword)) {
                return true;
            }
        }
        
        // 检查SQL函数
        for (String function : SQL_FUNCTIONS) {
            if (lowerInput.contains(function)) {
                return true;
            }
        }
        
        // 检查危险字符
        if (input.matches(".*[;\\-\\'\\\"\\(\\)]+.*")) {
            return true;
        }
        
        return false;
    }
    
    private Mono<Void> handleSqlInjection(ServerWebExchange exchange) {
        ServerHttpResponse response = exchange.getResponse();
        response.setStatusCode(HttpStatus.FORBIDDEN);
        
        Map<String, Object> error = new HashMap<>();
        error.put("timestamp", System.currentTimeMillis());
        error.put("status", 403);
        error.put("error", "Forbidden");
        error.put("message", "SQL injection detected");
        
        try {
            String json = new ObjectMapper().writeValueAsString(error);
            DataBuffer buffer = response.bufferFactory().wrap(json.getBytes());
            response.getHeaders().add("Content-Type", "application/json");
            return response.writeWith(Mono.just(buffer));
        } catch (Exception e) {
            return Mono.empty();
        }
    }
}

六、性能监控与调优实践

6.1 监控指标体系构建

@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("Total gateway requests")
            .register(meterRegistry);
            
        // 响应时间定时器
        this.responseTimer = Timer.builder("gateway.response.time")
            .description("Gateway response time")
            .register(meterRegistry);
            
        // 活跃请求数
        this.activeRequestsGauge = Gauge.builder("gateway.active.requests")
            .description("Current active gateway requests")
            .register(meterRegistry, 0L, value -> getActiveRequests());
    }
    
    public void recordRequest(String method, String path, int statusCode) {
        requestCounter.increment();
        
        // 可以添加更详细的标签
        Counter.builder("gateway.requests")
            .tag("method", method)
            .tag("path", path)
            .tag("status", String.valueOf(statusCode))
            .register(meterRegistry)
            .increment();
    }
    
    public void recordResponseTime(long duration) {
        responseTimer.record(duration, TimeUnit.MILLISECONDS);
    }
    
    private long getActiveRequests() {
        // 实现获取活跃请求数的逻辑
        return 0;
    }
}

6.2 性能调优建议

@Configuration
public class GatewayPerformanceConfig {
    
    @Bean
    public WebServerFactoryCustomizer<NettyWebServerFactory> nettyCustomizer() {
        return factory -> {
            factory.addServerCustomizers(server -> {
                // 配置Netty服务器参数
                server.option(ChannelOption.SO_BACKLOG, 1024);
                server.option(ChannelOption.SO_REUSEADDR, true);
                server.option(ChannelOption.TCP_NODELAY, true);
                
                // 配置连接超时
                server.childOption(ChannelOption.SO_KEEPALIVE, true);
               
相关推荐
广告位招租

相似文章

    评论 (0)

    0/2000