精通springcloud:微服务之间的通信,监控延迟和容错
Posted jinggege795
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了精通springcloud:微服务之间的通信,监控延迟和容错相关的知识,希望对你有一定的参考价值。
监控延迟和容错
如前文所述,Hystrix 并不是一个仅能实现断路器模式的简单工具。它是一种可以处理分布式系统中延迟和容错的解决方案。Hystrix 提供的一个有趣功能是能够公开与服务间通信相关的最重要指标,并通过用户界面仪表板显示它们。此功能适用于使用Hystrix命令包裹的客户端。
在之前的一些示例中,我们仅分析了系统的一部分,以模拟customer-service服务和account-service服务之间的通信延迟。在测试高级负载均衡算法或不同的断路器配置设置时,这是一个非常好的方法,但现在我们将回过头来分析为一组独立的Spring Boot应用程序设置的作为一个一体化的示例系统,这将使得开发人员能够观察Spring Cloud 与NetflixOSS工具一起工作的方式,了解它们如何帮助监控和响应微服务之间的通信中的延迟和失败问题。该示例系统将以简单的方式模拟故障。它具有静态配置,其中包括product-service服务和account-service服务的两个实例的网络地址,但每个服务只运行其中一个实例。
为了加深印象并区别于上一个示例,本示例的系统架构考虑了有关故障的假设,其示意图如图7.1所示。
这一次的测试也有所不同。以下是测试方法的片段,它在循环中被调用。首先,它将调用order-service服务的POST htp:///calhost:8090/端点,发送Order 对象,并接收具有id、 status 和price集合的响应。该请求在图7.1中被标记为①,order-service 服务与product-service服务和customer-service 服务通信,此外,customer-service 服务将调用account-service服务的端点。如果订单已被接收,则测试客户端将使用订单的id调用PUTht:/oc/thost:8090/ {id}方法接收该订单并从该账户中提取资金。在服务器端,这种情况下只有一个服务间通信,在图7.1中标记为②。在运行此测试之前,必须启动属于系统一部分的所有微服务。
Random r = new Random() ;
Order order - new Order() ;
order. setCustomerId( (1ong) r.nextInt(3)+1) ;
order . setProductIds (Arrays. asList (new Long[] ( (long) r. nextInt (10) +1, (long)
r.nextInt(10)+1}));
order - template . postForobject ("http://localhost:8090", order,
Order.class); /1 对应图7.1中的①
if (order.getstatus() !- OrderStatus . REJECTED) {
template . put ("http://localhost:8090/{id}", null, order.getId0); //对应图7.1中的②
}
公开Hystrix的指标流
使用Hytrix与其他微服务进行通信的每个微服务都可能公开使用Hystrix命令包裹的每个集成的指标。要启用此类指标流(Metrics Stream),应该在
spring-boot-starter-actuator上包含依赖项,这会将/ystrix.stream对象公开为管理端点。此外,开发人员还必须包含spring-cloud- sarer-hystrix,因为它已经被添加到我们的示例应用程序中。
<dependency>
<groupId>org . springfr amework . boot</groupId>
<artifactId>spring-boot-starter- actuator</artifactId>
</dependency>
已经生成的流将进一步公开为JSON条目,这些JSON条目中将包含表示方法中的单一调用的特征的指标。以下是来自customer-service服务的GET /withAccounts/{id}方法中的单个条目。
("type" :"HystrixCommand","name" :”customer-service . findWi thAccounts",
"group" : "CustomerService", "currentTime" :1513089204882,
"isCircuitBreakeropen" : false, "errorPercentage":0, "errorCount":0,
" requestCount":74, "rollingCountBadRequests":0,
”rollingCountCollapsedRequests":0, "rollingCountEmit":0,
"rollingCountExceptionsThrown":0, "rollingCountFailure":0,
”rollingCountFallbackEmit":0, "rollingCountFallbackFailure":O,
"rollingCountFallbackMissing":0, "rollingCountFallbackRejection":0,
"rollingCountFal lbackSuccess":0, "rollingCountResponsesFromCache":0,
"rollingCountSemaphoreRejected":0, "rollingCountShortcircuited":0,
"rolli ngCountSuccess": 75,"rollingCountThreadPoolRejected":0,
”rollingCountTimeout":0, "currentConcur rentExecutionCount":0,
| "rollingMaxConcurrentExecutionCount":1, "latencyExecute mean":5,
"latencyExecute": ("0":0, "25":0, "50":0,"75":15, "90":16,"95":31,
"99":47, "99.5":47, "100":62), "latencyTotal mean":5,
"latencyTotal":{"0":0, "25":0, "50":0, "75":15, "90":16, "95":31,
"99":47, "99.5":47,"100":62},
"propertyValue_ circuitBreakerRequestVolumeThreshold":10,
"propertyValue_ circuitBreakerSleepWindowInMilliseconds":10000,
"propertyalue_ circuitBreakerErrorThresholdPercentage":30,
"propertyValue_ circuitBreakerForceopen":false,
"propertyvalue_ circuitBreakerForceClosed":false,
"propertyvalue_ circuitBreakerEnabled":true,
"propertyvalue_ executionIsolationStrategy" :"THREAD",
"propertyValue_ executionIsolationThreadTimeout InMilliseconds" :2000,
"propertyValue_ executionTimeout InMilliseconds":2000,
"propertyvalue_ executionIsolati onThreadInterruptOnTimeout" :truer
"propertyvalue_ executionIsolationThreadPoolKeyoverride":null,
"propertyValue_ executionIsolati onSemaphoreMaxConcurrentRequests":10,
"propertyValue_ fallbackIsolati onSemaphoreMaxConcur rentRequests":10,
"propertyValue_ metricsRollingStatisticalWindowI nMilliseconds": 10000,
"propertyvalue_ requestCacheEnabled":true,
"propertyValue_ requestLogEnabled": true, " reportingHosts":1,
"threadPool": "Custom erService")
Hystrix 仪表板
Hystrix仪表板将可视化以下信息。
口运行状况和流量将显示为一个圆圈,这个圆圈会更改其颜色和大小,以反映传入的统计信息的更改。
口过去10秒内的错误百分比。
口按数字显示最后两分钟的请求率,在图表上显示结果。
口断路器状态。断开为Open, 闭合为Closed服务主机的数量。
口最后 一分钟的延迟百分位数。
口服务的线程池。
1.使用仪表板构建应用程序
Hystrix仪表板与Spring Cloud集成在一起。 在系统内部实现仪表板时,最好的方法是将独立的Spring Boot应用程序与仪表板分开。要在项目中包含Hystrix仪表板,可以使用spring cloud-starter hystrix-netix -dashboard启动器:对于Spring Cloud Netlix来说则是使用
spring-cloud-starter-hystrix- dashboard.请注意,Spring Cloud Netlix版本必须早于1.4.0.
<dependency>
<groupId>org . spr ingEr amework. cloud</groupId>
<artifactId>spring-cloud-atarter-hystrix-dashboard</artifactId>
</dependency>
应用程序的main 类应该使用@ EnablHystrixDashboard进行注解。在启动之后,Hystrix仪表板即在hytrix上下文路径下可用。
@springBootApplication
@EnableHystrixDashboard
public class HystrixApplication {
public static void main(string[] args) {
new
SpringApplicationBuilder (HystrixApplication.class) .web (true)。run(args);
}
}
本示例系统已经将端口9000 配置为Hystrix 应用程序的默认设置,并且这是在hystrix- dashboard模块中实现的。因此,在启动hystrix dashboard后,如果在Web浏览器中调用ht:/oclhost,9000htrx地址,它将显示如图7.2所示的页面。在该页面,开发人员应该提供Hystrix流端点的地址,以及可选的标题。如果要显示从order-service服务调用的所有端点的指标,可输入地址htt:l/ho/t/:/htrixri stream,然后单击MonitorSteam (监控流)按钮。
2.监控仪表板上的指标
现在我们将介绍如何调用customer-service服务的GET /withAccounts/{id}方法。它被@HystrixCommand包裹,显示在Hystrix 仪表板.上,并且在
customer-service.findWithAccounts标题下,取自commandKey属性。此外,用户界面仪表板还将显示有关分配给每个Spring Bean的线程池的信息,这些线程池提供了使用Hystrix命令包裹方法的实现。在这种情况下,它是CustomerService.
@Service
public class CustomerService {
//...
@CachePut ("customers")
@HystrixCommand (commandKey一"customer -service. findwithAccounts",
fallbackMethod = "findCustomerWi thAccountsFallback",
commandProperties = (
@HystrixProperty (name =
”execution. isolation. thread. timeoutInMilliseconds", value = "2000"),
@HystrixProperty (name -
"circuitBreaker. requestVolumeThreshold", value = "10"),
@HystrixProperty (name =
"circuitBreaker.errorThresholdPercentage", value =“30),
@HystrixProperty (name =
"circuitBreaker. sleepWindowInMilliseconds", value = "10000"),
@HyatrixProperty (name二
"metrics . rollingStats. time InMilliseconds", value 一"10000")
})
public Customer findcustome rWi thAccounts (Long customerId; {
Customer customer =
template . getForobject ("http://customer -service/withAccounts/lid}",
Customer.class, customerId) ;
return customer;
}
public Customer findCustome rWi thAccountsFallback (Long customerId)4
ValueWrapper w =
cacheManager . getCache ("customers") .get (customerId) ;
if (w ! =nu11) {
return (Customer) w.get();
} else {
return new Customer();
}
}
}
如图7.3所示是JUnit测试开始后Hystrix 仪表板的屏幕截图。在该图中,我们监视的是使用@HystrixCommand包裹的所有3个方法的状态。正如预期的那样, product-service服务的findBylds方法的电路已经断开。几秒钟之后,account-service 服务的withdraw方法的电路也已经断开。
片刻之后,情况将会稳定下来。所有电路都保持闭合状态,因为只有一小部分流量被发送到应用程序的非活动实例。这显示了Spring Cloud与Hystrix和Ribbon的强大功能。系统能够自动重新配置自身,以便根据负载均衡器和断路器生成的指标将大多数传入请求重定向到工作实例,如图7.4所示。
3.使用Turbine聚集Hystrix的流
开发人员可能已经注意到,我们只能在Hystrix仪表板中查看该服务的单个实例。当我们显示order-service服务的命令状态时, customer. service服务和account-service服务之间的通信便没有指标数据,反之亦然。可以想象,如果order-service服务有多个实例在运行,那肯定会使我们手忙脚乱,因为必须在Hystrix仪表板中的不同实例或服务之间定期切换。幸运的是,有一个名为Turbine的应用程序,它可以将所有相关的Ahystrix. stream端点聚合到一个组合的turbine.stream中,使我们能够轻松监控整个系统的整体运行状况。
(1)启用Turbine
在做出修改以便为示例应用程序启用Turbine之前,应该从启用服务发现开始,这是启用Turbine所必须的。切换到hystrix. _with_ turbine 分支以访问支持使用Eureka进行服务发现并使用Turbine聚合Hystrix流的示例系统版本。要为公开用户界面仪表板的项目启用Turbine,只需在依赖项中包含spring-cloud-starter turbine,并使用@EnableTurbine注解应用程序的main类。
<dependency>
<groupId>org, spr ingf r amework. cloud</groupId>
<arti factId>spring-cloud-starter-turbine</artifactId>
</ dependency>
turbine. appConfig配置属性是Turbine将用于查找实例的Eureka服务名称的列表。然后,可以在URL http://localhost,900/turbinestreamn) 下的Hystrix仪表板中使用Turbine流。该地址也可以由
turbine.aggregator.clusterConfig属性的值确定,如hp://calhost:9000/turbine. stream?cluster-<clusterName>.如果该名称是default,则可以省略cluster参数。以下是Turbine配置,它可以将所有Hystrix的可视化指标结合在一个用户界面仪表板中。
turbine :
appConfig:
order- service, customer-service
cluste rNameExpression:“‘default’”
现在,整个示例系统的所有Hystrix指标都显示在一- 个仪表板站点中。我们需要显示的只是监视统计信息流,这可在http:/p:/0//0rbine.straeo’下找到,如图7.5所示。
开发人员也可以通过提供一个具有turbine aggregator .clusterConfig属性的服务的列表来为每个服务配置一个集群。在这种情况下,开发人员可以通过提供具有ht:t/calhost9000/turbine. stream.cluster- ORDER-SERVICE参数的服务名cluster在集群之间切换。该集群的名称必须以大写形式提供,因为Eureka服务器返回的值是大写的。
turbine :
aggregator:
clusterConfig: ORDER- SERVICE, CUSTOMER- SERVICE
appConfig: order-service, customer-service
默认情况下,Turbine将在Eureka中已注册实例的homePageUrl地址下查找该实例的/hystrix.stream端点,然后它会将/ystix.stram附加到该URL。本示例应用程序的order-service服务是在端口8090下启动的,因此,还应该将默认管理端口覆盖到8090。order- service服务的当前配置显示在以下代码片段中。或者,开发人员也可以使用eureka.instance.
metadata-map.management.port属性更改该端口。
spring:
application:
name: order-service
server:
port: ${PORT:8090)
eureka:
client:
serviceurl:
defaultZone: S(EUREKA URL:http://localhost:8761/eureka/}
management:
security:
enabled: false
port: 8090
(2)通过流传输启用Turbine
虽然经典Turbine模块可以从所有分布式Hystrix命令中提取指标,但这并不总是一个好选择。诸如从HTTP端点收集指标数据之类的操作也可以使用消息代理以异步方式实现。要通过流传输(Streaming)启用Turbine,应该在项目中包含以下依赖项,然后再使用@EnableTurbineStream注解主应用程序。虽然以下示例使用了RabbitMQ作为默认的消息代理,但是开发人员也可以通过包含spring-cloud starter steam-kafka来使用ApacheKafka.
<dependency>
<groupId>org. springf ramework. cloud</groupId>
<artifactId>spr ing-cloud-starter- turbine- stream</artifactId>
</ dependency>
<dependency>
<groupId>org. springframework. cloud</groupId>
<artifactId>spring-cloud- starter-stream- rabbit</artifactId>
</ dependency>
上述代码中的依赖项应包含在服务器端。对于客户端应用程序来说,这些是order-service服务和customer-service服务,开发人员需要添加
spring-cloud-netflix-hystrix-stream库。如果已经在本地运行消息代理,则它应该已在自动配置的设置上成功运行。开发人员也可以使用Docker容器运行RabbitMQ,就像我们在本书第5章“使用Spring CloudConfig进行分布式配置”的Spring Cloud Config 集成使用AMQP的示例中所做的那样。然后,开发人员应该在application.yml中为客户端和服务器端应用程序覆盖以下属性。
spring:
rabbi tmq:
host: 192.168.99.100
port: 5672
username: gues t
password: guest
如果登录到htp://92. 1899.100:15672下的RabbitMQ管理控制台,开发人员将看到在本示例应用程序启动后创建了名为springCloudHystrixStream的新交换消息。现在,我们唯一要做的就是运行和上一小节的经典Turbine方法示例相同的JUnit测试,所有指标数据都通过消息代理发送,并且可以在ht:/oclhost:9000端点下观察。如果开发人员想要自己尝试,可切换到hystrix. with_ turbine_ stream 分支(有关详细信息,请参阅htpt:/ithubo.
com/piomin/sample-spring-cloud-omm/tree/hystrix. with_ turbine. stream)。
总结
因为文章包含的内容实在是太多了,就不给大家做过多的介绍了,需要这份文档来学习的小伙伴,可以转发此文关注小编。
扫码来获取就可以了!
以上是关于精通springcloud:微服务之间的通信,监控延迟和容错的主要内容,如果未能解决你的问题,请参考以下文章
精通springcloud:微服务之间的通信,使用Ribbon执行负载均衡
精通springcloud:微服务之间的通信,带Hystrix的断路器模式
你是否精通springcloud:使用SpringCloud进行同步通信?
你是否精通springcloud:使用SpringCloud进行同步通信?