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

Managed Service for OpenTelemetry:Zipkin を使用して Java アプリケーションデータを送信する

最終更新日:Dec 30, 2024

Zipkin は分散トレーシングシステムです。これは、リアルタイムデータの追跡のために Twitter によって開発されたオープンソースシステムです。Zipkin は、複数の異種システムから収集されたリアルタイムの監視データを集約するために使用されます。Zipkin を使用して、Java アプリケーションデータを Tracing Analysis に送信できます。

前提条件

Jaeger または Zipkin のエンドポイントを取得するには、次の手順を実行します。

  1. Managed Service for OpenTelemetry コンソール にログインします。

  2. 左側のナビゲーションペインで、クラスタ設定 をクリックします。表示されるページで、アクセスポイント情報 タブをクリックします。

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

  4. クライアントパラメータを Jaeger または Zipkin に設定します。この例では、Jaeger が選択されています。

    下部にある表の 関連情報 列で、Jaeger または Zipkin のエンドポイントを取得します。

    Jaeger/Zipkin接入点信息

    説明

    アプリケーションが Alibaba Cloud 本番環境にデプロイされている場合は、VPC エンドポイントを使用します。それ以外の場合は、パブリックエンドポイントを使用します。通常、Zipkin には v2 のエンドポイントを使用します。Zipkin をよく理解している場合のみ、v1 のエンドポイントを使用してください。

背景情報

Zipkin は長年にわたって開発されており、次のような Java フレームワークなど、包括的なフレームワークセットをサポートしています。詳細については、brave-instrumentation を参照してください。

  • Apache HttpClient
  • Dubbo
  • gRPC
  • JAX-RS 2.X
  • Jersey Server
  • Java Message Service (JMS)
  • Kafka
  • MySQL
  • Netty
  • OkHttp
  • Servlet
  • Spark
  • Spring Boot
  • Spring MVC

Zipkin を使用して Java アプリケーションデータを Tracing Analysis コンソールに送信するには、最初にアプリケーションをインストラメント化する必要があります。アプリケーションのインストラメント化は、手動で行うか、既存のコンポーネントを使用して行うことができます。

次の図は、Zipkin を使用してデータを送信する方法を示しています。

Java アプリケーションを手動でインストラメント化する

Java アプリケーションを手動でインストラメント化する場合は、インストラメント化コードを記述する必要があります。

説明 デモプロジェクト をダウンロードします。次に、manualDemo ディレクトリに移動し、README.md ファイルに記載されている手順を実行してデモプログラムを実行します。
  1. JAR パッケージを依存関係として追加します。
    <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. トレーサーを作成します。
    private static final String zipkinEndPoint = "<endpoint>";
      ...
      // Create an object that is used to send data. 
      OkHttpSender sender = OkHttpSender.newBuilder().endpoint(zipkinEndPoint).build();
    
      // Create an object that is used to report data. 
      Reporter<Span> reporter = AsyncReporter.builder(sender).build();
    
      tracing = Tracing.newBuilder().localServiceName(localServiceName).spanReporter(reporter).build();
  3. スパンと子スパンを作成します。
    private void firstBiz() {
            // Create a root span. 
            tracing.tracer().startScopedSpan("parentSpan");
            Span span =  tracing.tracer().currentSpan();
            span.tag("key", "firstBiz");
            secondBiz();
            span.finish();
        }
    
        private void secondBiz() {
            tracing.tracer().startScopedSpanWithParent("childSpan", tracing.tracer().currentSpan().context());
            Span childSpan =  tracing.tracer().currentSpan();
            childSpan.tag("key", "secondBiz");
            childSpan.finish();
            System.out.println("end tracing,id:" + childSpan.context().traceIdString());
        }
  4. オプション。迅速なトラブルシューティングのために、スパンにカスタムタグを追加します。たとえば、リクエストの戻り値を記録したり、エラーが発生したかどうかを確認したりするために、カスタムタグを追加できます。
    tracer.activeSpan().setTag("http.status_code", "500");
  5. 分散システムでは、リモートプロシージャコール (RPC) リクエストはトレースデータとともに送信されます。トレースデータには、TraceId、ParentSpanId、SpanId、および Sampled パラメータの値が含まれています。Extract または Inject メソッドを呼び出して、HTTP リクエストヘッダーでデータを指定できます。次の例は、プロセス全体を示しています。
    流程图
    1. クライアントで Inject メソッドを呼び出して、コンテキスト情報を指定します。
      // start a new span representing a client request
          oneWaySend = tracer.nextSpan().name(service + "/" + method).kind(CLIENT);
          --snip--
      
          // Add the trace context to the request, so it can be propagated in-band
          tracing.propagation().injector(Request::addHeader)
                           .inject(oneWaySend.context(), request);
      
         // fire off the request asynchronously, totally dropping any response
         request.execute();
      
         // start the client side and flush instead of finish
         oneWaySend.start().flush();
    2. サーバーで Extract メソッドを呼び出して、コンテキスト情報を抽出します。
      // pull the context out of the incoming request
      extractor = tracing.propagation().extractor(Request::getHeader);
      
      // convert that context to a span which you can name and add tags to
      oneWayReceive = nextSpan(tracer, extractor.extract(request))
          .name("process-request")
          .kind(SERVER)
          ... add tags etc.
      
      // start the server side and flush instead of finish
      oneWayReceive.start().flush();
      
      // you should not modify this span anymore as it is complete. However,
      // you can create children to represent follow-up work.
      next = tracer.newSpan(oneWayReceive.context()).name("step2").start();

Spring 2.5 MVC または Spring 3.0 MVC を使用して Java アプリケーションをインストラメント化する

Spring 2.5 MVC または Spring 3.0 MVC を使用して Java アプリケーションをインストラメント化できます。

説明 デモプロジェクト をダウンロードします。次に、springMvcDemo\webmvc3|webmvc25 ディレクトリに移動し、README.md ファイルに記載されている手順を実行してデモプログラムを実行します。
  1. applicationContext.xml ファイルでトレーシングオブジェクトを設定します。
    <bean class="zipkin2.reporter.beans.OkHttpSenderFactoryBean">
      <property name="endpoint" value="<endpoint>"/>
    </bean>
    
    <!-- allows us to read the service name from spring config -->
    <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"/>
          <!-- wait up to half a second for any in-flight spans on close -->
          <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. interceptors オブジェクトを追加します。
    <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>
    
      <!-- Loads the controller -->
      <context:component-scan base-package="brave.webmvc"/>
  3. filter オブジェクトを追加します。
    <!-- Add the delegate to the standard tracing filter and map it to all paths -->
    <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>

Spring 4.0 MVC または Spring Boot を使用して Java アプリケーションをインストラメント化する

Spring 4.0 MVC または Spring Boot を使用して Java アプリケーションをインストラメント化できます。

説明 デモプロジェクト をダウンロードします。次に、springMvcDemo\webmvc4-boot|webmv4 ディレクトリに移動し、README.md ファイルに記載されている手順を実行してデモプログラムを実行します。
  1. トレーシングオブジェクトとフィルターオブジェクトを設定します。
    /** Configuration for how to send spans to Zipkin */
      @Bean Sender sender() {
        return OkHttpSender.create("<endpoint>"); // Zipkin へのスパン送信方法の設定
      }
    
      /** Configuration for how to buffer spans into messages for Zipkin */
      @Bean AsyncReporter<Span> spanReporter() {
        return AsyncReporter.create(sender()); // Zipkin へのメッセージのバッファ方法の設定
      }
    
      /** Controls aspects of tracing such as the name that shows up in the UI */
      @Bean Tracing tracing(@Value("${spring.application.name}") String serviceName) {
        return Tracing.newBuilder() // UI に表示される名前など、トレースの側面を制御します
            .localServiceName(serviceName)
            .propagationFactory(ExtraFieldPropagation.newFactory(B3Propagation.FACTORY, "user-name"))
            .currentTraceContext(ThreadLocalCurrentTraceContext.newBuilder()
                .addScopeDecorator(MDCScopeDecorator.create()) // puts trace IDs into logs //トレースIDをログに記録
                .build()
            )
            .spanReporter(spanReporter()).build();
      }
    
      /** decides how to name and tag spans. By default they are named the same as the http method. */
      @Bean HttpTracing httpTracing(Tracing tracing) {
        return HttpTracing.create(tracing); // スパンの名前付けとタグ付け方法を決定します。デフォルトでは、HTTP メソッドと同じ名前が付けられます。
      }
    
      /** Creates client spans for http requests */
      // We are using a BPP as the Frontend supplies a RestTemplate bean prior to this configuration
      @Bean BeanPostProcessor connectionFactoryDecorator(final BeanFactory beanFactory) {
        return new BeanPostProcessor() { // HTTP リクエストのクライアントスパンを作成します
          @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;
          }
    
          // Lazy lookup so that the BPP doesn't end up needing to proxy anything.
          ClientHttpRequestInterceptor getTracingInterceptor() {
            return TracingClientHttpRequestInterceptor.create(beanFactory.getBean(HttpTracing.class));
          }
        };
      }
    
      /** Creates server spans for http requests */
      @Bean Filter tracingFilter(HttpTracing httpTracing) {
        return TracingFilter.create(httpTracing); // HTTP リクエストのサーバースパンを作成します
      }
    
      @Autowired SpanCustomizingAsyncHandlerInterceptor webMvcTracingCustomizer;
    
      /** Decorates server spans with application-defined web tags */
      @Override public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(webMvcTracingCustomizer); // サーバースパンをアプリケーション定義の Web タグで装飾します
      }
  2. spring.factories ファイルで自動設定を設定します。
    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    brave.webmvc.TracingConfiguration

Dubbo を使用して Java アプリケーションをインストラメント化する

Dubbo を使用して Java アプリケーションをインストラメント化できます。

説明 デモプロジェクト をダウンロードします。次に、dubboDemo ディレクトリに移動し、README.md ファイルに記載されている手順を実行してデモプログラムを実行します。
  1. JAR パッケージを依存関係として追加します。
    <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>
            <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. トレーシングオブジェクトを設定します。
    <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"/>
                    <!-- wait up to half a second for any in-flight spans on close -->
                    <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. フィルターオブジェクトを設定します。
    // Configuration on the server. 
    <dubbo:provider filter="tracing" /> // サーバー側の設定
    // Configuration on the client. 
    <dubbo:consumer filter="tracing" /> // クライアント側の設定
    

Spring Sleuth を使用して Java アプリケーションをインストラメント化する

Spring Sleuth を使用して Java アプリケーションをインストラメント化できます。

説明 デモプロジェクト をダウンロードします。次に、sleuthDemo ディレクトリに移動し、README.md ファイルに記載されている手順を実行してデモプログラムを実行します。
  1. JAR パッケージを依存関係として追加します。
    <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 ファイルを設定します。
    説明 <endpoint_short> は、クライアントとリージョンのエンドポイントに置き換える必要があります。Tracing Analysis コンソールにログインし、クラスタ設定ページの クラスター構成 タブで、api/v2/spans で終わるパブリックエンドポイントを取得できます。
    spring:
       application:
         # This ends up as the service name in zipkin // Zipkin のサービス名として使用されます
         name: sleuthDemo
       zipkin:
         # Uncomment to send to zipkin, replacing 192.168.99.100 with your zipkin IP address // Zipkin に送信するにはコメントを外し、192.168.99.100 を Zipkin の IP アドレスに置き換えます
         baseUrl: <endpoint_short>
    
       sleuth:
         sampler:
           probability: 1.0
    
       sample:
       zipkin:
         # When enabled=false, traces log to the console. Comment to send to zipkin // enabled=false の場合、トレースはコンソールに記録されます。Zipkin に送信するにはコメントアウトします
         enabled: true
  3. HTTP リクエストを開始します。例: http://localhost:3380/traced
    説明 その他のリクエストパスについては、デモプロジェクトの com.alibaba.apm.SampleController にあるメソッドを参照してください。

FAQ

Q: デモプログラムを実行した後、特定の Web サイトでデータが見つからないのはなぜですか?

A: parseResponse メソッドにブレークポイントを挿入して zipkin2.reporter.okhttp3.HttpCall をデバッグし、データ送信リクエストの戻り値を確認します。403 エラーが返された場合は、ユーザー名設定が無効です。エンドポイント設定を確認する必要があります。