Spring Cloud实战小贴士:turbine如何聚合设置了context-path的hystrix数据

之前在spring for all社区看到这样一个问题:当actuator端点设置了context-path之后,turbine如何聚合数据?首先,我们要知道actuator端点设置了context-path是什么意思?也就是说,此时spring boot actuator的端点都有了一个前缀,比如:

management.context-path=/xxx

如果设置了上面的参数,那个对于收集hystrix数据的端点将变为:/xxx/hystrix.stream,如果我们还是拿上一篇Spring Cloud构建微服务架构:Hystrix监控数据聚合【Dalston版】中构建你的turbine应用,那么将会看到如下错误:

INFO 7812 --- [        Timer-0] c.n.t.monitor.instance.InstanceMonitor   : Url for host: http://172.15.0.18:9020/hystrix.stream default

ERROR 7812 --- [InstanceMonitor] c.n.t.monitor.instance.InstanceMonitor   : Could not initiate connection to host, giving up: [{"timestamp":1499941336284,"status":404,"error":"Not Found","message":"No message available","path":"/hystrix.stream"}]

WARN 7812 --- [InstanceMonitor] c.n.t.monitor.instance.InstanceMonitor   : Stopping InstanceMonitor for: 172.15.0.18:9020 default

com.netflix.turbine.monitor.instance.InstanceMonitor$MisconfiguredHostException: [{"timestamp":1499941336284,"status":404,"error":"Not Found","message":"No message available","path":"/hystrix.stream"}]

	at com.netflix.turbine.monitor.instance.InstanceMonitor.init(InstanceMonitor.java:318) ~[turbine-core-1.0.0.jar:na]

	at com.netflix.turbine.monitor.instance.InstanceMonitor.access$100(InstanceMonitor.java:103) ~[turbine-core-1.0.0.jar:na]

	at com.netflix.turbine.monitor.instance.InstanceMonitor$2.call(InstanceMonitor.java:235) [turbine-core-1.0.0.jar:na]

	at com.netflix.turbine.monitor.instance.InstanceMonitor$2.call(InstanceMonitor.java:229) [turbine-core-1.0.0.jar:na]

	at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_91]

	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_91]

	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_91]

	at java.lang.Thread.run(Thread.java:745) [na:1.8.0_91]

从上述错误中我们可以知道,turbine在收集的时候由于访问的是/hystrix.stream,而此时收集端点却是/xxx/hystrix.stream,所以报了404错误。

那么我们要如何解决呢?通过之前的配置内容,我们可能找不到相关的配置信息,所以只能遍历一下源码,最后找到这个类:org.springframework.cloud.netflix.turbine.SpringClusterMonitor。它的具体内容如下:

public static InstanceUrlClosure ClusterConfigBasedUrlClosure = new InstanceUrlClosure() {

private final DynamicStringProperty defaultUrlClosureConfig = DynamicPropertyFactory

			.getInstance().getStringProperty("turbine.instanceUrlSuffix",

				    	"hystrix.stream");

private final DynamicBooleanProperty instanceInsertPort = DynamicPropertyFactory

				.getInstance().getBooleanProperty("turbine.instanceInsertPort", true);

@Override

public String getUrlPath(Instance host) {

if (host.getCluster() == null) {

throw new RuntimeException(

"Host must have cluster name in order to use ClusterConfigBasedUrlClosure");

		}

// find url

		String key = "turbine.instanceUrlSuffix." + host.getCluster();

		DynamicStringProperty urlClosureConfig = DynamicPropertyFactory.getInstance()

					.getStringProperty(key, null);

		String url = urlClosureConfig.get();

if (url == null) {

			url = this.defaultUrlClosureConfig.get();

		}

if (url == null) {

throw new RuntimeException("Config property: "

					+ urlClosureConfig.getName() + " or "

					+ this.defaultUrlClosureConfig.getName() + " must be set");

		}

// find port and scheme

		String port;

		String scheme;

if (host.getAttributes().containsKey("securePort")) {

			port = host.getAttributes().get("securePort");

			scheme = "https";

		} else {

			port = host.getAttributes().get("port");

			scheme = "http";

		}

if (host.getAttributes().containsKey("fusedHostPort")) {

return String.format("%s://%s/%s", scheme, host.getAttributes().get("fusedHostPort"), url);

		}

// determine if to insert port

		String insertPortKey = "turbine.instanceInsertPort." + host.getCluster();

		DynamicStringProperty insertPortProp = DynamicPropertyFactory.getInstance()

					.getStringProperty(insertPortKey, null);

boolean insertPort;

if (insertPortProp.get() == null) {

			insertPort = this.instanceInsertPort.get();

		}

else {

			insertPort = Boolean.parseBoolean(insertPortProp.get());

		}

// format url with port

if (insertPort) {

if (url.startsWith("/")) {

				url = url.substring(1);

			}

if (port == null) {

throw new RuntimeException(

"Configured to use port, but port or securePort is not in host attributes");

			}

return String.format("%s://%s:%s/%s", scheme, host.getHostname(), port, url);

		}

//format url without port

return scheme + "://" + host.getHostname() + url;

	}

};

从上述源码中,我们可以找到这个参数turbine.instanceUrlSuffix,由此该问题就迎刃而解了,我们只需要在turbine应用的配置文件中增加如下配置信息,就能正确的收集之前配置了management.context-path=/xxx的微服务的hystrix数据了。

turbine.instanceUrlSuffix=/xxx/hystrix.stream

原文发布于微信公众号 - 程序猿DD(didispace)

原文发表时间:2017-07-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏猿天地

注解面试题-请了解下

金三银四,三四月是找工作最好的时期。错过了三月千万别放弃四月。 在面试的时候,有些面试官会问注解相关的问题, 注解最典型的代表框架就是Spring了,特别是Sp...

3599
来自专栏cloudskyme

jbpm5.1介绍(6)

Junit测试的mini流程helloworld 这是一个在demo中使用的Script Task做的简单示例,在执行到这个任务结点的时候自动输出"hello...

3667
来自专栏Java 技术分享

SpringMVC(一)

1232
来自专栏Java成神之路

SpringMVC学习笔记

(1)通过 contextConfigLocation 来配置 SpringMVC 的配置文件

1074
来自专栏JAVA技术站

SpringBoot中Configure注解和Bean注解的使用

  Configure不加参数,仅声明为配置类,加了参数代表该类为实例,实例名称为参数名

7423
来自专栏爱撒谎的男孩

Springmvc之向JSP页面提供数据(request,session)

3574
来自专栏高性能服务器开发

linux服务器开发实战(一)——排查Flamingo服务端一个崩溃的问题

我的flamingo服务器(关于flamingo可以参看这里)最近在杀掉进程(如使用Ctrl + C或者kill + 程序pid)偶尔会出现崩溃问题,虽然这个问...

3471
来自专栏Albert陈凯

2018-04-27 读配置文件到静态变量中,加载properties到static变量field

项目的配置文件要写到jar档外面,提供给运维人员更改,基于这个需求,就会有很多的常量需要从外部文件读取进来 JAVA最常见的就是properties文件,提供k...

3649
来自专栏Spring相关

第3章—高级装配—条件化的Bean

通过活动的profile,我们可以获得不同的Bean。Spring 4提供了一个更通用的基于条件的Bean的创建方式,即使用@Conditional注解。

952
来自专栏Java 技术分享

SpringMVC(一)

1983

扫码关注云+社区

领取腾讯云代金券