すべてのプロダクト
Search
ドキュメントセンター

Managed Service for OpenTelemetry:Zipkin を使用した Java アプリケーションのデータレポート

最終更新日:Aug 27, 2026

Zipkin は、Twitter によって開発された、リアルタイムデータをトレースするためのオープンソース分散トレーシングシステムです。複数の異種システムから収集されたリアルタイム監視データを集約します。このガイドでは、Brave ライブラリを使用して Java アプリケーションをインストルメント化し、Zipkin 互換エンドポイントを介して ARMS トレーシング分析にトレースデータをレポートする方法を説明します。

インストルメンテーション方法の選択

フレームワークに適した方法を選択してください。Spring Sleuth は最小限の設定で済むため、Spring Boot プロジェクトに推奨されます。

方法 最適な用途 複雑さ
Spring Sleuth Spring Cloud マイクロサービス (推奨) 低
Spring 4.0 MVC または Spring Boot 最新のアノテーションベース Spring プロジェクト 中
Spring 2.5 または 3.0 MVC レガシー XML ベース Spring プロジェクト 中
Dubbo Dubbo RPC アプリケーション 中
手動インストルメンテーション スパンとタグの完全な制御 高

データフロー

アプリケーションは Brave ライブラリを使用してスパンを作成し、Zipkin 互換エンドポイントを介して ARMS にレポートします。

Use Zipkin to report data

前提条件

Zipkinエンドポイントの取得

トレースデータをレポートするには、トレーシング分析コンソールから Zipkin 互換エンドポイントが必要です。

  1. トレーシング分析コンソール にログインします。

  2. 左側のナビゲーションペインで、[クラスター設定] をクリックします。次に、[アクセスポイント情報] タブをクリックします。

  3. トップナビゲーションバーで、リージョンを選択します。[クラスター情報] セクションで、[トークンの表示] をオンにします。

  4. [クライアント] セクションで Zipkin をクリックします。

[関連情報] 列からエンドポイントをコピーします。

Endpoint of Jaeger or Zipkin
アプリケーションが Alibaba Cloud の本番環境で実行される場合は、Alibaba Cloud VPC アクセスポイントを使用してください。それ以外の場合は、パブリックエンドポイントを使用してください。
v1 を使用する特別な理由がない限り、v2 エンドポイントを使用してください。

サポートされているフレームワーク

Brave は以下の Java フレームワークのインストルメンテーションを提供しています。完全なリストについては、「brave-instrumentation」をご参照ください。

Apache HttpClient、Dubbo、gRPC、JAX-RS 2.X、Jersey Server、JMS、Kafka、MySQL、Netty、OkHttp、Servlet、Spark、Spring Boot、Spring MVC

デモプロジェクト

各インストルメンテーション方法に対応する動作可能なデモが用意されています。デモプロジェクトをダウンロードし、対応するディレクトリの README に従ってください。

方法 デモディレクトリ
手動インストルメンテーション manualDemo
Spring 2.5 または 3.0 MVC springMvcDemo\webmvc3|webmvc25
Spring 4.0 MVC または Spring Boot springMvcDemo\webmvc4-boot|webmvc4
Dubbo dubboDemo
Spring Sleuth sleuthDemo

Spring Sleuthによるインストルメンテーション

Spring Cloud Sleuth は、最小限の設定で Spring Boot アプリケーションに自動分散トレーシングを提供します。Zipkin とのネイティブ統合により、トレースレポートが可能です。

ステップ1:依存関係の追加

pom.xml に以下の依存関係を追加します。

<dependency>
    <groupId>io.zipkin.brave</groupId>
    <artifactId>brave</artifactId>
    <version>5.4.2</version>
</dependency>

<dependency>
    <groupId>io.zipkin.reporter2</groupId>
    <artifactId>zipkin-sender-okhttp3</artifactId>
    <version>2.7.9</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.0.1.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-sleuth-core</artifactId>
    <version>2.0.1.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-sleuth-zipkin</artifactId>
    <version>2.0.1.RELEASE</version>
</dependency>

ステップ2:application.ymlの設定

Zipkin ベース URL とサンプリングレートを設定します。<endpoint_short> を、トレース分析コンソールの [アクセスポイント情報] タブから取得した、api/v2/spans で終わるパブリックエンドポイントに置き換えます。

spring:
   application:
     # Zipkin のサービス名として使用されます
     name: sleuthDemo
   zipkin:
     # Zipkin に送信する場合はコメントを外し、192.168.99.100 を Zipkin の IP アドレスに置き換えます
     baseUrl: <endpoint_short>

   sleuth:
     sampler:
       probability: 1.0

   sample:
   zipkin:
     # enabled: true に設定すると、トレースが Zipkin に送信されます。false の場合、トレースはコンソールに記録されます。
     enabled: true

ステップ3:セットアップの検証

HTTP リクエストを送信して、トレースレポートをトリガーします。

http://localhost:3380/traced

リクエストを送信した後、トレーシング分析コンソールで受信トレースデータを確認します。追加のリクエストパスについては、デモプロジェクトの com.alibaba.apm.SampleController 配下のメソッドをご参照ください。

Spring 4.0 MVCまたはSpring Bootによるインストルメンテーション

Spring 4.0 MVC または Spring Boot アプリケーション向けに、Java アノテーションを使用してトレーシングを設定します。

動作可能な例については、デモプロジェクトの springMvcDemo\webmvc4-boot|webmvc4 ディレクトリをご参照ください。

ステップ1:トレーシングとフィルターBeanの設定

以下の設定クラスを追加します。<endpoint> を、前提条件で取得したエンドポイントに置き換えます。

/** Zipkin へのスパン送信方法の設定 */
@Bean Sender sender() {
  return OkHttpSender.create("<endpoint>");
}

/** Zipkin 用のメッセージにスパンをバッファリングする方法の設定 */
@Bean AsyncReporter<Span> spanReporter() {
  return AsyncReporter.create(sender());
}

/** UI に表示される名前などのトレーシングの側面を制御します */
@Bean Tracing tracing(@Value("${spring.application.name}") String serviceName) {
  return Tracing.newBuilder()
      .localServiceName(serviceName)
      .propagationFactory(ExtraFieldPropagation.newFactory(B3Propagation.FACTORY, "user-name"))
      .currentTraceContext(ThreadLocalCurrentTraceContext.newBuilder()
          .addScopeDecorator(MDCScopeDecorator.create()) // トレース ID をログに記録します
          .build()
      )
      .spanReporter(spanReporter()).build();
}

/** スパンの命名とタグ付けの方法を決定します。デフォルトでは、HTTP メソッドと同じ名前が付けられます。*/
@Bean HttpTracing httpTracing(Tracing tracing) {
  return HttpTracing.create(tracing);
}

/** HTTP リクエストのクライアントスパンを作成します */
// 先行する設定で RestTemplate Bean が提供されるため、BPP を使用しています
@Bean BeanPostProcessor connectionFactoryDecorator(final BeanFactory beanFactory) {
  return new BeanPostProcessor() {
    @Override public Object postProcessBeforeInitialization(Object bean, String beanName) {
      return bean;
    }

    @Override public Object postProcessAfterInitialization(Object bean, String beanName) {
      if (!(bean instanceof RestTemplate)) return bean;

      RestTemplate restTemplate = (RestTemplate) bean;
      List<ClientHttpRequestInterceptor> interceptors =
          new ArrayList<>(restTemplate.getInterceptors());
      interceptors.add(0, getTracingInterceptor());
      restTemplate.setInterceptors(interceptors);
      return bean;
    }

    // BPP が何かをプロキシする必要がないように、遅延ルックアップを行います。
    ClientHttpRequestInterceptor getTracingInterceptor() {
      return TracingClientHttpRequestInterceptor.create(beanFactory.getBean(HttpTracing.class));
    }
  };
}

/** HTTP リクエストのサーバースパンを作成します */
@Bean Filter tracingFilter(HttpTracing httpTracing) {
  return TracingFilter.create(httpTracing);
}

@Autowired SpanCustomizingAsyncHandlerInterceptor webMvcTracingCustomizer;

/** アプリケーション定義の Web タグでサーバースパンを装飾します */
@Override public void addInterceptors(InterceptorRegistry registry) {
  registry.addInterceptor(webMvcTracingCustomizer);
}

ステップ2:自動設定の有効化

src/main/resources/META-INF/spring.factories に以下の行を追加します。

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
brave.webmvc.TracingConfiguration

Spring 2.5または3.0 MVCによるインストルメンテーション

Spring 2.5 または 3.0 MVC アプリケーション向けに、XML Bean 定義を使用してトレーシングを設定します。

動作可能な例については、デモプロジェクトの springMvcDemo\webmvc3|webmvc25 ディレクトリをご参照ください。

ステップ1:トレーシングオブジェクトの設定

applicationContext.xml に以下の Bean 定義を追加します。<endpoint> を、前提条件で取得したエンドポイントに置き換えます。

<bean class="zipkin2.reporter.beans.OkHttpSenderFactoryBean">
  <property name="endpoint" value="<endpoint>"/>
</bean>

<!-- Spring 設定からサービス名を読み取ることができます -->
<context:property-placeholder/>

<bean class="brave.spring.beans.TracingFactoryBean">
  <property name="localServiceName" value="brave-webmvc3-example"/>
  <property name="spanReporter">
    <bean class="zipkin2.reporter.beans.AsyncReporterFactoryBean">
      <property name="encoder" value="JSON_V2"/>
      <property name="sender" ref="sender"/>
      <!-- クローズ時に実行中のスパンを最大 0.5 秒待機します -->
      <property name="closeTimeout" value="500"/>
    </bean>
  </property>
  <property name="propagationFactory">
    <bean class="brave.propagation.ExtraFieldPropagation" factory-method="newFactory">
      <constructor-arg index="0">
        <util:constant static-field="brave.propagation.B3Propagation.FACTORY"/>
      </constructor-arg>
      <constructor-arg index="1">
        <list>
          <value>user-name</value>
        </list>
      </constructor-arg>
    </bean>
  </property>
  <property name="currentTraceContext">
    <bean class="brave.spring.beans.CurrentTraceContextFactoryBean">
      <property name="scopeDecorators">
        <bean class="brave.context.log4j12.MDCScopeDecorator" factory-method="create"/>
      </property>
    </bean>
  </property>
</bean>

<bean class="brave.spring.beans.HttpTracingFactoryBean">
  <property name="tracing" ref="tracing"/>
</bean>

ステップ2:インターセプターの追加

トレーシング HTTP クライアントビルダーとハンドラーインターセプターを登録します。

<bean class="brave.httpclient.TracingHttpClientBuilder"
      factory-method="create">
    <constructor-arg type="brave.http.HttpTracing" ref="httpTracing"/>
  </bean>

  <bean factory-bean="httpClientBuilder" factory-method="build"/>

  <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
    <property name="interceptors">
      <list>
        <bean class="brave.spring.webmvc.SpanCustomizingHandlerInterceptor"/>
      </list>
    </property>
  </bean>

  <!-- コントローラーをロードします -->
  <context:component-scan base-package="brave.webmvc"/>

ステップ3:サーブレットフィルターの追加

web.xml にトレーシングフィルターを追加して、すべての受信リクエストをインターセプトします。

<!-- 標準トレーシングフィルターにデリゲートを追加し、すべてのパスにマッピングします -->
<filter>
  <filter-name>tracingFilter</filter-name>
  <filter-class>brave.spring.webmvc.DelegatingTracingFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>tracingFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

Dubboによるインストルメンテーション

Brave Dubbo インストルメンテーションライブラリは、Dubbo RPC アプリケーションに分散トレーシングを追加します。

動作可能な例については、デモプロジェクトの dubboDemo ディレクトリをご参照ください。

ステップ1:依存関係の追加

pom.xml に以下の依存関係を追加します。

<dependency>
    <groupId>io.zipkin.brave</groupId>
    <artifactId>brave</artifactId>
    <version>5.4.2</version>
</dependency>

<dependency>
    <groupId>io.zipkin.brave</groupId>
    <artifactId>brave-instrumentation-dubbo-rpc</artifactId>
    <version>5.4.2</version>
</dependency>

<dependency>
    <groupId>io.zipkin.brave</groupId>
    <artifactId>brave-spring-beans</artifactId>
    <version>5.4.2</version>
</dependency>

<dependency>
    <groupId>io.zipkin.brave</groupId>
    <artifactId>brave-context-slf4j</artifactId>
    <version>5.4.2</version>
</dependency>

<dependency>
    <groupId>io.zipkin.reporter2</groupId>
    <artifactId>zipkin-sender-okhttp3</artifactId>
    <version>2.7.9</version>
</dependency>

ステップ2:トレーシングオブジェクトの設定

Spring XML 設定に以下の Bean 定義を追加します。<endpoint> を、前提条件で取得したエンドポイントに置き換えます。

<bean class="zipkin2.reporter.beans.OkHttpSenderFactoryBean">
    <property name="endpoint" value="<endpoint>"/>
</bean>

<bean class="brave.spring.beans.TracingFactoryBean">
    <property name="localServiceName" value="double-provider"/>
    <property name="spanReporter">
        <bean class="zipkin2.reporter.beans.AsyncReporterFactoryBean">
            <property name="sender" ref="sender"/>
            <!-- クローズ時に実行中のスパンを最大 0.5 秒待機します -->
            <property name="closeTimeout" value="500"/>
        </bean>
    </property>
    <property name="currentTraceContext">
        <bean class="brave.spring.beans.CurrentTraceContextFactoryBean">
            <property name="scopeDecorators">
                <bean class="brave.context.slf4j.MDCScopeDecorator" factory-method="create"/>
            </property>
        </bean>
    </property>
</bean>

ステップ3:トレーシングフィルターの追加

プロバイダーとコンシューマーの両方の設定にトレーシングフィルターを適用します。

// サーバー設定
<dubbo:provider filter="tracing" />
// クライアント設定
<dubbo:consumer filter="tracing" />

Javaアプリケーションの手動インストルメンテーション

手動インストルメンテーションにより、トレースする操作と各スパンに付加するメタデータをきめ細かく制御できます。自動インストルメンテーションがフレームワークをカバーしていない場合や、カスタムスパン粒度が必要な場合に、この方法を使用します。

動作可能な例については、デモプロジェクトの manualDemo ディレクトリをご参照ください。

ステップ1:依存関係の追加

pom.xml に以下の依存関係を追加します。

<dependency>
    <groupId>io.zipkin.brave</groupId>
    <artifactId>brave</artifactId>
    <version>5.4.2</version>
</dependency>
<dependency>
    <groupId>io.zipkin.reporter2</groupId>
    <artifactId>zipkin-sender-okhttp3</artifactId>
    <version>2.7.9</version>
</dependency>

ステップ2:トレーサーの作成

Zipkin エンドポイントを使用してトレーサーを初期化します。<endpoint> を、前提条件で取得したエンドポイントに置き換えます。

private static final String zipkinEndPoint = "<endpoint>";
...
// スパンデータを送信するための Sender を作成します
OkHttpSender sender = OkHttpSender.newBuilder().endpoint(zipkinEndPoint).build();

// 非同期レポーターを作成します
Reporter<Span> reporter = AsyncReporter.builder(sender).build();

tracing = Tracing.newBuilder().localServiceName(localServiceName).spanReporter(reporter).build();

ステップ3:スパンの作成

ルートスパンを作成し、子スパンをネストしてサブオペレーションを表現します。

private void firstBiz() {
    // ルートスパンを作成し、try-with-resources でスコープを管理します
    try (Scope scope = tracing.tracer().startScopedSpan("parentSpan")) {
        Span span = tracing.tracer().currentSpan();
        span.tag("key", "firstBiz");
        secondBiz();
    } // スコープがクローズされると、スパンも自動的に終了します
}

private void secondBiz() {
    // 親のコンテキストを引き継いで子スパンを作成します
    try (Scope scope = tracing.tracer().startScopedSpanWithParent("childSpan", tracing.tracer().currentSpan().context())) {
        Span childSpan = tracing.tracer().currentSpan();
        childSpan.tag("key", "secondBiz");
        System.out.println("end tracing,id:" + childSpan.context().traceIdString());
    } // スコープがクローズされると、スパンも自動的に終了します
}

ステップ4:カスタムタグの追加 (オプション)

トラブルシューティングを容易にするために、スパンにメタデータを付加します。例えば、HTTP ステータスコードを記録します。

tracer.activeSpan().tag("http.status_code", "500");

ステップ5:サービス間でのトレースコンテキストの伝播

分散システムでは、トレースコンテキスト (TraceId、ParentSpanId、SpanId、Sampled) を各 RPC リクエストとともに伝播させる必要があります。クライアント側で inject を呼び出してコンテキストをリクエストヘッダーに埋め込み、サーバー側で extract を呼び出して読み取ります。

Inject and Extract flow

クライアント側 -- コンテキストのインジェクト

// クライアントリクエストを表す新しいスパンを開始します
oneWaySend = tracer.nextSpan().name(service + "/" + method).kind(CLIENT);
--snip--

// リクエストにトレースコンテキストを追加して、インバンドで伝播できるようにします
tracing.propagation().injector(Request::addHeader)
                 .inject(oneWaySend.context(), request);

// リクエストを非同期で実行し、レスポンスを完全に破棄します
request.execute();

// クライアント側を開始し、finish ではなく flush を実行します
oneWaySend.start().flush();

サーバー側 -- コンテキストのエクストラクト

// 受信リクエストからコンテキストを取り出します
extractor = tracing.propagation().extractor(Request::getHeader);

// そのコンテキストを、名前を付けてタグを追加できるスパンに変換します
oneWayReceive = nextSpan(tracer, extractor.extract(request))
    .name("process-request")
    .kind(SERVER)
    ... タグなどを追加

// サーバー側を開始し、finish ではなく flush を実行します
oneWayReceive.start().flush();

// このスパンは完了しているため、これ以上変更しないでください。ただし、
// 後続作業を表す子スパンを作成できます。
next = tracer.newSpan(oneWayReceive.context()).name("step2").start();

よくある質問

Q:デモを実行してもトレースデータが表示されません。

A:通常、これはエンドポイント設定が正しくないことを示しています。問題を診断するには、次の手順を実行してください。

  1. エンドポイントが Tracing Analysis コンソールの[アクセスポイント情報]タブに表示されているものと一致することを確認してください。

  2. エンドポイントをコピーする際に、正しいクライアントタイプ (Jaeger ではなく Zipkin) を選択したことを確認してください。

  3. VPC アクセスポイントを使用する場合は、アプリケーションが同じ VPC 内で実行されていることを確認してください。

  4. さらにデバッグするには、zipkin2.reporter.okhttp3.HttpCall の parseResponse メソッドにブレークポイントを設定し、HTTP レスポンスを検査してください。403 エラーは、ユーザー名の設定が無効であることを示しています。エンドポイント設定を確認してください。