turbine是怎么收集指标数据的

我们通过spring cloud图形化dashboard是如何实现指标的收集展示的知道了,图形化的指标是从turbine获取到指标数据的。那么turbine的数据是从哪里来的呢?

1、数据来源

我们通过url:http://localhost:10000/turbine.stream?cluster=default可以获取到指标的json数据。那么指标数据又是从何处获取到的。

答案是:从各个服务的/manage/hystrix.stream端点获取的

2、turbine架构设计

turbine官方的github地址:

https://github.com/Netflix/turbine/wiki

可以找到turbine的架构设计

详细信息参考

https://github.com/Netflix/Turbine/wiki/Design-And-Architecture-(1.x)

说明:turbine启动的时候,会去连接需要监控的主机,建立起监听,每一个实例会有一个监听。当实例监听从各个服务获取到数据的时候,会将数据填充到派发器dispatcher中,由派发器将数据输出到各个客户端。

3、源码阅读

turbine的实现在turbine核心包下

com.netflix.turbine:turbine-core

在该包下,可以找到几个关键的类

InstanceMonitorHandlerQueueTupleTurbineDataDispatcherTurbineStreamServlet

我们启动调试的时候,可以看到

实例的url其实是指向具体需要监控的实例的端点,即

http://sheng:8088/manage/hystrix.stream

查看这个链接我们可以看到

InstanceMonitor启动监听

public void startMonitor() throws Exception {
// This is the only state that we allow startMonitor to proceed in
if (monitorState.get() != State.NotStarted) {
return;
} taskFuture = ThreadPool.submit(new Callable<Void>() { @Override
public Void call() throws Exception { try {
//初始化,连接到具体实例上
init();
monitorState.set(State.Running);
while(monitorState.get() == State.Running) {
//关键代码
doWork();
}
} catch(Throwable t) {
logger.warn("Stopping InstanceMonitor for: " + getStatsInstance().getHostname() + " " + getStatsInstance().getCluster(), t);
} finally {
if (monitorState.get() == State.Running) {
monitorState.set(State.StopRequested);
}
cleanup();
monitorState.set(State.CleanedUp);
}
return null;
}
});
}

    private void init() throws Exception {

        HttpGet httpget = new HttpGet(url);

        HttpResponse response = gatewayHttpClient.getHttpClient().execute(httpget);

        HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
//初始化一个输入流
reader = new BufferedReader(new InputStreamReader(is)); int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != 200) {
// this is unexpected. We probably have the wrong endpoint. Print the response out for debugging and give up here.
List<String> responseMessage = IOUtils.readLines(reader);
logger.error("Could not initiate connection to host, giving up: " + responseMessage);
throw new MisconfiguredHostException(responseMessage.toString());
}
}

dowork()方法做了什么呢

    private void doWork() throws Exception {

        DataFromSingleInstance instanceData = null;

        //获取实例数据
instanceData = getNextStatsData();
if(instanceData == null) {
return;
} else {
lastEventUpdateTime.set(System.currentTimeMillis());
} List<DataFromSingleInstance> list = new ArrayList<DataFromSingleInstance>();
list.add(instanceData); /* send to all handlers */
//将获取到的数据添加到dispatcher中
boolean continueRunning = dispatcher.pushData(getStatsInstance(), list);
if(!continueRunning) {
logger.info("No more listeners to the host monitor, stopping monitor for: " + host.getHostname() + " " + host.getCluster());
monitorState.set(State.StopRequested);
return;
}
}

getNextStatsData读取数据


那么派发器是什么呢,它的实现查看TurbineDataDispatcher

查看它的pushData方法

发现调用的是tuple.pushData(statsData);tuple其实就像一个管道,查看HandlerQueueTuplepushData方法

    public void pushData(K data) {
if (stopped) {
return;
}
boolean success = queue.writeEvent(data);
if (isCritical()) {
// track stats
if (success) {
counter.increment(Type.EVENT_PROCESSED);
} else {
counter.increment(Type.EVENT_DISCARDED);
}
}
}

看到queue.writeEvent(data)、往队列里写数据

这个队列又是什么呢?

其实就是一个事件队列EventQueue,查看它的写事件方法

  public boolean writeEvent(T event) {
if (count.get() > maxCapacity) { // approx check for capacity
return false;
}
count.incrementAndGet();
queue.add(event);
return true;
}

如果队列中的长度大于maxCapacity,将不会再往队列里填充数据。


当客户端连接上的时候,queue就会被消费。如果客户端没有连接上的时候,queue读出来,经过一系列的操作会写回queue中,直到队列满了就不在写了。

1、当没有客户端连接上的时候

eventHandler经过一些列的处理,数据会被写回到queue中

2、当有客户端连上的时候,假设我们通过浏览器地址栏输入了

http://localhost:10000/turbine.stream?cluster=default

此时

我们看到eventHandler为TurbineStreamingConnection,见下图

handlData()就变成了TurbineStreamingConnection中的方法

    public void handleData(Collection<T> data) {

        if (stopMonitoring) {
// we have been stopped so don't try handling data
return;
}
//将数据写到steamHandler中
writeToStream(data);
}

writeToStream()中有个关键的操作streamHandler.writeData(jsonStringForDataHash)

writeData()方法就可以将数据写到response中

客户端访问http://localhost:10000/turbine.stream?cluster=default的时候,其实就是通过TurbineStreamServlet获取到响应结果的。

turbine是怎么收集指标数据的的更多相关文章

  1. Spring Cloud 入门教程(八): 断路器指标数据监控Hystrix Dashboard 和 Turbine

    1. Hystrix Dashboard (断路器:hystrix 仪表盘)  Hystrix一个很重要的功能是,可以通过HystrixCommand收集相关数据指标. Hystrix Dashboa ...

  2. 运维相关指标数据采集并ES入仓 - 运维笔记

    为了进行数字化IT治理,需要对一些应用进程相关指标进行采集并入库.收集到的应用指标数据最好要进行ES入仓,入到Kafka里面,并通过Kibana可视化展示. 需要进行采集的应用进程相关指标如下: ES ...

  3. 使用 shell 脚本自动获取发版指标数据

    问题背景 大一点的公司都会建立一套规章流程来避免低级错误,例如合入代码前必需经过同行评审:上线前必需提测且通过 QA 验证:全量前必需经过 1%.5%.10%.20%.50% 的灰度过程.尤其是最后一 ...

  4. .NetCore下使用Prometheus实现系统监控和警报 (六)进阶Grafana集成自定义收集指标

    Prometheus中包含了很多收集指标,那么我们怎来在Grafana中来使用呢? 接下来我们还是以之前自定义的来演示如图:我们在Prometheus中已经可以看到这个之前我们自定义的类型了 关于Gr ...

  5. .NetCore下使用Prometheus实现系统监控和警报 (五)进阶自定义收集指标 之 Counter

    Prometheus下面定了四种类型的收集方式,下面我们主要来来说下Counter的使用 Nuget导入Prometheus.AspNetCore包 下面先来看下我的Prometheus配置,这里我没 ...

  6. nGrinder对监控机器收集自定义数据及源码分析

    转载:https://blog.csdn.net/neven7/article/details/50782451 0.背景 性能测试工具nGrinder支持在无需修改源码的情况下,对目标服务器收集自定 ...

  7. Facebook 被指收集用户数据:通过照片和文本

    北京时间5月25日消息,在加利福尼亚州进行的对Facebook泄露用户信息一案中,法院对Facebook提起一项新的诉讼,指控该公司通过App收集了用户及他们朋友的信息. 上周向加利福尼亚州圣马特奥市 ...

  8. tushare获取股票每日重要的基本面指标数据,并存入Elasticsearch

    tushare是一个开放的,免费的金融数据平台,包含沪深股票数据,指数数据,基金数据,期货数据,期权数据,债券数据,外汇数据,港股数据,行业经济数据,宏观经济数据以及新闻快讯等特色数据.其中以沪深股票 ...

  9. .Net最佳实践3:使用性能计数器收集性能数据

    本文值得阅读吗? 本文讨论我们如何使用性能计数器从应用程序收集数据.我们将先了解的基本知识,然后我们将看到一个简单的示例,我们将从中收集一些性能数据. 介绍: - 我的应用程序的性能是最好的,像火箭 ...

随机推荐

  1. mysql 触发器 trigger用法 three (稍微复杂的)

    MySQL包含对触发器的支持.触发器是一种与表操作有关的数据库对象,当触发器所在表上出现指定事件时,将调用该对象,即表的操作事件触发表上的触发器的执行. 创建触发器 在MySQL中,创建触发器语法如下 ...

  2. Python3 打开 https 链接,异常:“SSL: CERTIFICATE_VERIFY_FAILED”

    Python3 打开 https 链接,异常:“SSL: CERTIFICATE_VERIFY_FAILED” 一.问题 Python2.7.9 之后,当使用urllib.urlopen打开一个 ht ...

  3. Django国际化和本地化

    把django的这篇文档看了一遍,基本弄懂了,讲的也挺详细的 https://docs.djangoproject.com/en/1.6/topics/i18n/ 首先是国际化和本地化概念: 1,国际 ...

  4. 《课程设计》——cupp的使用

    <课程设计>--cupp的使用 cupp简介 cupp是强大的字典生成脚本.它是一款用Python语言写成的可交互性的字典生成脚本.尤其适合社会工程学,当你收集到目标的具体信息后,你就可以 ...

  5. 20162311 Hash 补分博客

    20162311 Hash 补分博客 一.任务详情 二.解题过程 除留余数法和拉链法都懂了,也都会做,主要是开放寻址法.课下查了一些资料,也问了老师才彻底理解 引用例子 引用网上的一个例子来理解 参考 ...

  6. linux下安装微信小程序开发工具

    一.环境:: ubuntu 16.04 二.安装过程: 2.1 安装wine sudo apt-get install wine 2.2 安装nwjs-sdk 2.2.1 下载linux版nwjs-s ...

  7. cmder的使用和编码问题解决

    cmder 是一款 windows 下的命令集合软件,它可以集合各种系统下的命令,并且操作非常快速方便.安装有两个版本,一个是简化版(4.27M),一个是完全版(75.7M),它们的唯一区别:完全版包 ...

  8. 桌面共享UDP组播实现

    组播(Multicast)传输:在发送者和每一接收者之间实现点对多点网络连接.如果一台发送者同时给多个的接收者传输相同的数据,也只需复制一份的相同数据包.它提高了数据传送效率.减少了骨干网络出现拥塞的 ...

  9. OpenVirteX 创建简易虚拟网络

    OpenVirteX 创建简易虚拟网络 1.打开OVX sh OpenVirteX/script/ovx.sh 2.创建mininet物理拓扑 1sw, 2hosts mn --controller= ...

  10. 【NOI2013】向量内积

    定义两个$d$维向量${A=[a_1,a_2....a_n]}$,${B=[b_1,b_2....b_n]}$的内积为其相对应维度的权值的乘积和: $${\left \langle A,B \righ ...