Verfolgen Sie die in Jersey mit Zipkin erstellte Java-Anwendung JAX-RS2.
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
Die Bewerbung erfolgt mit Jersey, wie der Titel schon sagt. Die fertige Bewerbung wird auf github hochgeladen.
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>
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.
bold.jaxrs2.TracingFeature
ist eine Trace-Instrumentierung für JAX-RS2, die Tracing-Daten erstellt (https://zipkin.io/pages/architecture.html). zipkin.reporter.AsyncReporter
sendet die in der Anwendung gesammelten Ablaufverfolgungsdaten an den Zipkin -Server.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.