Commit ba248113 by Nastya Smirnova Committed by Ryan Baxter

Report jmx and management ports to Eureka metadata map (#1830)

parent 573d5211
...@@ -669,8 +669,9 @@ in order for the Hystrix Dashboard to make a successful connection to the stream ...@@ -669,8 +669,9 @@ in order for the Hystrix Dashboard to make a successful connection to the stream
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-netflix-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`. 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-netflix-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. NOTE: By default, Turbine looks for the `/hystrix.stream` endpoint on a registered instance by looking up its `hostName` and `port` entries in Eureka, then appending `/hystrix.stream` to it.
To make turbine find the Hystrix stream at the correct port, you need to add `management.port` to the instances' metadata: If the instance's metadata contains `management.port`, it will be used instead of the `port` value for the `/hystrix.stream` endpoint.
By default, metadata entry `management.port` is equal to the `management.port` configuration property, it can be overridden though with following configuration:
---- ----
eureka: eureka:
instance: instance:
......
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*
*/ */
package org.springframework.cloud.netflix.eureka; package org.springframework.cloud.netflix.eureka;
...@@ -26,6 +25,7 @@ import java.lang.annotation.RetentionPolicy; ...@@ -26,6 +25,7 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.endpoint.Endpoint; import org.springframework.boot.actuate.endpoint.Endpoint;
...@@ -131,6 +131,7 @@ public class EurekaClientAutoConfiguration { ...@@ -131,6 +131,7 @@ public class EurekaClientAutoConfiguration {
int managementPort = Integer.valueOf(propertyResolver.getProperty("management.port", String.valueOf(nonSecurePort))); int managementPort = Integer.valueOf(propertyResolver.getProperty("management.port", String.valueOf(nonSecurePort)));
String managementContextPath = propertyResolver.getProperty("management.contextPath", propertyResolver.getProperty("server.contextPath", "/")); String managementContextPath = propertyResolver.getProperty("management.contextPath", propertyResolver.getProperty("server.contextPath", "/"));
Integer jmxPort = propertyResolver.getProperty("com.sun.management.jmxremote.port", Integer.class);//nullable
EurekaInstanceConfigBean instance = new EurekaInstanceConfigBean(inetUtils); EurekaInstanceConfigBean instance = new EurekaInstanceConfigBean(inetUtils);
instance.setNonSecurePort(nonSecurePort); instance.setNonSecurePort(nonSecurePort);
instance.setInstanceId(getDefaultInstanceId(propertyResolver)); instance.setInstanceId(getDefaultInstanceId(propertyResolver));
...@@ -162,9 +163,21 @@ public class EurekaClientAutoConfiguration { ...@@ -162,9 +163,21 @@ public class EurekaClientAutoConfiguration {
instance.setStatusPageUrl(new URL(base, StringUtils.trimLeadingCharacter(instance.getStatusPageUrlPath(), '/')).toString()); instance.setStatusPageUrl(new URL(base, StringUtils.trimLeadingCharacter(instance.getStatusPageUrlPath(), '/')).toString());
instance.setHealthCheckUrl(new URL(base, StringUtils.trimLeadingCharacter(instance.getHealthCheckUrlPath(), '/')).toString()); instance.setHealthCheckUrl(new URL(base, StringUtils.trimLeadingCharacter(instance.getHealthCheckUrlPath(), '/')).toString());
} }
setupMetadataMap(instance, managementPort, jmxPort);
return instance; return instance;
} }
private void setupMetadataMap(EurekaInstanceConfigBean instance, int managementPort,
Integer jmxPort) {
Map<String, String> metadataMap = instance.getMetadataMap();
if (metadataMap.get("management.port") == null && managementPort != 0) {
metadataMap.put("management.port", String.valueOf(managementPort));
}
if (metadataMap.get("jmx.port") == null && jmxPort != null) {
metadataMap.put("jmx.port", String.valueOf(jmxPort));
}
}
@Bean @Bean
public DiscoveryClient discoveryClient(EurekaInstanceConfig config, EurekaClient client) { public DiscoveryClient discoveryClient(EurekaInstanceConfig config, EurekaClient client) {
return new EurekaDiscoveryClient(config, client); return new EurekaDiscoveryClient(config, client);
......
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*
*/ */
package org.springframework.cloud.netflix.eureka; package org.springframework.cloud.netflix.eureka;
...@@ -27,7 +26,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean ...@@ -27,7 +26,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.condition.SearchStrategy; import org.springframework.boot.autoconfigure.condition.SearchStrategy;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.util.EnvironmentTestUtils;
import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration;
import org.springframework.cloud.commons.util.UtilAutoConfiguration; import org.springframework.cloud.commons.util.UtilAutoConfiguration;
import org.springframework.cloud.context.scope.GenericScope; import org.springframework.cloud.context.scope.GenericScope;
...@@ -75,6 +73,54 @@ public class EurekaClientAutoConfigurationTests { ...@@ -75,6 +73,54 @@ public class EurekaClientAutoConfigurationTests {
} }
@Test @Test
public void shouldSetManagementPortInMetadataMapIfEqualToServerPort() throws Exception {
addEnvironment(this.context, "server.port=8989");
setupContext(RefreshAutoConfiguration.class);
EurekaInstanceConfigBean instance = this.context
.getBean(EurekaInstanceConfigBean.class);
assertEquals("8989", instance.getMetadataMap().get("management.port"));
}
@Test
public void shouldNotSetManagementAndJmxPortsInMetadataMap() throws Exception {
addEnvironment(this.context, "server.port=8989", "management.port=0");
setupContext(RefreshAutoConfiguration.class);
EurekaInstanceConfigBean instance = this.context
.getBean(EurekaInstanceConfigBean.class);
assertEquals(null, instance.getMetadataMap().get("management.port"));
assertEquals(null, instance.getMetadataMap().get("jmx.port"));
}
@Test
public void shouldSetManagementAndJmxPortsInMetadataMap() throws Exception {
addEnvironment(this.context, "management.port=9999",
"com.sun.management.jmxremote.port=6789");
setupContext(RefreshAutoConfiguration.class);
EurekaInstanceConfigBean instance = this.context
.getBean(EurekaInstanceConfigBean.class);
assertEquals("9999", instance.getMetadataMap().get("management.port"));
assertEquals("6789", instance.getMetadataMap().get("jmx.port"));
}
@Test
public void shouldNotResetManagementAndJmxPortsInMetadataMap() throws Exception {
addEnvironment(this.context, "management.port=9999",
"eureka.instance.metadata-map.jmx.port=9898",
"eureka.instance.metadata-map.management.port=7878");
setupContext(RefreshAutoConfiguration.class);
EurekaInstanceConfigBean instance = this.context
.getBean(EurekaInstanceConfigBean.class);
assertEquals("7878", instance.getMetadataMap().get("management.port"));
assertEquals("9898", instance.getMetadataMap().get("jmx.port"));
}
@Test
public void nonSecurePortPeriods() { public void nonSecurePortPeriods() {
testNonSecurePort("server.port"); testNonSecurePort("server.port");
} }
...@@ -110,7 +156,7 @@ public class EurekaClientAutoConfigurationTests { ...@@ -110,7 +156,7 @@ public class EurekaClientAutoConfigurationTests {
@Test @Test
public void managementPort() { public void managementPort() {
EnvironmentTestUtils.addEnvironment(this.context, "server.port=8989", addEnvironment(this.context, "server.port=8989",
"management.port=9999"); "management.port=9999");
setupContext(RefreshAutoConfiguration.class); setupContext(RefreshAutoConfiguration.class);
EurekaInstanceConfigBean instance = this.context EurekaInstanceConfigBean instance = this.context
...@@ -121,7 +167,7 @@ public class EurekaClientAutoConfigurationTests { ...@@ -121,7 +167,7 @@ public class EurekaClientAutoConfigurationTests {
@Test @Test
public void statusPageUrlPathAndManagementPort() { public void statusPageUrlPathAndManagementPort() {
EnvironmentTestUtils.addEnvironment(this.context, "server.port=8989", addEnvironment(this.context, "server.port=8989",
"management.port=9999", "management.port=9999",
"eureka.instance.statusPageUrlPath=/myStatusPage"); "eureka.instance.statusPageUrlPath=/myStatusPage");
setupContext(RefreshAutoConfiguration.class); setupContext(RefreshAutoConfiguration.class);
...@@ -133,7 +179,7 @@ public class EurekaClientAutoConfigurationTests { ...@@ -133,7 +179,7 @@ public class EurekaClientAutoConfigurationTests {
@Test @Test
public void healthCheckUrlPathAndManagementPort() { public void healthCheckUrlPathAndManagementPort() {
EnvironmentTestUtils.addEnvironment(this.context, "server.port=8989", addEnvironment(this.context, "server.port=8989",
"management.port=9999", "management.port=9999",
"eureka.instance.healthCheckUrlPath=/myHealthCheck"); "eureka.instance.healthCheckUrlPath=/myHealthCheck");
setupContext(RefreshAutoConfiguration.class); setupContext(RefreshAutoConfiguration.class);
...@@ -145,7 +191,7 @@ public class EurekaClientAutoConfigurationTests { ...@@ -145,7 +191,7 @@ public class EurekaClientAutoConfigurationTests {
@Test @Test
public void statusPageUrlPathAndManagementPortAndContextPath() { public void statusPageUrlPathAndManagementPortAndContextPath() {
EnvironmentTestUtils.addEnvironment(this.context, "server.port=8989", addEnvironment(this.context, "server.port=8989",
"management.port=9999", "management.contextPath=/manage", "management.port=9999", "management.contextPath=/manage",
"eureka.instance.statusPageUrlPath=/myStatusPage"); "eureka.instance.statusPageUrlPath=/myStatusPage");
setupContext(RefreshAutoConfiguration.class); setupContext(RefreshAutoConfiguration.class);
...@@ -157,7 +203,7 @@ public class EurekaClientAutoConfigurationTests { ...@@ -157,7 +203,7 @@ public class EurekaClientAutoConfigurationTests {
@Test @Test
public void healthCheckUrlPathAndManagementPortAndContextPath() { public void healthCheckUrlPathAndManagementPortAndContextPath() {
EnvironmentTestUtils.addEnvironment(this.context, "server.port=8989", addEnvironment(this.context, "server.port=8989",
"management.port=9999", "management.contextPath=/manage", "management.port=9999", "management.contextPath=/manage",
"eureka.instance.healthCheckUrlPath=/myHealthCheck"); "eureka.instance.healthCheckUrlPath=/myHealthCheck");
setupContext(RefreshAutoConfiguration.class); setupContext(RefreshAutoConfiguration.class);
...@@ -169,7 +215,7 @@ public class EurekaClientAutoConfigurationTests { ...@@ -169,7 +215,7 @@ public class EurekaClientAutoConfigurationTests {
@Test @Test
public void statusPageUrlPathAndManagementPortAndContextPathKebobCase() { public void statusPageUrlPathAndManagementPortAndContextPathKebobCase() {
EnvironmentTestUtils.addEnvironment(this.context, "server.port=8989", addEnvironment(this.context, "server.port=8989",
"management.port=9999", "management.context-path=/manage", "management.port=9999", "management.context-path=/manage",
"eureka.instance.statusPageUrlPath=/myStatusPage"); "eureka.instance.statusPageUrlPath=/myStatusPage");
setupContext(RefreshAutoConfiguration.class); setupContext(RefreshAutoConfiguration.class);
...@@ -181,7 +227,7 @@ public class EurekaClientAutoConfigurationTests { ...@@ -181,7 +227,7 @@ public class EurekaClientAutoConfigurationTests {
@Test @Test
public void healthCheckUrlPathAndManagementPortAndContextPathKebobCase() { public void healthCheckUrlPathAndManagementPortAndContextPathKebobCase() {
EnvironmentTestUtils.addEnvironment(this.context, "server.port=8989", addEnvironment(this.context, "server.port=8989",
"management.port=9999", "management.context-path=/manage", "management.port=9999", "management.context-path=/manage",
"eureka.instance.healthCheckUrlPath=/myHealthCheck"); "eureka.instance.healthCheckUrlPath=/myHealthCheck");
setupContext(RefreshAutoConfiguration.class); setupContext(RefreshAutoConfiguration.class);
...@@ -193,7 +239,7 @@ public class EurekaClientAutoConfigurationTests { ...@@ -193,7 +239,7 @@ public class EurekaClientAutoConfigurationTests {
@Test @Test
public void statusPageUrlPathAndManagementPortKabobCase() { public void statusPageUrlPathAndManagementPortKabobCase() {
EnvironmentTestUtils.addEnvironment(this.context, "server.port=8989", addEnvironment(this.context, "server.port=8989",
"management.port=9999", "management.port=9999",
"eureka.instance.status-page-url-path=/myStatusPage"); "eureka.instance.status-page-url-path=/myStatusPage");
setupContext(RefreshAutoConfiguration.class); setupContext(RefreshAutoConfiguration.class);
...@@ -205,7 +251,7 @@ public class EurekaClientAutoConfigurationTests { ...@@ -205,7 +251,7 @@ public class EurekaClientAutoConfigurationTests {
@Test @Test
public void statusPageUrlAndPreferIpAddress() { public void statusPageUrlAndPreferIpAddress() {
EnvironmentTestUtils.addEnvironment(this.context, "server.port=8989", addEnvironment(this.context, "server.port=8989",
"management.port=9999", "eureka.instance.hostname=foo", "management.port=9999", "eureka.instance.hostname=foo",
"eureka.instance.preferIpAddress:true"); "eureka.instance.preferIpAddress:true");
...@@ -219,7 +265,7 @@ public class EurekaClientAutoConfigurationTests { ...@@ -219,7 +265,7 @@ public class EurekaClientAutoConfigurationTests {
@Test @Test
public void healthCheckUrlPathAndManagementPortKabobCase() { public void healthCheckUrlPathAndManagementPortKabobCase() {
EnvironmentTestUtils.addEnvironment(this.context, "server.port=8989", addEnvironment(this.context, "server.port=8989",
"management.port=9999", "management.port=9999",
"eureka.instance.health-check-url-path=/myHealthCheck"); "eureka.instance.health-check-url-path=/myHealthCheck");
setupContext(RefreshAutoConfiguration.class); setupContext(RefreshAutoConfiguration.class);
...@@ -231,7 +277,7 @@ public class EurekaClientAutoConfigurationTests { ...@@ -231,7 +277,7 @@ public class EurekaClientAutoConfigurationTests {
@Test @Test
public void statusPageUrlPathAndManagementPortUpperCase() { public void statusPageUrlPathAndManagementPortUpperCase() {
EnvironmentTestUtils.addEnvironment(this.context, "server.port=8989", addEnvironment(this.context, "server.port=8989",
"management.port=9999", "management.port=9999",
"EUREKA_INSTANCE_STATUS_PAGE_URL_PATH=/myStatusPage"); "EUREKA_INSTANCE_STATUS_PAGE_URL_PATH=/myStatusPage");
setupContext(RefreshAutoConfiguration.class); setupContext(RefreshAutoConfiguration.class);
...@@ -243,7 +289,7 @@ public class EurekaClientAutoConfigurationTests { ...@@ -243,7 +289,7 @@ public class EurekaClientAutoConfigurationTests {
@Test @Test
public void healthCheckUrlPathAndManagementPortUpperCase() { public void healthCheckUrlPathAndManagementPortUpperCase() {
EnvironmentTestUtils.addEnvironment(this.context, "server.port=8989", addEnvironment(this.context, "server.port=8989",
"management.port=9999", "management.port=9999",
"EUREKA_INSTANCE_HEALTH_CHECK_URL_PATH=/myHealthCheck"); "EUREKA_INSTANCE_HEALTH_CHECK_URL_PATH=/myHealthCheck");
setupContext(RefreshAutoConfiguration.class); setupContext(RefreshAutoConfiguration.class);
...@@ -255,7 +301,7 @@ public class EurekaClientAutoConfigurationTests { ...@@ -255,7 +301,7 @@ public class EurekaClientAutoConfigurationTests {
@Test @Test
public void hostname() { public void hostname() {
EnvironmentTestUtils.addEnvironment(this.context, "server.port=8989", addEnvironment(this.context, "server.port=8989",
"management.port=9999", "eureka.instance.hostname=foo"); "management.port=9999", "eureka.instance.hostname=foo");
setupContext(RefreshAutoConfiguration.class); setupContext(RefreshAutoConfiguration.class);
EurekaInstanceConfigBean instance = this.context EurekaInstanceConfigBean instance = this.context
...@@ -275,7 +321,7 @@ public class EurekaClientAutoConfigurationTests { ...@@ -275,7 +321,7 @@ public class EurekaClientAutoConfigurationTests {
@Test @Test
public void basicAuth() { public void basicAuth() {
EnvironmentTestUtils.addEnvironment(this.context, "server.port=8989", addEnvironment(this.context, "server.port=8989",
"eureka.client.serviceUrl.defaultZone=http://user:foo@example.com:80/eureka"); "eureka.client.serviceUrl.defaultZone=http://user:foo@example.com:80/eureka");
setupContext(MockClientConfiguration.class); setupContext(MockClientConfiguration.class);
// ApacheHttpClient4 http = this.context.getBean(ApacheHttpClient4.class); // ApacheHttpClient4 http = this.context.getBean(ApacheHttpClient4.class);
...@@ -292,7 +338,7 @@ public class EurekaClientAutoConfigurationTests { ...@@ -292,7 +338,7 @@ public class EurekaClientAutoConfigurationTests {
@Test @Test
public void testAppName() throws Exception { public void testAppName() throws Exception {
EnvironmentTestUtils.addEnvironment(this.context, "spring.application.name=mytest"); addEnvironment(this.context, "spring.application.name=mytest");
setupContext(); setupContext();
assertEquals("mytest", getInstanceConfig().getAppname()); assertEquals("mytest", getInstanceConfig().getAppname());
assertEquals("mytest", getInstanceConfig().getVirtualHostName()); assertEquals("mytest", getInstanceConfig().getVirtualHostName());
...@@ -301,7 +347,7 @@ public class EurekaClientAutoConfigurationTests { ...@@ -301,7 +347,7 @@ public class EurekaClientAutoConfigurationTests {
@Test @Test
public void testAppNameUpper() throws Exception { public void testAppNameUpper() throws Exception {
EnvironmentTestUtils.addEnvironment(this.context, "SPRING_APPLICATION_NAME=mytestupper"); addEnvironment(this.context, "SPRING_APPLICATION_NAME=mytestupper");
setupContext(); setupContext();
assertEquals("mytestupper", getInstanceConfig().getAppname()); assertEquals("mytestupper", getInstanceConfig().getAppname());
assertEquals("mytestupper", getInstanceConfig().getVirtualHostName()); assertEquals("mytestupper", getInstanceConfig().getVirtualHostName());
...@@ -310,7 +356,7 @@ public class EurekaClientAutoConfigurationTests { ...@@ -310,7 +356,7 @@ public class EurekaClientAutoConfigurationTests {
@Test @Test
public void testInstanceNamePreferred() throws Exception { public void testInstanceNamePreferred() throws Exception {
EnvironmentTestUtils.addEnvironment(this.context, "SPRING_APPLICATION_NAME=mytestspringappname", addEnvironment(this.context, "SPRING_APPLICATION_NAME=mytestspringappname",
"eureka.instance.appname=mytesteurekaappname"); "eureka.instance.appname=mytesteurekaappname");
setupContext(); setupContext();
assertEquals("mytesteurekaappname", getInstanceConfig().getAppname()); assertEquals("mytesteurekaappname", getInstanceConfig().getAppname());
...@@ -349,7 +395,7 @@ public class EurekaClientAutoConfigurationTests { ...@@ -349,7 +395,7 @@ public class EurekaClientAutoConfigurationTests {
} }
private void testSecurePort(String propName) { private void testSecurePort(String propName) {
EnvironmentTestUtils.addEnvironment(this.context, "eureka.instance.securePortEnabled=true"); addEnvironment(this.context, "eureka.instance.securePortEnabled=true");
addEnvironment(this.context, propName + ":8443"); addEnvironment(this.context, propName + ":8443");
setupContext(); setupContext();
assertEquals(8443, getInstanceConfig().getSecurePort()); assertEquals(8443, getInstanceConfig().getSecurePort());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment