为了正确地工作,Hystrix必须在内部收集大量的统计信息,包括计算成功和失败的调用和响应时间分布。将这些宝贵的数据保存在库中是一种自私的做法,但不用担心:Hystrix提供了几种方法来消化理解它。您可以订阅由Hystrix编写的多种类型的流,它们可以在库中发出事件。例如,下面的代码创建了一组HystrixCommandCompletion事件,每次FetchRating命令完成时都会发射事件:
import com.netflix.hystrix.metric.HystrixCommandCompletion;
import com.netflix.hystrix.metric.HystrixCommandCompletionStream;
Observable<HystrixCommandCompletion> stats =
HystrixCommandCompletionStream
.getInstance(HystrixCommandKey.Factory.asKey("FetchRating"))
.observe();
HystrixCommandCompletionStream是这样的流的一个工厂,但这里还有其他的像HystrixCommandStartStream或HystrixCollapserEventStream这样的。在应用程序内部拥有这些流可以让您构建更复杂的监视机制。例如,如果您想知道每秒给定命令失败多少次,请尝试以下方法:
import static com.netflix.hystrix.HystrixEventType.FAILURE;
HystrixCommandCompletionStream
.getInstance(HystrixCommandKey.Factory.asKey("FetchRating"))
.observe()
.filter(e -> e.getEventCounts().getCount(FAILURE) > 0)
.window(1, TimeUnit.SECONDS)
.flatMap(Observable::count)
.subscribe(x -> log.info("{} failures/s", x));
但是在这些流之上构建监控基础设施需要一点设计和工作。您还可能希望将监视从实际应用程序中具体化。Hystrix,通过hystrix-metrics-event-stream模块,支持通过HTTP推动所有聚合指标。如果您的应用程序已经在上面运行,或者有一个嵌入式servlet容器,这是足以将内置HystrixMetricsStreamServlet添加到您的映射。否则,您可以自己启动一个小容器:
import
com.netflix.hystrix.contrib.metrics.eventstream.
HystrixMetricsStreamServlet;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import static org.eclipse.jetty.servlet.ServletContextHandler.NO_SESSIONS;
//...
ServletContextHandler context = new ServletContextHandler(NO_SESSIONS);
HystrixMetricsStreamServlet servlet = new HystrixMetricsStreamServlet();
context.addServlet(new ServletHolder(servlet), "/hystrix.stream");
Server server = new Server(8080);
server.setHandler(context);
server.start();
无论您是将servlet映射到一个现有的容器,还是自己创建一个servlet,现在都可以通过实时访问Hystrix的统计数据。请注意,此连接不是简单的请求-响应,而是一个server-sent events(SSEs)流。每一秒都有一个新的JSON格式的统计信息被推到客户端:
$ curl -v localhost:8080/hystrix.stream
> GET /hystrix.stream HTTP/1.1
...
< HTTP/1.1 200 OK
< Content-Type: text/event-stream;charset=UTF-8
ping:
data: {
"currentConcurrentExecutionCount": 2,
"errorCount": 0,
"errorPercentage": 0,
"group": "Books",
"isCircuitBreakerOpen": false,
"latencyExecute": {/* ... */},
"latencyExecute_mean": 0,
"latencyTotal": {"0":18, "25":80, "50":98, "75":120, "90":138,
"95":146, "99":159, "99.5":159, "100":167},
"latencyTotal_mean": 0,
"name": "FetchRating",
"propertyValue_circuitBreakerErrorThresholdPercentage": 50,
"propertyValue_circuitBreakerSleepWindowInMilliseconds": 5000,
"propertyValue_executionIsolationSemaphoreMaxConcurrentRequests": 10,
"propertyValue_executionTimeoutInMilliseconds": 1000,
"requestCount": 334
...
}
data: { ...
即使在这个被剥离的示例中,您也可以看到哪个命令被测量了、什么是延迟分布(从0到100百分比)、断路器是否打开、它的参数是什么(错误阈值,超时等等)。这种连续的数据流可以被定制的监视工具和指示板进一步消费。然而,Hystrix又来了,它提供了一个非常健壮的仪表板,几乎完全是用在浏览器中运行的JavaScript编写的。所有这些独立应用程序----通过hystrix-dashboard实现----需要一个到hystrix.stream的URL。下面的图形显示了一个示例指示板:
PS-IMAGE
对于每个命令,都有一个类似的瓷砖,每一个都提出了几个重要的遥测细节,包括以下内容:
执行的命令的数量,按timeout (14), failure (31), short-circuited (0)等等分组。
延迟百分比(例如,我们看到90%的请求在不超过147毫秒的情况下)和图表上的短期历史
断路器状态和总吞吐量
如果我们使用阻塞的HystrixCommand情况下的线程池统计信息
该仪表板还可以通过Turbine显示从多个服务器聚合的流。这就是为什么我们可以看到主机数量和集群吞吐量的原因,即使流来自一个机器。一个Hystrix指示板非常有用,因为它可以在接近实时的情况下快速显示多个命令的状态。它也是彩色编码的,所以如果一些命令开始失败,它们相应的瓷砖会变成红色。
在分布式系统中,Hystrix是一个有用的工具,在这些系统中失败是不可避免的。命令模式允许我们封装和隔离错误域。与RxJava的集成使它成为需要更好的错误处理的响应式应用程序的一个好选择。