1.turbine是什么?它的作用是什么?

Turbine is a tool for aggregating streams of Server-Sent Event (SSE) JSON data into a single stream. The targeted use case is metrics streams from instances in an SOA being aggregated for dashboards.

For example, Netflix uses Hystrix which has a realtime dashboard that uses Turbine to aggregate data from 100s or 1000s of machines.

2.eureka启动turbine类StartEurekaTurbine

public static void main(String[] args) {
OptionParser optionParser = new OptionParser();
optionParser.accepts("port").withRequiredArg();
optionParser.accepts("app").withRequiredArg();
optionParser.accepts("urlTemplate").withRequiredArg(); OptionSet options = optionParser.parse(args);
int port = -1;
if (!options.has("port")) {
System.err.println("Argument -port required for SSE HTTP server to start on. Eg. -port 8888");
System.exit(-1);
} else {
try {
port = Integer.parseInt(String.valueOf(options.valueOf("port")));
} catch (NumberFormatException e) {
System.err.println("Value of port must be an integer but was: " + options.valueOf("port"));
}
} String app = null;
if (!options.has("app")) {
System.err.println("Argument -app required for Eureka instance discovery. Eg. -app api");
System.exit(-1);
} else {
app = String.valueOf(options.valueOf("app"));
} String template = null;
if (!options.has("urlTemplate")) {
System.err.println("Argument -urlTemplate required. Eg. http://" + EurekaStreamDiscovery.HOSTNAME + "/metrics.stream");
System.exit(-1);
} else {
template = String.valueOf(options.valueOf("urlTemplate"));
if (!template.contains(EurekaStreamDiscovery.HOSTNAME)) {
System.err.println("Argument -urlTemplate must contain " + EurekaStreamDiscovery.HOSTNAME + " marker. Eg. http://" + EurekaStreamDiscovery.HOSTNAME + "/metrics.stream");
System.exit(-1);
}
} logger.info("Turbine => Eureka App: " + app);
logger.info("Turbine => Eureka URL Template: " + template); try {
Turbine.startServerSentEventServer(port, EurekaStreamDiscovery.create(app, template));
} catch (Throwable e) {
e.printStackTrace();
}
}

执行类如下;

startServerSentEventServer(port, aggregateHttpSSE(discovery));

首先,聚合http

  /**
* Aggregate multiple HTTP Server-Sent Event streams into one stream with the values summed.
* <p>
* The returned data must be JSON data that contains the following keys:
* <p>
* instanceId => Unique instance representing each stream to be merged, such as the instanceId of the server the stream is from.
* type => The type of data such as HystrixCommand or HystrixThreadPool if aggregating Hystrix metrics.
* name => Name of a group of metrics to be aggregated, such as a HystrixCommand name if aggregating Hystrix metrics.
*
* @param uri
* @return
*/
public static Observable<GroupedObservable<TypeAndNameKey, Map<String, Object>>> aggregateHttpSSE(StreamDiscovery discovery) {
Observable<StreamAction> streamActions = discovery.getInstanceList().publish().refCount();
Observable<StreamAction> streamAdds = streamActions.filter(a -> a.getType() == ActionType.ADD);
Observable<StreamAction> streamRemoves = streamActions.filter(a -> a.getType() == ActionType.REMOVE); Observable<GroupedObservable<InstanceKey, Map<String, Object>>> streamPerInstance =
streamAdds.map(streamAction -> {
URI uri = streamAction.getUri(); Observable<Map<String, Object>> io = Observable.defer(() -> {
Observable<Map<String, Object>> flatMap = RxNetty.createHttpClient(uri.getHost(), uri.getPort(), PipelineConfigurators.<ByteBuf>sseClientConfigurator())
.submit(createRequest(uri))
.flatMap(response -> {
if (response.getStatus().code() != 200) {
return Observable.error(new RuntimeException("Failed to connect: " + response.getStatus()));
}
return response.getContent()
.doOnSubscribe(() -> logger.info("Turbine => Aggregate Stream from URI: " + uri.toASCIIString()))
.doOnUnsubscribe(() -> logger.info("Turbine => Unsubscribing Stream: " + uri))
.takeUntil(streamRemoves.filter(a -> a.getUri().equals(streamAction.getUri()))) // unsubscribe when we receive a remove event
.map(sse -> JsonUtility.jsonToMap(sse.getEventData()));
});
// eclipse is having issues with type inference so breaking up
return flatMap.retryWhen(attempts -> {
return attempts.flatMap(e -> {
return Observable.timer(1, TimeUnit.SECONDS)
.doOnEach(n -> logger.info("Turbine => Retrying connection to: " + uri));
});
}); }); return GroupedObservable.from(InstanceKey.create(uri.toASCIIString()), io);
}); return StreamAggregator.aggregateGroupedStreams(streamPerInstance);
}

然后启动聚合

public static void startServerSentEventServer(int port, Observable<GroupedObservable<TypeAndNameKey, Map<String, Object>>> streams) {
logger.info("Turbine => Starting server on " + port); // multicast so multiple concurrent subscribers get the same stream
Observable<Map<String, Object>> publishedStreams = streams
.doOnUnsubscribe(() -> logger.info("Turbine => Unsubscribing aggregation."))
.doOnSubscribe(() -> logger.info("Turbine => Starting aggregation"))
.flatMap(o -> o).publish().refCount(); RxNetty.createHttpServer(port, (request, response) -> {
logger.info("Turbine => SSE Request Received");
response.getHeaders().setHeader("Content-Type", "text/event-stream");
return publishedStreams
.doOnUnsubscribe(() -> logger.info("Turbine => Unsubscribing RxNetty server connection"))
.flatMap(data -> {
return response.writeAndFlush(new ServerSentEvent(null, null, JsonUtility.mapToJson(data)));
});
}, PipelineConfigurators.<ByteBuf>sseServerConfigurator()).startAndWait();
}

3.单独启动turbine的过程和上面类似StartTurbine

 public static void main(String[] args) {
OptionParser optionParser = new OptionParser();
optionParser.accepts("port").withRequiredArg();
optionParser.accepts("streams").withRequiredArg(); OptionSet options = optionParser.parse(args);
int port = -1;
if (!options.has("port")) {
System.err.println("Argument -port required for SSE HTTP server to start on.");
System.exit(-1);
} else {
try {
port = Integer.parseInt(String.valueOf(options.valueOf("port")));
} catch (NumberFormatException e) {
System.err.println("Value of port must be an integer but was: " + options.valueOf("port"));
}
} URI[] streams = null;
if (!options.hasArgument("streams")) {
System.err.println("Argument -streams required with URIs to connect to. Eg. -streams \"http://host1/metrics.stream http://host2/metrics.stream\"");
System.exit(-1);
} else {
String streamsArg = String.valueOf(options.valueOf("streams"));
String[] ss = streamsArg.split(" ");
streams = new URI[ss.length];
for (int i = 0; i < ss.length; i++) {
try {
streams[i] = new URI(ss[i]);
} catch (URISyntaxException e) {
System.err.println("ERROR: Could not parse stream into URI: " + ss[i]);
System.exit(-1);
}
}
} if (streams == null || streams.length == 0) {
System.err.println("There must be at least 1 valid stream URI.");
System.exit(-1);
} try {
Turbine.startServerSentEventServer(port, Turbine.aggregateHttpSSE(streams));
} catch (Throwable e) {
e.printStackTrace();
}
}

netflix turbine概述的更多相关文章

  1. netflix ribbon概述

    LB方案分类 目前主流的LB方案可分成两类:一种是集中式LB, 即在服务的消费方和提供方之间使用独立的LB设施(可以是硬件,如F5, 也可以是软件,如nginx), 由该设施负责把访问请求通过某种策略 ...

  2. netflix feign概述

    1.什么是feign?feign的作用是什么? Feign is a java to http client binder inspired by Retrofit, JAXRS-2.0, and W ...

  3. 第二十六章 hystrix-dashboard + turbine

    一.使用turbine的意义 引入多个hystrix stream: 1.使用hystrix-dashboard的可以添加多个stream的功能 图中添加的两个stream会在真正monitor的时候 ...

  4. 附7 turbine

    一.作用 聚集同一个微服务的相同的commandKey.Threadpool.commandGroupKey数据进行聚合 二.配置 1.集群(cluster)(turbine聚集数据的粒度) turb ...

  5. Building microservices with Spring Cloud and Netflix OSS, part 2

    In Part 1 we used core components in Spring Cloud and Netflix OSS, i.e. Eureka, Ribbon and Zuul, to ...

  6. 基于Spring Cloud和Netflix OSS构建微服务,Part 2

    在上一篇文章中,我们已使用Spring Cloud和Netflix OSS中的核心组件,如Eureka.Ribbon和Zuul,部分实现了操作模型(operations model),允许单独部署的微 ...

  7. spring cloud熔断监控Hystrix Dashboard和Turbine

    参考: http://blog.csdn.net/ityouknow/article/details/72625646 完整pom <?xml version="1.0" e ...

  8. SpringCloud系列七:Hystrix 熔断机制(Hystrix基本配置、服务降级、HystrixDashboard服务监控、Turbine聚合监控)

    1.概念:Hystrix 熔断机制 2.具体内容 所谓的熔断机制和日常生活中见到电路保险丝是非常相似的,当出现了问题之后,保险丝会自动烧断,以保护我们的电器, 那么如果换到了程序之中呢? 当现在服务的 ...

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

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

随机推荐

  1. VUEJS开发规范

    VUEJS开发规范 基于组件化开发理解 组件命名规范 结构化规范 注释规范 编码规范 基于组件化开发理解 什么是组件? ``` 组件其实就是页面组成的一部分,好比是电脑中的每一个元件(如硬盘.键盘.鼠 ...

  2. 三 概要模式 3) MR计数器计数 。无 reduce 计数

    计数器模式讲解:         先讲一下,就是说只用 Map 阶段  不需要 Reduce . 也就是说去掉了中间输出,而是Map 直接输出结果.大大提高了 MR 的效率且节省了 MR 中间输出读入 ...

  3. UVA 11020 Efficient Solutions+multiset的应用

    题目链接:点击进入 首先来讲,非常easy看到我们事实上仅仅要维护优势人群的集合:假设增加一个新的人,我们首先看一下优势人群中是否有人会让这个人失去优势,假设没有,则将这个人插入集合中.但要注意到这个 ...

  4. 深度学习系列之ANN

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd3F0aGFoYQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA ...

  5. C内存管理一 概述

    我们写了这么多年的程序猿.可能理论方面还比不上大学生.有人 "嘘"我了,假设有能回答下面几个问题的同学请举手: 1.面试常常遇到:同学请说说堆栈的差别? 2.同学请说说一个函数在堆 ...

  6. spark groupByKey 也是可以filter的

    >>> v=sc.parallelize(["one", "two", "two", "three", ...

  7. nyoj--1009--So Easy[Ⅰ](数学)

    So Easy[Ⅰ] 时间限制:1000 ms  |  内存限制:65535 KB 难度:2 描述 给出任意一个三角形的三个边a,b,c. 要求:求出这个三角形的外接圆半径. 输入 输入数据有多组. ...

  8. 数据仓库 SSIS

    SSDT 下载 :https://msdn.microsoft.com/en-us/library/mt204009.aspx Codeplex 上的 AdventureWorks 示例数据库此链接将 ...

  9. java 8 , merge()

    import java.util.HashMap; import java.util.Map; public class j8merge { public static void main(Strin ...

  10. Mac上vmware虚拟机Windows10安装Tomcat8.0及配置环境

    1.下载tomcat8.0或其他版本.下载地址:http://tomcat.apache.org/download-80.cgi 2.双击进行解压. 3.安装成功之后,右键我的电脑 --> 选择 ...