深入浅出springcloud与微服务构建(快来深度解锁SpringCloud主流组件)

深入浅出springcloud与微服务构建(快来深度解锁SpringCloud主流组件)(1)

Hystrix注解

通过前面的内容,基本上了解了Hystrix的大部分功能的设计意图和用法,但是发现使用Hystrix需要配合大量的命令模式,需要编写除业务代码之外更多的代码,当然Hystrix也提供了一些简单的用法,如通过注解来完成指令和缓存的配置。

虽然使用注解也有一定的侵入性,但是比每次创建一个Command要优雅一些,比较常见的就是@HystrixCommand 注解。通过HystrixCommand可以快速设置 fallback,同样也可以完 成如commandKey和groupKey的配置,具体代码如下。

同样,在使用请求缓存时,也可以通过@CacheResult 、@CacheRemove来实现,代码如下。

深入浅出springcloud与微服务构建(快来深度解锁SpringCloud主流组件)(2)

在上述代码中,通过@CacheResult来标记需要Hystrix缓存的方法,然后通过cacheKey Method来指定生成缓存key的方法,当数据更新后,可以通过@CacheRemove清除缓存。下面写一个测试来验证一下,代码如下。

深入浅出springcloud与微服务构建(快来深度解锁SpringCloud主流组件)(3)

我们期望得到的输出如下。

深入浅出springcloud与微服务构建(快来深度解锁SpringCloud主流组件)(4)

如果仅仅是单元测试,那么这里应该会报错。

深入浅出springcloud与微服务构建(快来深度解锁SpringCloud主流组件)(5)

所以还需要初始化HystrixRequestContext,代码如下。

深入浅出springcloud与微服务构建(快来深度解锁SpringCloud主流组件)(6)

当然,大多数情况下可能不需要每次都定义cacheKeyMethod,通常可以直接使用@CacheKey来设置缓存的key值。下面使用之前cacheKeyMethod的例子,使用@CacheKey改造后的代码如下。

深入浅出springcloud与微服务构建(快来深度解锁SpringCloud主流组件)(7)

由上述代码可知,直接使用用户的ID作为缓存的key,@CacheKey是作用在方法参数上的,也可以通过@CacheKey的value来指定key的规则。例如,在updateUser方法上,方法参数是User,可以通过指定@CacheKey("id")来表示使用User中属性名为ID的值来作为缓存的key值。下面查看@CacheKey的源码来了解该注解value的详细说明。

深入浅出springcloud与微服务构建(快来深度解锁SpringCloud主流组件)(8)

Hystrix控制台

Hystrix Dashboard是Hystrix为我们提供的一个友好的监控页面,它收集了Hystrix中的每个HystrixCommand的执行情况,使用时需要添加额外的依赖spring-cloud-starter-hystrix dashboard,还需要在Spring Boot的启动类上增加@EnableHystrixDashboard注解来启动监控。假如此时本地的服务端口是8080 , 就可以通过访问localhost:8080/hystrix进入Dashboard首页,如图3.5所示。

深入浅出springcloud与微服务构建(快来深度解锁SpringCloud主流组件)(9)

假如此时我们想查看本地8080服务的断路器使用情况,可以在第一个地址栏中输入服务的地址 , 然后加上hystrix.stream , 如http://localhost:8080/hystrix.stream,最后单击图3.5所示最下方的Monitor Stream按钮,就会进入具体的统计页面,如图3.6所示。

深入浅出springcloud与微服务构建(快来深度解锁SpringCloud主流组件)(10)

Hystrix Dashboard是基于Spring Boot Actuator(Spring Boot健康监控组件,在下节中会详细介绍)来进行数据收集的,而且是以Web的方式,如果你使用的是2.0及以上版本的Spring Boot,那么这里需要注意,在新版本中,监控组件并不会默认开启所有的Web端点数据,所以Hystrix Dashboard并不能访问Hystrix的监控数据,这里需要手动开放Web的Hystrix的监控端点,在application.yml中的配置代码如下。

深入浅出springcloud与微服务构建(快来深度解锁SpringCloud主流组件)(11)

hystrix.stream是Hystrix监控端点的名称,开启后重启服务即可,新版本监控地址也发生了变化,hystrix.stream的地址变成了http://localhost:8080/actuator/hystrix.stream , 在 Hystrix Dashboard的首页输入该地址即可。

首次使用时会出现没有数据的现象,如图3.7所示。

深入浅出springcloud与微服务构建(快来深度解锁SpringCloud主流组件)(12)

那是因为这是第一次启动,还没有任何配置断路器的请求发生,我们可以手动发送几次请求,数据就会出现了。至此,关于Spring Cloud Netflix Hystrix的功能和用法基本介绍完了,还想深度了解的读者可以访问Spring Cloud Netflix的官方教程。

健康监控

在生产环境中,我们通常会为服务添加各种监控组件或日志追踪等功能,看了Hystrix的监控功能是不是觉得很好用?除了Hystrix,我们还能对微服务进行哪些监控?下面了解一下其他的监控组件。Spring Boot为我们提供了一个十分便捷的框架:Spring Boot Actuator。Actuator提供了几个生产级的服务,用于监控应用程序的运行信息,如运行状态、指标、环境变量、配置信息等,只要简单的几个步骤就可以使用。

Actuator本身的用法也十分简单,只需引入Actuator的依赖包spring-boot-starter-actuator即可,然后启动服务。假设本地的端口还是8080,通过 HTTP 的方式在浏览器中访问地址http://localhost:8080/actuator,得到JSON数据如下。

深入浅出springcloud与微服务构建(快来深度解锁SpringCloud主流组件)(13)

其中,每个地址都被称为一个Endpoint(端点),Actuator提供了很多端点的实现,并且提供了JMX和Web两种接口方式。其中,JMX的接口几乎暴露了所有的端点,而Web的接口默认只开启health和info的端点,我们可以通过配置开启和关闭这些端点,具体如下。

深入浅出springcloud与微服务构建(快来深度解锁SpringCloud主流组件)(14)

通过在application.yml中添加如上配置,在Web接口上增加了env、metrics、beans等端点,移除了info的端点,如果想配置开启全部的端点,也可以配置include:*,在重启服务后,再次访问/actuator的地址来验证配置是否生效,得到的JSON数据如下。

深入浅出springcloud与微服务构建(快来深度解锁SpringCloud主流组件)(15)

那么,这些端点是什么意思,监控了哪些信息,还有哪些端点呢?下面就为大家展示一些常用的端口说明。

(1)auditevents:安全相关的统计信息,如用户登录、注销等。

(2)beans:返回所有BeanFactory使用的Bean。

(3)conditions:之前版本是autoconfig,展示所有的自动化配置信息。

(4)configprops:所有@ConfigurationProperties的Bean。

(5)env:应用的环境属性,可以通过/env/{name}进行过滤。

(6)flyway:flyway数据迁移的信息,flyway是一个数据库管理和迁移的工具。

(7)health:应用的健康信息总览。

(8)info:应用的一般信息,也可以是自定义数据。

(9)Liquibase:同flyway,是另一个数据库管理工具。

(10)Metrics:应用程序的指标信息,包括通用指标和自定义指标。

(11)Mappings:应用的Mapped的URL信息,包括Servlet和Filter的信息。

(12)Scheduledtasks:应用程序中计划任务的详细信息。

(13)Sessions:正在使用的Spring Session详细信息。

(14)Shutdown:关闭应用程序,不推荐使用,默认是关闭。

(15)threaddump:执行一个JVM线程dump。

(16)heapdump:从我们的应用程序使用的JVM构建,并返回当前JVM的堆快照信息(二进制格式)。

(17)logfile:应用程序日志信息。

(18)loggers:查询和修改应用程序的日志记录级别。

虽然Spring Boot Actuator提供了大量的内置端口,可以满足大部分的服务健康监控的需求,但实际项目中会遇到各种需求,有时想要自定义监控逻辑,但又不想从零全部自己实现监控的代码,这时该如何处理?Actuator也提供了自定义端点的方式,只需自己实现具体的监控业务代码即可。

例如,统计一个通过ID获取用户的API的请求次数,先定义一个端点来做统计这件事情,代码如下。

深入浅出springcloud与微服务构建(快来深度解锁SpringCloud主流组件)(16)

使用@Endpoint注解来声明这是一个端点,并且定义了端点的ID,为了简便就不实现持久化的存储了,仅使用AtomicInteger来做请求次数的统计,提供record方法去记录请求次数,通过@ReadOperation注解提供 GET 方法的返回 , Actuator 还提供了@WriteOperation 和@DeleteOperation注解,与HTTP的方法映射关系如下。

@ReadOperation ←→ GET

@WriteOperation ←→ POST

@DeleteOperation ←→ DELETE

使用@ReadOperation,然后在对应的Controller或WebFilter中做记录即可。例如,这里将计数方法添加到Controller中,代码如下。

深入浅出springcloud与微服务构建(快来深度解锁SpringCloud主流组件)(17)

然后需要在配置文件中配置端口的ID,具体如下。

深入浅出springcloud与微服务构建(快来深度解锁SpringCloud主流组件)(18)

在启动服务后,先通过浏览器调用几次getById的接口,最后访问地址http://localhost:8080/actuator/getuserbyid,得到我们想要的统计。当然,通常我们会返回一些对象,如Map,这样可以得到JSON数据,这里的例子为了简便,直接返回基本数据类型,得到结果如下。

分布式链路跟踪

已经可以通过如Hystrix Dashboard和Spring Boot Actuator等方式监控服务的运行状况,微服务的调用和依赖往往是复杂的,如图3.2所示,这时如果系统出现异常,随着系统的调用链越来越长,我们将无法快速地定位,甚至无法定位到底哪个服务出现了问题。所以需要一种可以追踪调用链、快速定位问题信息的工具,分布式链路跟踪就是这种工具。同样地,Spring Cloud也为我们提供了分布式链路跟踪的框架:Spring Cloud Sleuth。

设计要素和术语

凡是跟踪或监控系统都会对业务代码有一定的侵入性,所以设计的首要目的是低侵入性,所有的埋点都应该尽量少地侵入或不侵入业务代码,从而减少开发人员的负担,监控方法的调用次数的例子就是不好的设计,将埋点直接写在了业务代码中。

其次,只要是埋点,就会涉及数据的收集、传递和存储等操作,会有一定的资源开销,但我们要尽可能地降低这些开销,降低埋点本身的性能消耗等非业务系统本身的开销。例如,一个接口本身运行只需要200ms,埋点需要1s,这个接口整体运行下来需要1.2s,这就得不偿失了。

深入浅出springcloud与微服务构建(快来深度解锁SpringCloud主流组件)(19)

跟踪系统一定要支持分布式,要具有良好的扩展能力。除了具备这些能力,一个完整的分布式跟踪系统还应该具备日志的生成、收集和存储的功能,以及统计和分析日志数据的功能,此外,还有展示结果辅助决策的功能。

满足以上几点,才能算是一个好的分布式链路跟踪系统。SpringCloud Sleuth中使用了Dapper的术语,其中要了解以下关键术语。

(1)Span:最基本的工作单元,如一次调用,Span中描述了该工作单元的基本信息。(2)Trace:由一串Span组成的树状的链路,通过对Trace的分析可以得到很多有用的信息。

(3)Annotation:用于及时记录事件的存在,主要包括CS、SR、SS和CR事件,详细描述如下。

①CS:Client Sent,客户提出了请求。

②SR:Server Received,服务端获得请求并开始处理它。

③SS:Server Sent,响应被服务端发送回客户端。

④CR:Client Received,客户端已成功收到服务端的响应。

Spring Cloud Sleuth链路监控

Spring Cloud Sleuth的使用大量借助了Dapper、Zipkin和HTrace等开源框架,用于记录和追踪链路数据,对于一般使用者来讲,跟踪是隐形的,并且与外部系统的交互都会有检测,我们可以通过Sleuth简单地在日志中捕获数据,也可以将数据发送到远程收集服务器上。因此,要使用它也十分简单,以集成Zipkin为例,我们只需在想要监控的服务上增加Spring Cloud Sleuth和Zipkin的依赖即可,代码如下。

深入浅出springcloud与微服务构建(快来深度解锁SpringCloud主流组件)(20)

同时,需要在Gradle中配置Spring Cloud的依赖管理插件,代码如下。

深入浅出springcloud与微服务构建(快来深度解锁SpringCloud主流组件)(21)

Spring Cloud Sleuth有一个Sampler策略,可以通过这个策略来控制采样算法。采样器不会阻碍与Span相关ID的产生,但是会对导出以及附加事件标签的相关操作造成影响。Sleuth默认采样算法的实现是Reservoir sampling,具体的实现类是PercentageBasedSampler,默 认的采样比例为 0.1( 10% ) 。不过可以通过spring.sleuth.sampler.percentage来设置,所 设置的值为0.0~1.0,1.0表示全部采集。若需要全部采集,则配置如下。

深入浅出springcloud与微服务构建(快来深度解锁SpringCloud主流组件)(22)

Spring Cloud Sleuth的工作模式就是将Trace和Span添加到Slf4jMDC,因此可以从日志聚合器中的给定跟踪或跨度中提取所有日志。同时,Sleuth还提供对分布式跟踪数据模型的抽象:traces、spans、annotations 和 key-value annotations 等 。 基于 HTrace , 但兼容Zipkin和Dapper。其中,大部分埋点的出口和入口均来自Spring框架的组件,如Servlet Filter、RestTemplate、Cheduled Actions、Message Channels、Zuul Filters和Feign Client等。

深入浅出springcloud与微服务构建(快来深度解锁SpringCloud主流组件)(23)

Spring Cloud Sleuth会在不同的服务中自动添加相关的监控埋点,如果这里想要将埋点数据收集并进行统计,就要借助Zipkin服务器把埋点的数据收集起来,默认的Sleuth会将收集的数据发送到localhost(端口9411)上的Zipkin收集器服务上。也可以通过配置项spring.zipkin.baseUrl来修改这个地址,在application.yml中的配置如下。

深入浅出springcloud与微服务构建(快来深度解锁SpringCloud主流组件)(24)

可以通过Docker的方式快速启动一个Zipkin服务,指令如下。

深入浅出springcloud与微服务构建(快来深度解锁SpringCloud主流组件)(25)

Zipkin也可以通过安装源码或者Jar包的方式运行,Zipkin的运行并不是本章介绍的重点,感兴趣的读者可以查阅Zipkin的GitHub官方地址https://github.com/openzipkin/zipkin进行学习。下面为大家展示Zipkin的一些监控效果,如图3.8所示。

深入浅出springcloud与微服务构建(快来深度解锁SpringCloud主流组件)(26)

关于Spring Cloud Sleuth的基础功能就介绍到这里,SpringCloud Sleuth还有很多高级的用法,如抽样、传播、自定义Span等,可以到Spring的官网上查询详细的教程。在学习众多技术实践后,读者基本上可以搭建一套包含服务治理、监控、熔断、跟踪等功能比较完善的微服务系统,但在实际项目中,还会遇到一些技术本身无法处理的问题,这时就需要在设计层面来优化微服务结构。契约测试就是一个很好的维护服务间相互依赖的设计(将在第4章介绍)。

深入浅出springcloud与微服务构建(快来深度解锁SpringCloud主流组件)(27)

本文给大家讲解的内容是Hystrix注解
  1. 下篇文章给大家讲解的是微服务架构下的契约测试;
  2. 觉得文章不错的朋友可以转发此文关注小编,有需要的可以私信小编获取;
  3. 感谢大家的支持!
,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页