usern
}
public static void main(String[] args) {
- SpringApplication.run(Backend.class,
- "--spring.application.name=backend",
- "--server.port=9000"
- );
+ new SpringApplicationBuilder(Backend.class)
+ .properties(ZipkinDiscoveryConfiguration.discoveryProperties())
+ .run("--spring.application.name=backend", "--server.port=9000");
}
}
diff --git a/webflux6-micrometer/src/main/java/brave/example/CustomObservationConfiguration.java b/webflux6-micrometer/src/main/java/brave/example/CustomObservationConfiguration.java
index aef0fca..aadf3d0 100644
--- a/webflux6-micrometer/src/main/java/brave/example/CustomObservationConfiguration.java
+++ b/webflux6-micrometer/src/main/java/brave/example/CustomObservationConfiguration.java
@@ -1,6 +1,5 @@
package brave.example;
-import brave.http.HttpTracing;
import io.micrometer.observation.ObservationPredicate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -21,7 +20,7 @@ public class CustomObservationConfiguration {
* spring.sleuth.web.additional-skip-pattern=/health
*
*
- * Brave uses {@link HttpTracing#serverRequestSampler()} for server request sampling policy.
+ *
Brave uses {@code HttpTracing#serverRequestSampler()} for server request sampling policy.
* Micrometer tracing bridges to Brave's core API, so it doesn't see or use the HTTP, Messaging or
* RPC policies. Instead, it relies on its own type, {@link ObservationPredicate}, which applies
* both to metrics and tracing.
diff --git a/webflux6-micrometer/src/main/java/brave/example/Frontend.java b/webflux6-micrometer/src/main/java/brave/example/Frontend.java
index 4b19add..883362c 100644
--- a/webflux6-micrometer/src/main/java/brave/example/Frontend.java
+++ b/webflux6-micrometer/src/main/java/brave/example/Frontend.java
@@ -2,8 +2,8 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.annotation.Import;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -12,7 +12,10 @@
@EnableAutoConfiguration
@RestController
-@Import(CustomObservationConfiguration.class)
+@Import(value = {
+ CustomObservationConfiguration.class,
+ ZipkinDiscoveryConfiguration.class
+})
public class Frontend {
final WebClient webClient;
@@ -26,9 +29,10 @@ public class Frontend {
}
public static void main(String[] args) {
- SpringApplication.run(Frontend.class,
- "--spring.application.name=frontend",
- "--server.port=8081"
- );
+ new SpringApplicationBuilder(Frontend.class)
+ .properties(ZipkinDiscoveryConfiguration.discoveryProperties())
+ .run("--spring.application.name=frontend",
+ "--server.port=8081"
+ );
}
}
diff --git a/webflux6-micrometer/src/main/java/brave/example/ZipkinDiscoveryConfiguration.java b/webflux6-micrometer/src/main/java/brave/example/ZipkinDiscoveryConfiguration.java
new file mode 100644
index 0000000..e26846f
--- /dev/null
+++ b/webflux6-micrometer/src/main/java/brave/example/ZipkinDiscoveryConfiguration.java
@@ -0,0 +1,67 @@
+package brave.example;
+
+import java.net.URI;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.cloud.client.ServiceInstance;
+import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import zipkin2.reporter.HttpEndpointSupplier;
+import zipkin2.reporter.HttpEndpointSuppliers;
+
+@Configuration(proxyBeanMethods = false)
+@ConditionalOnProperty("EUREKA_SERVICE_URL")
+public class ZipkinDiscoveryConfiguration {
+
+ /**
+ * It is very difficult to stop loadbalancer or discovery from initializing when starters are on
+ * the classpath. This is a workaround to disable it when EUREKA_SERVICE_URL is not set.
+ */
+ static Map discoveryProperties() {
+ Map properties = new LinkedHashMap<>();
+ String eurekaServiceUrl = System.getenv("EUREKA_SERVICE_URL");
+ boolean eurekaEnabled = eurekaServiceUrl != null && !eurekaServiceUrl.isEmpty();
+ if (eurekaEnabled) {
+ properties.put("eureka.client.serviceUrl.defaultZone", eurekaServiceUrl);
+ }
+ properties.put("spring.cloud.loadbalancer.enabled", eurekaEnabled);
+ properties.put("spring.cloud.discovery.enabled", eurekaEnabled);
+ return properties;
+ }
+
+ @Bean HttpEndpointSupplier.Factory loadbalancerEndpoints(LoadBalancerClient loadBalancerClient) {
+ LoadBalancerHttpEndpointSupplier.Factory httpEndpointSupplierFactory =
+ new LoadBalancerHttpEndpointSupplier.Factory(loadBalancerClient);
+ // don't ask more than 30 seconds (just to show)
+ return HttpEndpointSuppliers.newRateLimitedFactory(httpEndpointSupplierFactory, 30);
+ }
+
+ record LoadBalancerHttpEndpointSupplier(LoadBalancerClient loadBalancerClient, URI virtualURL)
+ implements HttpEndpointSupplier {
+ record Factory(LoadBalancerClient loadBalancerClient) implements HttpEndpointSupplier.Factory {
+
+ @Override public HttpEndpointSupplier create(String endpoint) {
+ return new LoadBalancerHttpEndpointSupplier(loadBalancerClient, URI.create(endpoint));
+ }
+ }
+
+ @Override public String get() {
+ // At least spring-cloud-netflix wants the actual hostname as a lookup value
+ ServiceInstance instance = loadBalancerClient.choose(virtualURL.getHost());
+ if (instance != null) {
+ return instance.getUri() + virtualURL.getPath();
+ }
+ throw new IllegalArgumentException(
+ virtualURL.getHost() + " is not an instance registered in Eureka");
+ }
+
+ @Override public void close() {
+ }
+
+ @Override public String toString() {
+ return "LoadBalancer{" + virtualURL + "}";
+ }
+ }
+}
diff --git a/webflux6-micrometer/src/main/resources/application.yaml b/webflux6-micrometer/src/main/resources/application.yaml
index 09c2e65..e3f0509 100644
--- a/webflux6-micrometer/src/main/resources/application.yaml
+++ b/webflux6-micrometer/src/main/resources/application.yaml
@@ -34,6 +34,10 @@ management:
tracing:
# Note: There is no property to bind ${brave.localServiceName:${spring.application.name}}
endpoint: ${zipkin.baseUrl:http://127.0.0.1:9411}/api/v2/spans
+spring:
+ cloud:
+ compatibilityVerifier:
+ enabled: false
logging:
level: