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

多租户Spring Boot应用:用OpenTelemetry实现Elasticsearch追踪数据隔离

多租户Spring Boot应用中OpenTelemetry+Elasticsearch 8.3.2追踪数据隔离方案

针对你的需求,结合OpenTelemetry当前最佳实践与Elasticsearch 8.3.2特性,推荐以下实现方案:

核心思路

通过Span处理器注入租户ID属性,配合新版Elasticsearch Exporter动态生成租户专属索引,实现每个租户追踪数据的隔离存储。该方案规避了旧版Exporter废弃、RestHighLevelClient兼容问题,同时适配多租户场景的动态特性。

具体实现步骤

1. 自定义Span处理器注入租户ID

在每个Span创建时,从请求上下文(如ThreadLocal、RequestAttributes)中获取当前租户ID,将其作为Span属性注入:

@Component
public class TenantSpanProcessor implements SpanProcessor {

    @Override
    public void onStart(Context parentContext, ReadWriteSpan span) {
        // 此处假设你通过ThreadLocal存储当前请求的租户ID,可根据实际场景调整
        String tenantId = TenantContext.getTenantId();
        if (tenantId != null) {
            span.setAttribute("tenant.id", tenantId);
        }
    }

    @Override
    public boolean isStartRequired() {
        return true;
    }

    @Override
    public void onEnd(ReadWriteSpan span) {}

    @Override
    public boolean isEndRequired() {
        return false;
    }
}

2. 引入新版OpenTelemetry Elasticsearch Exporter

旧版ElasticsearchSpanExporter已废弃,使用社区维护的新版Exporter(兼容Elasticsearch 8.x),先添加依赖:

<dependency>
    <groupId>io.opentelemetry.contrib</groupId>
    <artifactId>opentelemetry-exporter-elasticsearch</artifactId>
    <version>适配你的OTel版本的最新稳定版</version>
</dependency>

3. 配置动态索引的Exporter

通过自定义IndexNameProvider,根据Span中的租户ID属性动态生成索引名:

@Bean
public SpanExporter elasticsearchSpanExporter() {
    return ElasticsearchSpanExporter.builder()
            .setEndpoint("http://your-es-host:9200") // 替换为你的ES实例地址
            .setIndexNameProvider(span -> {
                String tenantId = span.getAttribute("tenant.id");
                // 无租户ID时使用默认索引,可根据业务需求调整命名规则
                return tenantId != null ? "traces-" + tenantId : "traces-default";
            })
            .build();
}

4. 配置TracerProvider并注册组件

将自定义Span处理器和Exporter注册到SdkTracerProvider:

@Bean
public SdkTracerProvider sdkTracerProvider(SpanExporter elasticsearchSpanExporter, TenantSpanProcessor tenantSpanProcessor) {
    return SdkTracerProvider.builder()
            .addSpanProcessor(BatchSpanProcessor.builder(elasticsearchSpanExporter).build())
            .addSpanProcessor(tenantSpanProcessor)
            .setResource(Resource.getDefault().merge(
                Resource.create(Attributes.of(AttributeKey.stringKey("service.name"), "your-service-name"))
            ))
            .build();
}

关于全局Resource方案的说明

你提到的setResource方式属于全局配置,在多租户Spring Boot应用中并不适用:Resource是单例全局对象,无法为每个请求动态切换租户标识,会导致所有租户的追踪数据共用同一索引或标识,无法实现有效隔离。

兼容性说明

新版Exporter使用Elasticsearch官方推荐的co.elastic.clients.elasticsearch.ElasticsearchClient(而非已废弃的RestHighLevelClient),完全兼容Elasticsearch 8.3.2版本,无需担心兼容性问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 06:47:49