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. ES6学习--对象属性的可枚举性( enumerable)

    可枚举性(enumerable)用来控制所描述的属性,是否将被包括在for...in循环之中.具体来说,如果一个属性的enumerable为false,下面三个操作不会取到该属性.* for..in循 ...

  2. Python3: Windows系统上同时安装Python2和Python3

    Python3: Windows系统上同时安装Python2和Python3 为什么要同时安装Python2和Python3环境呢? 因为一些库只支持Python2或者Python3; 在同一台电脑上 ...

  3. Win10 Ubuntu 双系统 卸载 Ubuntu

    Win10 Ubuntu 双系统 卸载 Ubuntu 其实卸载 Ubuntu 系统很简单,进 win10 系统之后,磁盘管理,格式化 Ubuntu 的磁盘就可以了. 但是最费劲的是什么呢? 就是格式化 ...

  4. 20145331魏澍琛《网络对抗》Exp4 恶意代码分析

    20145331魏澍琛<网络对抗>Exp4 恶意代码分析 基础问题回答 1.如果在工作中怀疑一台主机上有恶意代码,但只是猜想,所有想监控下系统一天天的到底在干些什么.请设计下你想监控的操作 ...

  5. Java JDK8 学习笔记 1-3章

    第一章 Java平台概论 1.了解Java的前世今生,Java SE.Java EE.JavaME三大平台.其中Java SE主要由四部分JVM.JRE.JDK与Java语言,JDK包含JRE,JRE ...

  6. C# 计算传入的时间距离今天的时间差

    /// <summary> /// 计算传入的时间距离今天的时间差 /// </summary> /// <param name="dt">&l ...

  7. (转)MyBatis & MyBatis Plus

    (二期)3.mybatis与mybatis plus [课程三]mybatis ...运用.xmind0.1MB [课程三]mybatis...机制.xmind0.2MB [课程三]mybatis与j ...

  8. 如何将一个Winform嵌入到一个Control当中

    /// <summary> /// 将一个winform窗体嵌入control中 /// </summary> /// <param name="f" ...

  9. 3D CNN for Video Processing

    3D CNN for Video Processing Updated on 2018-08-06 19:53:57 本文主要是总结下当前流行的处理 Video 信息的深度神经网络的处理方法. 参考文 ...

  10. v-pre原样输出&&v-once只加载一次

    html <div id="app"> <div v-pre>{{message1}}</div><!--原样输出--> <b ...