すべてのプロダクト
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.HttpCallparseResponse メソッドにブレークポイントを設定し、HTTP レスポンスを検査してください。403 エラーは、ユーザー名の設定が無効であることを示しています。エンドポイント設定を確認してください。