You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Spring WebClient默认Micrometer指标添加自定义标签

Spring WebFlux WebClient 指标添加自定义标签最优实现方案

实现逻辑

利用Spring Actuator默认集成的Micrometer WebClient指标扩展点,将调用时传入的自定义标签存入请求属性,再通过自定义标签提供者读取属性注入到指标中,不需要修改原有指标的默认生成逻辑。


实现步骤

1. 定义自定义标签存储常量

定义统一的请求属性Key,用于存储调用时传入的自定义标签:

public class WebClientCustomTagConstants {
    // 请求属性中存储自定义标签的Key
    public static final String CUSTOM_TAGS_ATTR = "webClient.custom.tags";
}

2. 自定义标签提供者

继承默认的WebClient指标标签提供者,扩展读取自定义标签的逻辑:

import io.micrometer.core.instrument.Tag;
import io.micrometer.core.instrument.Tags;
import org.springframework.boot.actuate.metrics.web.reactive.client.DefaultWebClientExchangeTagsProvider;
import org.springframework.web.reactive.function.client.ClientRequest;
import org.springframework.web.reactive.function.client.ClientResponse;

import java.util.Map;

public class CustomWebClientExchangeTagsProvider extends DefaultWebClientExchangeTagsProvider {

    @Override
    public Iterable<Tag> tags(ClientRequest request, ClientResponse response, Throwable throwable) {
        // 保留原有默认标签
        Tags tags = Tags.of(super.tags(request, response, throwable));
        // 从请求属性中读取自定义标签
        Map<String, String> customTags = request.attribute(WebClientCustomTagConstants.CUSTOM_TAGS_ATTR)
                .map(attr -> (Map<String, String>) attr)
                .orElse(Map.of());
        // 追加自定义标签到指标
        for (Map.Entry<String, String> entry : customTags.entrySet()) {
            tags = tags.and(Tag.of(entry.getKey(), entry.getValue()));
        }
        return tags;
    }
}

3. 注册自定义标签提供者为Bean

Spring会自动使用该Bean替换默认的标签提供者,不需要修改原有WebClient的配置:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.boot.actuate.metrics.web.reactive.client.WebClientExchangeTagsProvider;

@Configuration
public class MetricsConfig {

    @Bean
    public WebClientExchangeTagsProvider customWebClientExchangeTagsProvider() {
        return new CustomWebClientExchangeTagsProvider();
    }
}

4. 封装WebClient调用方法支持传入自定义标签

注意不要每次调用都新建WebClient实例,预初始化复用即可,可根据需求选择Map传参或可变参数传参:

方式1:Map传参

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import java.util.Map;

@Component
public class ShopApiClient {
    private final WebClient webClient;

    @Autowired
    public ShopApiClient(WebClient.Builder webClientBuilder) {
        // 预初始化WebClient,Spring会自动注入指标过滤器,无需手动配置
        this.webClient = webClientBuilder
                .baseUrl("http://my-app.com")
                .build();
    }

    public Mono<String> getShopsList(Map<String, String> extraTags) {
        return webClient.get()
                .uri("/shops")
                // 将自定义标签存入请求属性
                .attribute(WebClientCustomTagConstants.CUSTOM_TAGS_ATTR, extraTags)
                .retrieve()
                .bodyToMono(String.class);
    }
}

// 调用示例
// Map<String, String> tags = Map.of("investor", "A", "version", "v1");
// shopApiClient.getShopsList(tags).subscribe();

方式2:可变参数传参(符合示例写法)

public Mono<String> getShopsList(String... extraTags) {
    if (extraTags.length % 2 != 0) {
        throw new IllegalArgumentException("标签必须为键值对成对出现");
    }
    Map<String, String> tagMap = new HashMap<>();
    for (int i = 0; i < extraTags.length; i += 2) {
        tagMap.put(extraTags[i], extraTags[i + 1]);
    }
    return webClient.get()
            .uri("/shops")
            .attribute(WebClientCustomTagConstants.CUSTOM_TAGS_ATTR, tagMap)
            .retrieve()
            .bodyToMono(String.class);
}

// 调用示例
// getShopsList("investor", "A", "version", "v1").subscribe();

注意事项

  • 自定义标签的取值范围尽量小,避免出现大量唯一值导致Prometheus指标基数爆炸,影响监控服务性能
  • 不要每次调用都调用WebClient.Builder.build()新建实例,WebClient本身是线程安全的,复用即可

内容的提问来源于stack exchange,提问作者justAnotherDev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 06:36:04