[JAVA] Einführung in Zipkin to Jersey (JAX-RS2) -Anwendungen

Was willst du tun

Verfolgen Sie die in Jersey mit Zipkin erstellte Java-Anwendung JAX-RS2.

jersey-zipkin.png

Richten Sie einen Zipkin-Server ein

Installieren Sie Docker.

Linux installiert docker-compose zusätzlich. Mac und Windows sind nicht erforderlich, da sie im Docker-Installationsprogramm enthalten sind.

sudo curl -L https://github.com/docker/compose/releases/download/1.18.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

Klonen Sie Docker-Zipkin von Github und führen Sie den Zipkin -Server mit Docker aus.

git clone https://github.com/openzipkin/docker-zipkin.git
cd docker-zipkin
docker-compose up -d

Sie können unter der folgenden URL auf die Zipkin-Web-Benutzeroberfläche zugreifen

Implementieren Sie die Anwendung

Die Bewerbung erfolgt mit Jersey, wie der Titel schon sagt. Die fertige Bewerbung wird auf github hochgeladen.

Abhängige Bibliothek (pom.xml)

Verwendet Jersey 2, eine serverseitige JAX-RS2-Referenzimplementierung.

Beachten Sie, dass groupId progressivecom.sun.jersey``, die häufig beim Googeln in Jersey angezeigt wird, nicht mit der Jersey 1-Serie kompatibel ist.

<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.core/jersey-server -->
<dependency>
  <groupId>org.glassfish.jersey.core</groupId>
  <artifactId>jersey-server</artifactId>
  <version>2.26</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.inject/jersey-hk2 -->
<dependency>
  <groupId>org.glassfish.jersey.inject</groupId>
  <artifactId>jersey-hk2</artifactId>
  <version>2.26</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.containers/jersey-container-servlet -->
<dependency>
  <groupId>org.glassfish.jersey.containers</groupId>
  <artifactId>jersey-container-servlet</artifactId>
  <version>2.26</version>
</dependency>

Das clientseitige JAX-RS2 verwendet auch Jersey 2, eine Referenzimplementierung.

<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.core/jersey-client -->
<dependency>
  <groupId>org.glassfish.jersey.core</groupId>
  <artifactId>jersey-client</artifactId>
  <version>2.26</version>
</dependency>

In Java geschriebene Webanwendungen werden normalerweise von Tomcat, Glassfish, Jetty usw. ausgeführt. Verwenden Sie diesmal der Einfachheit halber jersey-container-jdk-http, um den HTTP-Server zu implementieren. Direkt in die Anwendung einbetten.

<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.containers/jersey-container-jdk-http -->
<dependency>
  <groupId>org.glassfish.jersey.containers</groupId>
  <artifactId>jersey-container-jdk-http</artifactId>
  <version>2.26</version>
</dependency>

JAX-RS2 Zipkin Instrumentation-Bibliothek für Java-Anwendungen, mit der Sie JAX-RS-Server / -Clients verfolgen können.

<!-- https://mvnrepository.com/artifact/io.zipkin.brave/brave-instrumentation-jaxrs2 -->
<dependency>
  <groupId>io.zipkin.brave</groupId>
  <artifactId>brave-instrumentation-jaxrs2</artifactId>
  <version>4.3.1</version>
</dependency>

Die gesammelten Ablaufverfolgungsdaten müssen an den Zipkin -Server gesendet werden. Diese Bibliothek sendet sie an ein beliebiges Ziel.

<!-- https://mvnrepository.com/artifact/io.zipkin.reporter/zipkin-sender-urlconnection -->
<dependency>
  <groupId>io.zipkin.reporter</groupId>
  <artifactId>zipkin-sender-urlconnection</artifactId>
  <version>1.1.2</version>
</dependency>

Java-Code

Mit JAX-RS2 können Sie eine externe Bibliothek anschließen, die javax.ws.rs.core.Feature IF implementiert.

Brave, eine Zipkin -Bibliothek für Java-Anwendungen, unterstützt verschiedene Java-Frameworks. Dieses Mal werden wir [mutig-instrumentation-jaxrs2] für JAX-RS2 verwenden.

package zipkin;

import brave.Tracing;
import brave.jaxrs2.TracingFeature;
import brave.sampler.Sampler;
import zipkin.reporter.AsyncReporter;
import zipkin.reporter.urlconnection.URLConnectionSender;
import javax.ws.rs.core.Feature;

public class ZipkinFeature {

    /**
     * @param localServiceName Dienstname, der in der Zipkin-Web-Benutzeroberfläche angezeigt wird
     */
    public static Feature create(String localServiceName) {
        // create a zipkin reporter.
        AsyncReporter<Span> asyncReporter = AsyncReporter
                .builder(URLConnectionSender.create("http://localhost:9411/api/v1/spans"))
                .build();

        // create a zipkin tracing.
        Tracing tracing = Tracing.newBuilder()
                .reporter(asyncReporter)
                .localServiceName(localServiceName)
                .sampler(Sampler.ALWAYS_SAMPLE)
                .build();

        // create a JAX-RS feature.
        Feature tracingFeature = TracingFeature.create(tracing);

        return tracingFeature;
    }
}

Erstellen Sie eine Klasse, die den serverseitigen JAX-RS2-Einstiegspunkt "javax.ws.rs.core.Application" implementiert Registrieren Sie sich bei serverseitigem JAX-RS2.

package app;

import zipkin.ZipkinFeature;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Feature;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;

@ApplicationPath("")
public class MyApplication extends Application {

    @Override
    public Set<Object> getSingletons() {
        // create a JAX-RS feature.
        Feature tracingFeature = ZipkinFeature.create("server");

        return new LinkedHashSet<>(Arrays.asList(tracingFeature));
    }
}

Erstellen Sie eine Ressourcenklasse (API-Definition) für serverseitiges JAX-RS2. Ursprünglich möchte ich mehrere Dienste bereitstellen und die Funktionsweise von Zipkin überprüfen. Der Einfachheit halber definieren Sie jedoch 3 APIs und Client-JAX. - In der Reihenfolge von RS2 angerufen. Auch hier ist die zuvor generierte Tracing-Funktion bold.jaxrs2.TracingFeature im Client JAX-RS2 registriert.

package resource;

import zipkin.ZipkinFeature;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.Feature;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

@Path("")
public class MyResource {

    /**
     * /front --> /mid --> /back
     *
     * @return String that will be returned as a text/plain response.
     */
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    @Path("front")
    public Response front() {
        // create a JAX-RS feature.
        Feature tracingFeature = ZipkinFeature.create("client");

        // http client: GET /mid
        Response r = ClientBuilder.newClient()
                .register(tracingFeature)
                .target("http://localhost:8080/myapp/mid")
                .request()
                .get();

        return Response.fromResponse(r).build();
    }

    /**
     * /mid --> /back
     *
     * @return String that will be returned as a text/plain response.
     */
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    @Path("mid")
    public Response mid() {
        // create a JAX-RS feature.
        Feature tracingFeature = ZipkinFeature.create("client");

        // http client: GET /back
        Response r = ClientBuilder.newClient()
                .register(tracingFeature)
                .target("http://localhost:8080/myapp/back")
                .request()
                .get();

        return Response.fromResponse(r).build();
    }

    /**
     * /back
     *
     * @return String that will be returned as a text/plain response.
     */
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    @Path("back")
    public String back() {
        return "hello";
    }
}

Wir verwenden jersey-container-jdk-http für die Implementierung des HTTP-Servers, da dies problemlos funktionieren soll.

package main;

import app.MyApplication;
import com.sun.net.httpserver.HttpServer;
import org.glassfish.jersey.jdkhttp.JdkHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;
import java.net.URI;

public class Main {

    public static void main(String[] args) {
        // register JAX-RS Application class.
        ResourceConfig rc = ResourceConfig.forApplicationClass(MyApplication.class);

        // register a path of REST resources.
        rc.packages(true, "resource");

        // run a jersey server.
        URI uri = URI.create("http://localhost:8080/myapp/");
        HttpServer httpServer = JdkHttpServerFactory.createHttpServer(uri, rc);
        Runtime.getRuntime().addShutdownHook(new Thread(() -> httpServer.stop(0)));
    }
}

Führen Sie die Anwendung aus. Sie können unter der folgenden URL darauf zugreifen.

Lassen Sie uns auf die Zipkin-Web-Benutzeroberfläche zugreifen. Sie sollten in der Lage sein, die Ablaufverfolgungsdaten des vorherigen Zugriffs anzuzeigen.

zipkin.png

Recommended Posts

Einführung in Zipkin to Jersey (JAX-RS2) -Anwendungen
Versuchen Sie, die Rails-App für EC2-Part 2 (Server Construction) bereitzustellen.
JAX-RS (Jersey) Tipps