在以前的文章中,咱们前后介绍了eureka,ribbon,feign,使用eureka集群的方式来保证注册中心的高可用,在eureka中使用ribbon进行负载均衡,使用feign接口替换手动编码请求接口的代码,整个微服务看似基本完成了,那是否有继续值得优化的地方呢?答案确定是有的,而且是整个微服务最重要的一环,那就是服务的热熔断与降级,那为何服务熔断与降级是最重要的一环呢?咱们先来看一下服务雪崩的概念.git
所谓服务雪崩,是微服务系统中特有的概念,不了解服务雪崩的概念的童鞋,初一听服务雪崩,确定会联想到缓存雪崩,所谓缓存雪崩,即大量缓存在同一时间过时,致使大量请求不走缓存而进行数据库访问,数据库瞬时压力暴增,致使数据库宕机.通常咱们的解决方案无非有几点:
1.为不一样的缓存设置不一样的过时时间.
2.热点数据永不过时.
3.缓存预热.
咱们之因此要预防缓存雪崩,从系统架构五个方面(高性能/高可用/伸缩性/扩展性/安全性)来说,是保证系统的高性能以及保护数据库,而咱们说要预防服务雪崩,是为了保证整个微服务系统的可用性,让咱们用一张图来讲说明:
github
假设在一个电商微服务系统中,有用户服务,订单服务,产品服务,物流服务等服务,用户服务调用订单服务,订单服务调用产品服务,产品服务调用物流服务,若是没有考虑服务的熔断与降级,假如在产品服务调用物流服务的时候,物流服务自己出问题了返回了错误或者是网络波动致使请求超时,则产品服务会报错,从而影响订单服务跟着报错,层层返回,直到最顶层的服务,这样就致使了一个微服务自身的问题影响了整个微服务系统级联报错,这就是所谓的服务雪崩,极端状况下,可能致使几个甚至整个微服务系统所有宕机,这对于现代微服务系统来讲,是没法忍受的,所以,咱们须要进行服务的熔断与降级.
须要注意的是,服务的熔断与降级是两个概念,通常而言,所谓服务熔断,是对服务提供方而言,当服务提供方没法调用的时候须要被熔断,而降级是对服务消费方而言,当服务提供方没法正常提供服务时,消费方须要降级处理.spring cloud中对服务的熔断和降级是使用hystrix,接下来,让咱们详细了解一下hystrix.spring
spring cloud中使用hystrix进行服务的熔断和降级,hystrix翻译成中文是豪猪的意思,它是Netflix开源的一款针对分布式系统进行服务熔断与降级的框架.那么咱们如何使用呢?让咱们直接用代码来演示一下:
把以前咱们的项目dhp-micro-service-producer复制一份为dhp-micro-service-producer-hystrix:
将之加入父项目:
数据库
老规矩,三个步骤,首先新增maven依赖:
缓存
而后修改代码:
安全
其中@HystrixCommand的做用是指定一个熔断方法,当有该注解的方法抛出异常的时候,会调用fallbackMethod指定的方法,该方法须要咱们本身根据业务须要来完成.须要注意的是,方法的入参和返回值都必需要和原始方法保持一致.
修改一下配置文件,注意eureka注册中心的地址和端口号,我这里修改端口号为7301:
网络
最后修改启动类,增长对hystrix的支持:
架构
而后启动来访问试一试,注意若是启动报错,看看是否eureka-server未启动,但这并不影响咱们的测试,因为咱们在producer项目中的product信息是使用代码方式来mock数据库操做:
app
总计只有6条数据,所以ID>6均查不出数据,返回product=null,就会触发咱们设置的降级方法,所以访问试一试:
负载均衡
说明咱们的服务提供方在服务出现异常时的熔断方法已经成功使用了,但这还不够,在某些状况下,服务的提供方并无问题,可是可能因为网络缘由致使消费方并不能成功调用到提供方的接口,此时服务提供方的任何处理都是毫无心义的,所以咱们须要在消费者端进行服务降级.
因为咱们以前使用feign进行接口代理,而feign中已经集成了hystrix,所以咱们须要改造consumer端代码:
首先在feign代理接口中新增fallbackFactory指定降级服务的类:
而后实现该类,该类须要实现FallbackFactory接口的create方法,返回一个泛型指定的服务,而且实现该指定接口中的全部方法的降级处理:
而后咱们能够验证一下:首先启动eureka-server,而后启动producer,将producer注册到eureka:
能够看到,咱们修改端口号为7301的producer[dhp-micro-service-producer-hystrix]已经成功注册到eureka,而后再启动consumer[dhp-micro-service-consumer-feign],我修改端口号为7005,而且还须要开启feign.hystrix.enabled=true,默认是false:
启动成功后,访问一下试一试:
当咱们id=1时,能够成功获取结果,再试一试当ID>6时的状况:
从描述能够看到,这是执行了producer[dhp-micro-service-producer-hystrix]的熔断方法,那咱们如何来验证消费者端的降级方法呢?首先须要关闭eureka-server的自我保护功能,而且设置10秒自检一次,剔除无效的服务:
那么如何算无效呢?这须要服务提供方进行设置,修改producer[dhp-micro-service-producer-hystrix]发送心跳时间以及服务过时时间,以便尽快让eureka-server剔除producer:
这里咱们为了快速让eureka-server剔除producer,设置5秒(默认值为30秒)发送1次心跳,而且告诉eureka-server,假如15秒(默认值为90秒,通常为心跳间隔时间的3倍)内没有发送任何心跳,则eureka-server将producer剔除,此时,eureka-server主动失效检测时间为10秒,则当咱们中止producer后最多25秒eureka-server会将producer剔除,此时再访问consumer:
能够看到,这是执行了咱们consumer的降级方法,自此hystrix在服务提供方和消费方的配置都完成了,是否是很简单?接下来,让咱们再了解一下hystrix的仪表盘dashboard.
Dashboard(仪表盘)是hystrix提供的一种用于服务监控的功能,能够利用它对某一个微服务进行监控,让咱们来试一试,首先新建一个module[dhp-micro-service-hystrix-dashboard]:
而后将之加入父项目:
接下来新增maven依赖:
而后配置文件修改服务端口号:
而后启动类新增对dashboard的支持:
启动起来看一下:
那么该如何使用呢?首先,须要确保被监控的服务有健康检查的依赖,好比咱们对producer[dhp-micro-service-producer-hystrix]进行监控,则须要确保producer的maven配置中有健康检查的相关依赖:
而且还须要相关的配置:
而后启动producer,而且在hystrix dashboard中输入对应的producer的地址,则就能监控到全部的对该地址的访问:
此时再访问该producer的相关接口,就能看到相关统计信息了:
至于其中每项数据的含义,我相信确定难不倒各位广大童鞋,毕竟有问题找度娘,你们都知道,有条件就Google,没有任何问题能难倒咱们.
细心的同窗会发现,以前咱们在hystrix-dashboard的首页上看到了这么一行提示:
翻译一下,就是告诉咱们若是是使用turbine的方式,监控地址的格式是turbine-hostname:port/turbine.stream,若是是单一的hystrix-app的方式,地址格式是hystrix-app:port/actuator/hystrix.stream,咱们以前就是使用的单一的这种方式,那么turbine又是什么呢?
咱们在上面说到,dashboard只能对某一个微服务进行监控,但实际状况是一个微服务生产系统远远不止一个微服务,咱们须要对全部的微服务都进行监控,而dashboard显然没法知足咱们的需求,而turbine则能够,所以turbine的做用就是能够对多个微服务同时进行监控.为了方便演示turbine对多个微服务的监控,咱们新建一个module[dhp-micro-service-user-hystrix]:
而后加入父项目:
而后老规矩,三个步骤,先配置maven依赖:
而后再配置application.properties:
相关配置具体的含义就不在多说了,以前的文章已经讲得很详细了,接着修改主类:
而后进行编码:
相关代码和producer相似,而后启动eureka-server,再启动user和producer:
能够看到两个服务都已经注册到eureka了,而后使用dashboard测试一下:
没有问题,说明能够,接下来,咱们使用turbine同时监控producer和user服务,为了便于和以前的dashboard比较,咱们新增一个turbine module[dhp-micro-service-turbine-dashboard]:
将之加入父项目:
而后老规矩,首先配置maven依赖:
而后配置application.properties:
其中最重要的就是须要配置turbine相关信息,app-config标识须要监控的服务,多个用逗号隔开,而且从名字咱们能够看出就是eureka中注册的服务的服务名:
新增主类配置:
而后先启动eureka-server,再启动user[dhp-micro-service-user-hystrix]和producer[dhp-micro-service-producer-hystrix]两个服务,再启动dashboard[dhp-micro-service-hystrix-dashboard],最后启动turbine[dhp-micro-service-turbine-dashboard],而后访问dashboard[dhp-micro-service-hystrix-dashboard],并监控turbine的地址:
而后分别请求user和producer:
而后看一下hystrix-dashboard:
发现只监控到了userController,可是并无监控到ProducerController,这是为何呢?是咱们配置不对吗?别着急,咱们来看一下控制台的信息:
提示信息告诉咱们,有一个链接被拒绝,所以放弃turbine对其的监控,失败的地址是192.168.1.13:7301,能够看出这是咱们的producer服务的地址,另外提示信息中status401,error和message都提示咱们,未受权的登陆,回忆一下,以前咱们的producer项目引入了dhp-micro-service-auth进行安全验证,须要用户名和密码,所以咱们找到了缘由:登陆producer时未受权,致使监控失败,那这该如何解决呢?很遗憾,turbine既能监控全部服务都有密码的情形,也能监控全部服务都没有密码的情形,可是对于有些服务有密码,而有些服务没有密码的情形,turbine就无能为力了,若是实在由于生产须要要适配,咱们只能经过修改dhp-micro-service-auth的方式,来让相应的服务取消对/actuator/hystrix.stream与/turbine.stream这两个地址的密码验证:
此时再重启一下producer,而后再次访问user和producer,再看一下dashboard:
此时producerController和UserController均成功被turbine监控了.
回顾一下,在本文咱们介绍了spring-cloud断路器hystrix以及对hystrix的单个服务监控hystrix-dashboard以及对多个服务监控的turbine,下一篇文章,咱们继续介绍网关zuul,敬请期待!
本文由博客一文多发平台 OpenWrite 发布!