网关 Spring-Cloud-Gateway 源码解析 —— 网关初始化

本文深入解析了Spring Cloud Gateway的启动初始化过程,包括GatewayAutoConfiguration的各个组件如NettyConfiguration、GlobalFilter等的初始化,以及如何通过配置开启和关闭网关。文章适合对Spring Cloud Gateway感兴趣的读者,旨在帮助读者理解其内部工作原理。

本文主要基于 Spring-Cloud-Gateway 2.0.X M4

摘要: 原创出处 http://www.iocoder.cn/Spring-Cloud-Gateway/init/ 「芋道源码」欢迎转载,保留摘要,谢谢!


������关注微信公众号:【芋道源码】有福利:
1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
4. 新的源码解析文章实时收到通知。每周更新一篇左右
5. 认真的源码交流微信群。


1. 概述

本文主要分享 Spring Cloud Gateway 启动初始化的过程

在初始化的过程中,涉及到的组件会较多,本文不会细说,留到后面每篇文章针对每个组件详细述说。

那么这有什么意义呢?先对 Spring Cloud Gateway 内部的组件有整体的印象。


在官方提供的实例项目 spring-cloud-gateway-sample ,我们看到 GatewaySampleApplication 上有 @EnableAutoConfiguration 注解。因为该项目导入了 spring-cloud-gateway-core 依赖库,它会扫描 Spring Cloud Gateway 的配置。

org.springframework.cloud.gateway.config 包下,我们可以看到四个配置类 :

  • GatewayAutoConfiguration
  • GatewayClassPathWarningAutoConfiguration
  • GatewayLoadBalancerClientAutoConfiguration
  • GatewayRedisAutoConfiguration

它们的初始化顺序如下图 :


推荐 Spring Cloud 书籍

推荐 Spring Cloud 视频

2. GatewayClassPathWarningAutoConfiguration

Spring Cloud Gateway 2.x 基于 Spring WebFlux 实现。

org.springframework.cloud.gateway.config.GatewayClassPathWarningAutoConfiguration ,用于检查项目是否正确导入 spring-boot-starter-webflux 依赖,而不是错误导入 spring-boot-starter-web 依赖。

点击链接 链接 查看 GatewayClassPathWarningAutoConfiguration 的代码实现。

3. GatewayLoadBalancerClientAutoConfiguration

org.springframework.cloud.gateway.config.GatewayLoadBalancerClientAutoConfiguration ,初始化 LoadBalancerClientFilter ,点击 链接 查看代码。

《Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.4) 之 LoadBalancerClientFilter 负载均衡》 详细解析 LoadBalancerClientFilter 的代码实现。

4. GatewayRedisAutoConfiguration

org.springframework.cloud.gateway.config.GatewayRedisAutoConfiguration ,初始化 RedisRateLimiter 。

RequestRateLimiterGatewayFilterFactory 基于 RedisRateLimiter 实现网关的限流功能,在 《Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.10) 之 RequestRateLimiterGatewayFilterFactory 请求限流》 详细解析相关的代码实现。

5. GatewayAutoConfiguration

org.springframework.cloud.gateway.config.GatewayAutoConfiguration ,Spring Cloud Gateway 核心配置类,初始化如下 :

  • Netty**Configuration**
  • Global**Filter**
  • FilteringWeb**Handler**
  • Gateway**Properties**
  • PrefixPathGateway**FilterFactory**
  • Route**PredicateFactory**
  • Route**DefinitionLocator**
  • Route**Locator**
  • Route**PredicateHandlerMapping**
  • GatewayWebflux**Endpoint**

组件关系交互如下图 :

5.1 网关的开启与关闭

从 GatewayAutoConfiguration 上的注解 @ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true) ,我们可以看出 :

  • 通过 spring.cloud.gateway.enabled 配置网关的开启与关闭。
  • matchIfMissing = true => 网关默认开启

5.2 初始化 NettyConfiguration

org.springframework.cloud.gateway.config.NettyConfiguration ,Netty 配置类。代码如下 :

  1: @Configuration
  2: @ConditionalOnClass(HttpClient.class)
  3: protected static class NettyConfiguration {
  4:    @Bean // 1.2
  5:    @ConditionalOnMissingBean
  6:    public HttpClient httpClient(@Qualifier("nettyClientOptions") Consumer<? super HttpClientOptions.Builder> options) {
  7:        return HttpClient.create(options);
  8:    }
  9: 
 10:    @Bean // 1.1
 11:    public Consumer<? super HttpClientOptions.Builder> nettyClientOptions() {
 12:        return opts -> {
 13:            opts.poolResources(PoolResources.elastic("proxy"));
 14:            // opts.disablePool(); //TODO: why do I need this again?
 15:        };
 16:    }
 17: 
 18:    @Bean // 1.3
 19:    public NettyRoutingFilter routingFilter(HttpClient httpClient) {
 20:        return new NettyRoutingFilter(httpClient);
 21:    }
 22: 
 23:    @Bean // 1.4
 24:    public NettyWriteResponseFilter nettyWriteResponseFilter() {
 25:        return new NettyWriteResponseFilter();
 26:    }
 27: 
 28:    @Bean // 1.5 {@link org.springframework.cloud.gateway.filter.WebsocketRoutingFilter}
 29:    public ReactorNettyWebSocketClient reactorNettyWebSocketClient(@Qualifier("nettyClientOptions") Consumer<? super HttpClientOptions.Builder> options) {
 30:        return new ReactorNettyWebSocketClient(options);
 31:    }
 32: }
  • 每个 @Bean 注解后的数字为 Bean 的初始化顺序
  • 第 10 至 16 行 :创建一个类型为 java.util.Objects.Consumer 的 Bean 对象。该 Consumer 会将传入类型为 reactor.ipc.netty.options.HttpClientOptions.Builder 的参数 opts ,设置 optspoolResources 属性。
    • 调用 PoolResources.elastic("proxy") 方法,创建 name 属性为 "proxy"reactor.ipc.netty.resources.PoolResources 。其中 "proxy" 用于实际使用时,打印日志的标记
  • 第 4 至 8 行 :创建一个类型为 reactor.ipc.netty.http.client.HttpClient 的 Bean 对象。该 HttpClient 使用 Netty 实现的 Client 。
  • 第 18 至 21 行 :使用 HttpClient Bean ,创建一个类型为 org.springframework.cloud.gateway.filter.NettyRoutingFilter 的 Bean 对象。在 《Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.7) 之 NettyRoutingFilter》 详细解析 NettyRoutingFilter 的代码实现。
  • 第 23 至 26 行 :创建一个类型为 org.springframework.cloud.gateway.filter.NettyWriteResponseFilter 的 Bean 对象。在 《Spring-Cloud-Gateway 源码解析 —— 过滤器 (4.7) 之 NettyRoutingFilter》 详细解析 NettyWriteResponseFilter 的代码实现。
  • 第 28 至 31 行 :创建一个类型为 org.springframework.web.reactive.socket.client.ReactorNettyWebSocketClient 的 Bean 对象,用于下文 WebsocketRoutingFilter 的 Bean 对象创建。

5.3 初始化 GlobalFilter

代码如下 :

  1: @Bean // 2.1
  2: public RouteToRequestUrlFilter routeToRequestUrlFilter() {
  3:    return new RouteToRequestUrlFilter();
  4: }
  5: 
  6: @Bean // 2.2
  7: @ConditionalOnBean(DispatcherHandler.class)
  8: public ForwardRoutingFilter forwardRoutingFilter(DispatcherHandler dispatcherHandler) {
  9:    return new ForwardRoutingFilter(dispatcherHandler);
 10: }
 11: 
 12: @Bean // 2.3
 13: public WebSocketService webSocketService() {
 14:    return new HandshakeWebSocketService();
 15: }
 16: 
 17: @Bean // 2.4
 18: public WebsocketRoutingFilter websocketRoutingFilter(WebSocketClient webSocketClient, WebSocketService webSocketService) {
 19:    return new WebsocketRoutingFilter(webSocketClient, webSocketService);
 20: }

5.4 初始化 FilteringWebHandler

当所有 org.springframework.cloud.gateway.filter.GlobalFilter 初始化完成时( 包括上面的 NettyRoutingFilter / NettyWriteResponseFilter ),创建一个类型为 org.springframework.cloud.gateway.handler.FilteringWebHandler 的 Bean 对象,代码如下 :

@Bean // 2.6
public FilteringWebHandler filteringWebHandler(List<GlobalFilter> globalFilters) {
    return new FilteringWebHandler(globalFilters);
}

5.5 初始化 GatewayProperties

创建一个类型为 org.springframework.cloud.gateway.config.GatewayProperties 的 Bean 对象,用于加载配置文件配置的 RouteDefinition / FilterDefinition 。代码如下 :

@Bean // 2.7
public GatewayProperties gatewayProperties() {
    return new GatewayProperties();
}

5.6 初始化 PrefixPathGatewayFilterFactory

链接 的【第 288 至 372 行】,创建 org.springframework.cloud.gateway.filter.factory 包下的 org.springframework.cloud.gateway.filter.factory.GatewayFilterFactory 接口的实现们。

后续我们会对每个 GatewayFilterFactory 的实现代码做详细解析。

5.7 初始化 RoutePredicateFactory

链接 的【第 236 至 284 行】,创建 org.springframework.cloud.gateway.handler.predicate 包下的 org.springframework.cloud.gateway.handler.predicate.RoutePredicateFactory 接口的实现们。

后续我们会对每个 RoutePredicateFactory 的实现代码做详细解析。

5.8 初始化 RouteDefinitionLocator

代码如下 :

  1: @Bean // 4.1
  2: @ConditionalOnMissingBean
  3: public PropertiesRouteDefinitionLocator propertiesRouteDefinitionLocator(GatewayProperties properties) {
  4:    return new PropertiesRouteDefinitionLocator(properties);
  5: }
  6: 
  7: @Bean // 4.2
  8: @ConditionalOnMissingBean(RouteDefinitionRepository.class)
  9: public InMemoryRouteDefinitionRepository inMemoryRouteDefinitionRepository() {
 10:    return new InMemoryRouteDefinitionRepository();
 11: }
 12: 
 13: @Bean // 4.3
 14: @Primary // 优先被注入
 15: public RouteDefinitionLocator routeDefinitionLocator(List<RouteDefinitionLocator> routeDefinitionLocators) {
 16:    return new CompositeRouteDefinitionLocator(Flux.fromIterable(routeDefinitionLocators));
 17: }

org.springframework.cloud.gateway.discovery.DiscoveryClientRouteDefinitionLocator ,基于 DiscoveryClient 注册发现的 RouteDefinitionLocator 实现类,需要手动引入配置,点击 链接 查看。在 《Spring-Cloud-Gateway 源码解析 —— 路由(1.4)之 DiscoveryClientRouteDefinitionLocator 注册中心》 详细解析 DiscoveryClientRouteDefinitionLocator 的代码实现。

5.9 初始化 RouteLocator

代码如下 :

  1: @Bean // 4.4
  2: public RouteLocator routeDefinitionRouteLocator(GatewayProperties properties,
  3:                                               List<GatewayFilterFactory> GatewayFilters,
  4:                                               List<RoutePredicateFactory> predicates,
  5:                                               RouteDefinitionLocator routeDefinitionLocator) {
  6:    return new RouteDefinitionRouteLocator(routeDefinitionLocator, predicates, GatewayFilters, properties);
  7: }
  8: 
  9: @Bean // 4.5
 10: @Primary
 11: public RouteLocator routeLocator(List<RouteLocator> routeLocators) {
 12:    return new CachingRouteLocator(new CompositeRouteLocator(Flux.fromIterable(routeLocators)));
 13: }

另外,有如下两种方式实现自定义 RouteLocator :

  • 使用 Routes#locator()#build() 方法,创建 RouteLocator ,例子代码如下 :

    @Bean
    public RouteLocator customRouteLocator() {
        //@formatter:off
        return Routes.locator()
                .route("test")
                    .predicate(host("**.abc.org").and(path("/image/png")))
                    .addResponseHeader("X-TestHeader", "foobar")
                    .uri("http://httpbin.org:80")
                .route("test2")
                    .predicate(path("/image/webp"))
                    .add(addResponseHeader("X-AnotherHeader", "baz"))
                    .uri("http://httpbin.org:80")
                .build();
        ////@formatter:on
    }
  • 使用 RouteLocatorDsl#gateway() 方法,创建 RouteLocator ,该方式使用 Kotlin 实现例子代码如下 :

    @Configuration
    class AdditionalRoutes {
    
        @Bean
        fun additionalRouteLocator(): RouteLocator = gateway {
            route(id = "test-kotlin") {
                uri("http://httpbin.org:80")
                predicate(host("kotlin.abc.org") and path("/image/png"))
                add(addResponseHeader("X-TestHeader", "foobar"))
            }
        }
    
    }

5.10 初始化 RoutePredicateHandlerMapping

创建一个类型为 org.springframework.cloud.gateway.handler.RoutePredicateHandlerMapping 的 Bean 对象,用于查找匹配到 Route ,并进行处理。代码如下 :

@Bean
public RoutePredicateHandlerMapping routePredicateHandlerMapping(FilteringWebHandler webHandler,
                                                                   RouteLocator routeLocator) {
    return new RoutePredicateHandlerMapping(webHandler, routeLocator);
}

5.11 初始化 GatewayWebfluxEndpoint

创建一个类型为 org.springframework.cloud.gateway.actuate.GatewayWebfluxEndpoint 的 Bean 对象,提供管理网关的 HTTP API ,代码如下 :

@ManagementContextConfiguration
@ConditionalOnProperty(value = "management.gateway.enabled", matchIfMissing = true)
@ConditionalOnClass(Health.class)
protected static class GatewayActuatorConfiguration {

    @Bean
    public GatewayWebfluxEndpoint gatewayWebfluxEndpoint(RouteDefinitionLocator routeDefinitionLocator, List<GlobalFilter> globalFilters,

        List<GatewayFilterFactory> GatewayFilters, RouteDefinitionWriter routeDefinitionWriter,
                                                         RouteLocator routeLocator) {
        return new GatewayWebfluxEndpoint(routeDefinitionLocator, globalFilters, GatewayFilters, routeDefinitionWriter, routeLocator);
    }
}

666. 彩蛋

知识星球

是不是内心里面有种感觉,“劳资看了一堆构造函数”?

嘿嘿嘿,后面咱一篇一篇走起!

胖友,分享一波朋友圈可好!

<think>我们使用Spring Boot Actuator和Micrometer来获取监控指标,并定时打印。以下是针对Spring Cloud Gateway 3.1.9版本的实现步骤: ### 1. 添加Maven依赖 确保在pom.xml中包含以下依赖: ```xml <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-prometheus</artifactId> </dependency> </dependencies> ``` ### 2. 配置application.yml 在配置文件中启用Actuator端点: ```yaml management: endpoints: web: exposure: include: metrics metrics: tags: application: ${spring.application.name} ``` ### 3. 创建定时任务打印指标 创建一个Spring组件,定时从MeterRegistry中读取指标并打印: ```java import io.micrometer.core.instrument.Meter; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Statistic; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.util.*; import java.util.stream.Collectors; @Component public class GatewayMetricsLogger { private static final Logger logger = LoggerFactory.getLogger(GatewayMetricsLogger.class); private final MeterRegistry meterRegistry; private static final Set<String> GATEWAY_METRICS = new HashSet<>(Arrays.asList( "gateway.requests", "gateway.route.requests", "gateway.route.response.time" )); public GatewayMetricsLogger(MeterRegistry meterRegistry) { this.meterRegistry = meterRegistry; } @Scheduled(fixedRate = 30000) // 每30秒执行一次 public void logMetrics() { Map<String, List<Meter>> metricsGrouped = meterRegistry.getMeters().stream() .filter(meter -> GATEWAY_METRICS.contains(meter.getId().getName())) .collect(Collectors.groupingBy(meter -> meter.getId().getName())); if (metricsGrouped.isEmpty()) { logger.info("No gateway metrics found."); return; } StringBuilder report = new StringBuilder("\n========== Gateway Metrics ==========\n"); metricsGrouped.forEach((metricName, meters) -> { report.append(metricName).append(":\n"); meters.forEach(meter -> { // 获取标签 String tags = meter.getId().getTags().stream() .map(tag -> tag.getKey() + "=" + tag.getValue()) .collect(Collectors.joining(", ")); // 获取测量值 String measurements = meter.measure().stream() .map(ms -> ms.getStatistic().name() + ": " + ms.getValue()) .collect(Collectors.joining(", ")); report.append(" ").append(tags).append(" -> ").append(measurements).append("\n"); }); }); report.append("====================================="); logger.info(report.toString()); } } ``` ### 4. 主应用类 确保主应用类启用定时任务: ```java import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @EnableScheduling public class GatewayApplication { public static void main(String[] args) { SpringApplication.run(GatewayApplication.class, args); } } ``` ### 代码解释 1. **依赖配置**: - `spring-boot-starter-actuator`:提供监控端点。 - `micrometer-registry-prometheus`:用于收集和暴露指标(虽然我们这里不直接使用Prometheus,但它会帮助初始化MeterRegistry)。 2. **定时任务**: - 使用`@Scheduled`注解每30秒执行一次`logMetrics`方法。 - 从`MeterRegistry`中获取所有Meter,然后过滤出网关相关的指标(`gateway.requests`等)。 3. **指标处理**: - 将指标按名称分组。 - 对于每个指标,打印其标签(如routeId, status等)和测量值(如count, totalTime, max等)。 4. **输出示例**: ``` ========== Gateway Metrics ========== gateway.requests: uri=/api/v1/users, status=200, ... -> COUNT: 10.0 uri=/api/v1/products, status=404, ... -> COUNT: 2.0 gateway.route.requests: routeId=user_route, ... -> COUNT: 10.0, TOTAL_TIME: 120.5, MAX: 20.3 ... ===================================== ``` ### 注意事项 - 如果网关没有接收到任何请求,可能看不到指标,因为指标是在请求过程中记录的。 - 指标名称可能因版本变化而不同,请根据实际情况调整。 ### 扩展:自定义指标 若要添加自定义指标,可以在过滤器中使用MeterRegistry记录: ```java import io.micrometer.core.instrument.Counter; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.server.ServerWebExchange; @Configuration public class CustomMetricsConfig { @Bean public GlobalFilter customMetricFilter(MeterRegistry registry) { Counter counter = registry.counter("custom.requests.count"); return (exchange, chain) -> { counter.increment(); return chain.filter(exchange); }; } } ``` §§相关问题§§: 1. 如何将Spring Cloud Gateway的指标导出到Prometheus? 2. 在Spring Cloud Gateway中如何自定义监控指标? 3. 如何通过HTTP端点获取Gateway的监控指标(不使用MeterRegistry)? 4. Gateway的指标中,哪些是对于性能监控比较关键的? </think> ### Spring Cloud Gateway 3.1.9 定时打印监控指标方案 以下是完整实现方案,包含指标收集、定时打印和可视化控制台输出: #### 1. 添加依赖 (`pom.xml`) ```xml <dependencies> <!-- Spring Cloud Gateway --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> <version>3.1.9</version> </dependency> <!-- 监控核心依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-core</artifactId> </dependency> </dependencies> ``` #### 2. 配置监控端点 (`application.yml`) ```yaml server: port: 8080 management: endpoints: web: exposure: include: health, metrics metrics: tags: application: gateway-service export: simple: enabled: true ``` #### 3. 指标打印服务实现 ```java import io.micrometer.core.instrument.Meter; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Statistic; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import java.util.*; import java.util.concurrent.TimeUnit; @Service public class GatewayMetricsReporter { private final MeterRegistry meterRegistry; private final Map<String, String> routeNames = new HashMap<>(); // 关键网关指标 private static final List<String> CORE_METRICS = Arrays.asList( "gateway.requests", "gateway.route.requests", "gateway.route.response.time", "reactor.netty.http.server.connections" ); public GatewayMetricsReporter(MeterRegistry meterRegistry) { this.meterRegistry = meterRegistry; // 初始化路由名称映射 routeNames.put("account_route", "账户服务"); routeNames.put("product_route", "商品服务"); } @Scheduled(fixedRate = 15, timeUnit = TimeUnit.SECONDS) public void reportMetrics() { System.out.println(buildMetricsReport()); } private String buildMetricsReport() { StringBuilder report = new StringBuilder(); report.append("\n╔════════════════════════════════════════════════════════╗"); report.append("\n║ GATEWAY METRICS REPORT (v3.1.9) ║"); report.append("\n╠════════════════════════════════════════════════════════╣"); // 核心指标区 report.append("\n║ CORE METRICS ║"); report.append("\n╠════════════════════════════════════════════════════════╣"); for (String metricName : CORE_METRICS) { meterRegistry.find(metricName).meters().forEach(meter -> { report.append(formatMeter(meter)); }); } // 请求统计区 report.append("\n║ REQUEST STATISTICS ║"); report.append("\n╠════════════════════════════════════════════════════════╣"); printRequestStats(report); // 连接监控区 report.append("\n║ CONNECTION MONITORING ║"); report.append("\n╠════════════════════════════════════════════════════════╣"); printConnectionMetrics(report); report.append("\n╚════════════════════════════════════════════════════════╝"); return report.toString(); } private String formatMeter(Meter meter) { StringBuilder sb = new StringBuilder(); String metricName = meter.getId().getName(); String routeId = getTagValue(meter, "routeId"); String status = getTagValue(meter, "status"); String outcome = getTagValue(meter, "outcome"); // 格式化路由名称 String displayName = routeNames.getOrDefault(routeId, routeId); if (displayName == null) displayName = "GLOBAL"; sb.append("\n║ "); sb.append(String.format("%-30s", abbreviateMetricName(metricName))); meter.measure().forEach(measurement -> { String stat = measurement.getStatistic().getTagValueRepresentation(); double value = measurement.getValue(); if (stat.equals("COUNT")) { sb.append(String.format("Count: %-8.0f", value)); } else if (stat.equals("TOTAL_TIME")) { sb.append(String.format("TotalTime: %-8.2fms", value)); } else if (stat.equals("MAX")) { sb.append(String.format("Max: %-8.2fms", value)); } }); sb.append(String.format("Route: %-15s", displayName)); if (status != null) sb.append(String.format("Status: %-5s", status)); if (outcome != null) sb.append(String.format("Outcome: %-8s", outcome)); return sb.toString(); } private void printRequestStats(StringBuilder report) { meterRegistry.find("gateway.requests").counters().forEach(counter -> { String route = getTagValue(counter, "routeId"); String status = getTagValue(counter, "status"); report.append("\n║ "); report.append(String.format("%-20s: %-8.0f (Status: %s)", routeNames.getOrDefault(route, route), counter.count(), status)); }); } private void printConnectionMetrics(StringBuilder report) { meterRegistry.find("reactor.netty.http.server.connections").gauges().forEach(gauge -> { String type = getTagValue(gauge, "type"); if (type != null) { report.append("\n║ "); report.append(String.format("%-15s connections: %-5.0f", type.toUpperCase(), gauge.value())); } }); } private String getTagValue(Meter meter, String tagKey) { return meter.getId().getTag(tagKey); } private String abbreviateMetricName(String fullName) { return fullName .replace("gateway.", "") .replace("reactor.netty.http.server.", ""); } } ``` #### 4. 主应用配置 ```java import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @EnableScheduling public class GatewayApplication { public static void main(String[] args) { SpringApplication.run(GatewayApplication.class, args); } } ``` ### 功能说明 1. **监控指标类型**: - `gateway.requests`:总请求数(按路由和状态分组) - `gateway.route.requests`:路由请求计数 - `gateway.route.response.time`:响应时间统计 - `reactor.netty.http.server.connections`:Netty连接数 2. **控制台输出示例**: ```plaintext ╔════════════════════════════════════════════════════════╗ ║ GATEWAY METRICS REPORT (v3.1.9) ║ ╠════════════════════════════════════════════════════════╣ ║ CORE METRICS ║ ╠════════════════════════════════════════════════════════╣ ║ requests Count: 120 Route: 账户服务 Status: 200 Outcome: SUCCESS ║ route.requests Count: 75 Route: 商品服务 Status: 200 ║ response.time TotalTime: 450.32ms Max: 120.50ms Route: 账户服务 ║ connections Active: 15 Route: GLOBAL Type: active ║ ║ REQUEST STATISTICS ║ ╠════════════════════════════════════════════════════════╣ ║ 账户服务 : 120 (Status: 200) ║ 商品服务 : 75 (Status: 200) ║ ║ CONNECTION MONITORING ║ ╠════════════════════════════════════════════════════════╣ ║ ACTIVE connections: 15 ╚════════════════════════════════════════════════════════╝ ``` 3. **关键功能**: - 每15秒自动打印监控报告 - 自定义路由名称映射(美化输出) - 分类展示核心指标、请求统计和连接信息 - 指标名称缩写处理(更紧凑的显示) - 表格化控制台输出(增强可读性) ### 自定义指标扩展 添加异常请求监控: ```java import io.micrometer.core.instrument.Counter; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.core.Ordered; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; @Component public class ErrorMetricsFilter implements GlobalFilter, Ordered { private final Counter errorCounter; public ErrorMetricsFilter(MeterRegistry registry) { errorCounter = registry.counter("gateway.errors", "type", "request_error"); } @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { return chain.filter(exchange) .doOnError(throwable -> { errorCounter.increment(); exchange.getAttributes().put("error", true); }); } @Override public int getOrder() { return -1; } } ``` ### 配置优化建议 在 `application.yml` 中添加: ```yaml spring: cloud: gateway: metrics: enabled: true # 确保启用网关指标 # 配置自定义标签 tags: path: "${path}" method: "${method}" status: "${status}" ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值