Browse Source

Use management.port for locating hystrix.stream (#1317)

Allow override of /hystrix.stream location via management.port metadata.
pull/6/head
Niklas Herder 8 years ago committed by Spencer Gibb
parent
commit
61de118130
  1. 10
      docs/src/main/asciidoc/spring-cloud-netflix.adoc
  2. 3
      spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/CommonsInstanceDiscovery.java
  3. 3
      spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscovery.java
  4. 18
      spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/CommonsInstanceDiscoveryTest.java
  5. 31
      spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscoveryTest.java

10
docs/src/main/asciidoc/spring-cloud-netflix.adoc

@ -590,6 +590,16 @@ To run the Hystrix Dashboard annotate your Spring Boot main class with `@EnableH @@ -590,6 +590,16 @@ To run the Hystrix Dashboard annotate your Spring Boot main class with `@EnableH
Looking at an individual instances Hystrix data is not very useful in terms of the overall health of the system. https://github.com/Netflix/Turbine[Turbine] is an application that aggregates all of the relevant `/hystrix.stream` endpoints into a combined `/turbine.stream` for use in the Hystrix Dashboard. Individual instances are located via Eureka. Running Turbine is as simple as annotating your main class with the `@EnableTurbine` annotation (e.g. using spring-cloud-starter-turbine to set up the classpath). All of the documented configuration properties from https://github.com/Netflix/Turbine/wiki/Configuration-(1.x)[the Turbine 1 wiki] apply. The only difference is that the `turbine.instanceUrlSuffix` does not need the port prepended as this is handled automatically unless `turbine.instanceInsertPort=false`.
NOTE: By default, Turbine looks for the `/hystrix.stream` endpoint on a registered instance by looking up its `homePageUrl` entry in Eureka, then appending `/hystrix.stream` to it. This means that if `spring-boot-actuator` is running on its own port (which is the default), the call to `/hystrix.stream` will fail.
To make turbine find the Hystrix stream at the correct port, you need to add `management.port` to the instances' metadata:
----
eureka:
instance:
metadata-map:
management.port: ${management.port:8081}
----
The configuration key `turbine.appConfig` is a list of eureka serviceIds that turbine will use to lookup instances. The turbine stream is then used in the Hystrix dashboard using a url that looks like: `http://my.turbine.sever:8080/turbine.stream?cluster=<CLUSTERNAME>` (the cluster parameter can be omitted if the name is "default"). The `cluster` parameter must match an entry in `turbine.aggregator.clusterConfig`. Values returned from eureka are uppercase, thus we expect this example to work if there is an app registered with Eureka called "customers":
----

3
spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/CommonsInstanceDiscovery.java

@ -157,7 +157,8 @@ public class CommonsInstanceDiscovery implements InstanceDiscovery { @@ -157,7 +157,8 @@ public class CommonsInstanceDiscovery implements InstanceDiscovery {
*/
Instance marshall(ServiceInstance serviceInstance) {
String hostname = serviceInstance.getHost();
String port = String.valueOf(serviceInstance.getPort());
String managementPort = serviceInstance.getMetadata().get("management.port");
String port = managementPort == null ? String.valueOf(serviceInstance.getPort()) : managementPort;
String cluster = getClusterName(serviceInstance);
Boolean status = Boolean.TRUE; //TODO: where to get?
if (hostname != null && cluster != null && status != null) {

3
spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscovery.java

@ -100,7 +100,8 @@ public class EurekaInstanceDiscovery extends CommonsInstanceDiscovery { @@ -100,7 +100,8 @@ public class EurekaInstanceDiscovery extends CommonsInstanceDiscovery {
*/
Instance marshall(InstanceInfo instanceInfo) {
String hostname = instanceInfo.getHostName();
String port = String.valueOf(instanceInfo.getPort());
final String managementPort = instanceInfo.getMetadata().get("management.port");
String port = managementPort == null ? String.valueOf(instanceInfo.getPort()) : managementPort;
String cluster = getClusterName(instanceInfo);
Boolean status = parseInstanceStatus(instanceInfo.getStatus());
if (hostname != null && cluster != null && status != null) {

18
spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/CommonsInstanceDiscoveryTest.java

@ -100,7 +100,23 @@ public class CommonsInstanceDiscoveryTest { @@ -100,7 +100,23 @@ public class CommonsInstanceDiscoveryTest {
assertEquals("url is wrong", "http://"+hostName+":"+port+"/hystrix.stream", urlPath);
}
@Test
@Test
public void testUseManagementPortFromMetadata() {
CommonsInstanceDiscovery discovery = createDiscovery();
String appName = "testAppName";
int port = 8080;
int managementPort = 8081;
String hostName = "myhost";
DefaultServiceInstance serviceInstance = new DefaultServiceInstance(appName, hostName, port, false);
serviceInstance.getMetadata().put("management.port", String.valueOf(managementPort));
Instance instance = discovery.marshall(serviceInstance);
assertEquals("port is wrong", String.valueOf(managementPort), instance.getAttributes().get("port"));
String urlPath = SpringClusterMonitor.ClusterConfigBasedUrlClosure.getUrlPath(instance);
assertEquals("url is wrong", "http://"+hostName+":"+managementPort+"/hystrix.stream", urlPath);
}
@Test
public void testGetSecurePort() {
CommonsInstanceDiscovery discovery = createDiscovery();
String appName = "testAppName";

31
spring-cloud-netflix-turbine/src/test/java/org/springframework/cloud/netflix/turbine/EurekaInstanceDiscoveryTest.java

@ -89,12 +89,35 @@ public class EurekaInstanceDiscoveryTest { @@ -89,12 +89,35 @@ public class EurekaInstanceDiscoveryTest {
}
@Test
public void testGetClusterName() {
EurekaInstanceDiscovery discovery = new EurekaInstanceDiscovery(
turbineProperties, eurekaClient);
public void testUseManagementPortFromMetadata() {
EurekaInstanceDiscovery discovery = new EurekaInstanceDiscovery(turbineProperties,
eurekaClient);
String appName = "testAppName";
InstanceInfo instanceInfo = builder.setAppName(appName)
int port = 8080;
int managementPort = 8081;
String hostName = "myhost";
InstanceInfo instanceInfo = builder.setAppName(appName).setHostName(hostName).setPort(port)
.build();
instanceInfo.getMetadata().put("management.port", "8081");
Instance instance = discovery.marshall(instanceInfo);
assertEquals("hostname is wrong", hostName + ":" + managementPort, instance.getHostname());
assertEquals("port is wrong", String.valueOf(managementPort),
instance.getAttributes().get("port"));
String urlPath = SpringClusterMonitor.ClusterConfigBasedUrlClosure.getUrlPath(instance);
assertEquals("url is wrong",
"http://" + hostName + ":" + managementPort + "/hystrix.stream", urlPath);
String clusterName = discovery.getClusterName(instanceInfo);
assertEquals("clusterName is wrong", appName.toUpperCase(), clusterName);
}
@Test
public void testGetClusterName() {
EurekaInstanceDiscovery discovery = new EurekaInstanceDiscovery(turbineProperties,
eurekaClient);
String appName = "testAppName";
InstanceInfo instanceInfo = builder.setAppName(appName).build();
String clusterName = discovery.getClusterName(instanceInfo);
assertEquals("clusterName is wrong", appName.toUpperCase(), clusterName);
}

Loading…
Cancel
Save