Skip to content

Commit

Permalink
Adds eureka support to micrometer example (#114)
Browse files Browse the repository at this point in the history
Signed-off-by: Adrian Cole <[email protected]>
  • Loading branch information
codefromthecrypt authored May 24, 2024
1 parent 3164cc8 commit 6a28c25
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 39 deletions.
2 changes: 1 addition & 1 deletion build-bin/test
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ build-bin/docker/docker_build ${docker_image} ${VERSION}
docker_compose_file=build-bin/docker-compose.test.yml

case ${VERSION} in
armeria|*sleuth* )
armeria|*sleuth*|*micrometer* )
docker_compose_file=build-bin/docker-compose-eureka.test.yml
;;
armeria-kafka )
Expand Down
43 changes: 18 additions & 25 deletions webflux6-micrometer/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,34 +19,10 @@
<jre.version>21</jre.version>
<maven.compiler.release>17</maven.compiler.release>

<spring-boot.version>3.3.0-RC1</spring-boot.version>
<spring-boot.version>3.3.0</spring-boot.version>
<micrometer.version>1.3.0</micrometer.version>
</properties>

<!-- Temporary until Spring boot 3.3.0 -->
<pluginRepositories>
<pluginRepository>
<id>repository.spring.milestone</id>
<name>Spring Milestone Repository</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>

<!-- Temporary until Spring boot 3.3.0 -->
<repositories>
<repository>
<id>repository.spring.milestone</id>
<name>Spring Milestone Repository</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>

<dependencyManagement>
<dependencies>
<dependency>
Expand All @@ -71,6 +47,23 @@
<artifactId>spring-boot-starter-actuator</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>4.1.1</version>
<exclusions>
<!-- dodge spring-jcl conflict error -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>

<!-- micrometer-tracing-bridge-brave configures instrumentation including what's in Brave and their own. -->
<dependency>
Expand Down
16 changes: 11 additions & 5 deletions webflux6-micrometer/src/main/java/brave/example/Backend.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package brave.example;

import java.time.LocalDate;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
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.RequestHeader;
Expand All @@ -12,7 +16,10 @@

@EnableAutoConfiguration
@RestController
@Import(CustomObservationConfiguration.class)
@Import(value = {
CustomObservationConfiguration.class,
ZipkinDiscoveryConfiguration.class
})
public class Backend {

@GetMapping("/api")
Expand All @@ -24,9 +31,8 @@ public Mono<String> printDate(@RequestHeader("user_name") Optional<String> 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");
}
}
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -21,7 +20,7 @@ public class CustomObservationConfiguration {
* spring.sleuth.web.additional-skip-pattern=/health
* </pre>
*
* <p>Brave uses {@link HttpTracing#serverRequestSampler()} for server request sampling policy.
* <p>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.
Expand Down
16 changes: 10 additions & 6 deletions webflux6-micrometer/src/main/java/brave/example/Frontend.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -12,7 +12,10 @@

@EnableAutoConfiguration
@RestController
@Import(CustomObservationConfiguration.class)
@Import(value = {
CustomObservationConfiguration.class,
ZipkinDiscoveryConfiguration.class
})
public class Frontend {
final WebClient webClient;

Expand All @@ -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"
);
}
}
Original file line number Diff line number Diff line change
@@ -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<String, Object> discoveryProperties() {
Map<String, Object> 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 + "}";
}
}
}
4 changes: 4 additions & 0 deletions webflux6-micrometer/src/main/resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down

0 comments on commit 6a28c25

Please sign in to comment.