在微服务场景中,通常会有很多层的服务调用。如果一个底层服务出现问题,故障会被向上传播给用户。我们需要一种机制,当底层服务不可用时,可以阻断故障的传播。这就是断路器的作用。他是系统服务稳定性的最后一重保障。
在springcloud中断路器组件就是Hystrix。Hystrix也是Netflix套件的一部分。他的功能是,当对某个服务的调用在一定的时间内(默认10s,由metrics.rollingStats.timeInMilliseconds配置),有超过一定次数(默认20次,由circuitBreaker.requestVolumeThreshold参数配置)并且失败率超过一定值(默认50%,由circuitBreaker.errorThresholdPercentage配置),该服务的断路器会打开。返回一个由开发者设定的fallback
fallback可以是另一个由Hystrix保护的服务调用,也可以是固定的值。fallback也可以设计成链式调用,先执行某些逻辑,再返回fallback。
如何使用
Netflix断路器是安装在服务消费者上。我们需要做的是在服务消费者上开启断路器并配置。
Ribbon消费者:
1,引入依赖
2,打开开关
只需要在启动类上加上@EnableCircuitBreaker注解即可
3,在服务上加上fallback
4,测试,将服务提供者关掉
过一会,再将服务提供者启动,可以观察到,服务消费者自动恢复。
注意,配置的fallbackMethod方法必须与被@HystrixCommand注解的方法有意向的入参和返回值
否则会报错fallback method wasn't found: defaultFallback
在Feign中使用
@EnableFeignClients中已经默认打开了断路器功能,所以这里的启动类上不需要再加@EnableCircuitBreaker注解
只需要在@FeignClient中为fallback参数指定fallback方法
因为@FeignClient注解的是接口,所以我们必须创建一个替代的类,就像mock一样
创建一个实现了HelloService接口的类
最后一步
在配置文件application.yml中开启断路器
在很早的版本中,Feign的断路器默认是开启的。后来有人提issue,认为这样不方便。一旦使用Feign就默认使用了断路器功能,导致了一些问题。后面从D版本开始断路器就是默认关闭的,需要手动打开。
可以看到和Ribbon一样的效果
注意事项
如果方法执行需要用到Thread Local的属性,这个属性默认是不能传递到fallback方法中的,因为在Hystrix中, 主要通过线程池来实现资源隔离. 通常在使用的时候我们会根据调用的远程服务划分出多个线程池. 例如调用产品服务的Command放入A线程池, 调用账户服务的Command放入B线程池. 这样做的主要优点是运行环境被隔离开了. 这样就算调用服务的代码存在bug或者由于其他原因导致自己所在线程池被耗尽时, 不会对系统的其他服务造成影响. 但是带来的代价就是维护多个线程池会对系统带来额外的性能开销. 如果是对性能有严格要求而且确信自己调用服务的客户端代码不会出问题的话, 可以使用Hystrix的信号模式(Semaphores)来隔离资源.
你需要做如下配置
Hystrix Dashboard
既然断路器可以检测到服务的可用性,但是不够直观。Hystrix Dashboard可以提供一个监控平台,方便查看服务的可用性。
1,新建一个工程
因为Dashboard是一个统一的断路器监控平台,所以我们新建一个项目。不和现在服务消费者混在一起
2,引入依赖
3,注解启动类
用@EnableHystrixDashboard注解启动类
启动引用,访问/hystrix
看上面的说明,我们可以知道,Hystrix Dashboard共支持三种不同的监控方式
1,默认的集群监控:通过URL:turbine-hostname:port/turbine.stream开启,实现对默认集群的监控。
2,指定的集群监控:通过URL:turbine-hostname:port/turbine.stream?cluster=[clusterName]开启,实现对clusterName集群的监控。
3,单体应用的监控:通过URL/hystrix-app:port/hystrix.stream开启,实现对具体某个服务实例的监控。
注意,这里有点问题,我们以前说过,从springboot2开始,actuator都是要在请求路径加上/actuator,也就是hystrix-app:port/actuator/hystrix.stream才对
Delay:控制服务器上轮询监控信息的延迟时间,默认为2000毫秒,可以通过配置该属性来降低客户端的网络和CPU消耗。
Title:该参数可以展示合适的标题。
监控单个实例的服务
我们先测试第3个,监控单个实例的服务。这个最好理解
对于Robbon工程,在上面我们已经加好了断路器。现在需要做的是引入actuator依赖
然后暴露hystrix.stream接口
启动应用。
现在我把windows10.microdone.cn:8781/actuator/hystrix.stream的服务填上,点击Monitor
多点击几次请求,可以看到请求的成功失败情况被监控起来了
对于Feign
我们上面讲过,Feign自己已经集成了断路器。但是如果要暴露hystrix.stream接口,还是必须引入spring-cloud-starter-netflix-hystrix依赖,在启动类上打上@EnableCircuitBreaker注解注解
然后测试,和Ribbon一样的效果
Turbine
turbine又是个什么概念?
Turbine是Netflix的一个独立项目,单独的一个springcloud实例的断路器数据用处并不大,而且很麻烦,像上面我们有两个消费者项目,就需要开两个页面查看,能不能把这些监控都聚合在以前看呢?
当然是可以的,所以才有了这个Turbine项目
Turbine的原理是,通过将将自己注册到注册中心,发现同一个注册中心上的hystrix服务,然后聚合数据。再通过暴露自己的端点,在仪表盘上进行展示。
操作:
1,创建一个应用
2,引入依赖:
启动类注解:
@EnableTurbine @EnableDiscoveryClient
yml配置:
启动,我们现在8792端口起来了turbine
在到hystrix页面,在监控地址填127.0.0.1:8792/turbine.stream
点击monitor
可以看到已经将feign和ribbon两个工程的消费者集合在了一起
服务名HelloService#hello(String)和hiService 是被Hystrix fallback的方法名
关于default
cluster-name-expression集群名字,可以是spel表达式,这里用的是默认的default。如果想自定义集群的名字,改为如下配置:
turbine:# 要监控的应用,多个用逗号隔开 app-config: feign-consumer,ribbon-consumer # 指定聚合哪些集群,多个使用","分割,默认为default aggregator: cluster-config: ribbon,feign # 配合被监控的应用使用。假设想要监控的应用配置了eureka.instance.metadata-map.cluster: ABC,则需要配置,同时turbine.aggregator.clusterConfig: ABC cluster-name-expression: metadata['cluster'] # 让同一主机上的服务通过主机名与端口号的组合来进行区分,默认情况下会以host来区分不同的服务,这会使得在本机调试的时候,本机上的不同服务聚合成一个服务来统计。 combine-host-port: true
这个配置是用了两个集群,ribbon和feign
cluster-name-expression配的是取元数据的cluster值
这个就需要对应去修改被监控应用的配置文件了,
ribbon消费者工程:
feign消费者工程:
全部重启一下
再去hystrix页面
这个时候再用 127.0.0.1:8792/turbine.stream是连不上的,因为集群名字已经变了,不再有default集群了
分别用127.0.0.1:8792/turbine.stream?cluster=feign和ribbon去监控
这样区分的作用是,如果公司有很多的服务,可以通过区分集群来分别查看。
举报/反馈

运维开发笔记

514获赞 706粉丝
专注IT互联网领域技术分享与业界动态追踪
关注
0
0
收藏
分享