1。1什么是Hystrix Hystix是Netflix开源的一个延迟和容错库,用于隔离访问远程服务、第三方库,防止出现级联失败。 熔断器Netflix是一个容错管理工具,作用是通过隔离,控制服务从而对延迟和故障提供强大的容错能力,避免整个系统被拖垮。 复杂的分布式系统架构通常都具有很大的依赖,当一个应用高度耦合其他服务时,非常的危险。且容易导致失败。这种失败很容易伤害到服务的调用者。最后导致一个接一个连续错误。 当在系统的高峰时期,大量对微服务的调用可能会堵塞远程服务器的线程池。如果这个线程池没有和主应用服务器的线程池隔离,就可能导致整个服务器挂机。 Hystixy使用自己的线程池,这样和主应用服务器的线程池隔离,如果调用花费很长时间。会停止调用,不同的命令和命令组,能够被配置他们各自的线程池。可以隔离不同服务。1。2。熔断器的工作机制: 正常工作的情况下,客户端请求调用服务API接口: 当有服务出现异常时,直接进行失败回滚,服务降级处理: 当服务繁忙时,如果服务出现异常,不是粗暴的直接报错,而是返回一个友好的提示,虽然拒绝了用户的访问,但是会返回一个结果。 这就好比去买鱼,平常超市买鱼会额外赠送杀鱼的服务。等到逢年过节,超时繁忙时,可能就不提供杀鱼服务了,这就是服务的降级。 系统特别繁忙时,一些次要服务暂时中断,优先保证主要服务的畅通,一切资源优先让给主要服务来使用,在双十一、618时,京东天猫都会采用这样的策略。1。3。动手实践 1。3。1。引入依赖 首先在userconsumer中引入Hystix依赖:org。springframework。cloudspringcloudstarternetflixhystrixartifactId 1。3。2。开启熔断 1。3。2。改造消费者 我们改造userconsumer,添加一个用来访问的user服务的DAO,并且声明一个失败时的回滚处理函数:ComponentpublicclassUserDao{AutowiredprivateRestTemplaterestTprivatestaticfinalLoggerloggerLoggerFactory。getLogger(UserDao。class);HystrixCommand(fallbackMethodqueryUserByIdFallback)publicUserqueryUserById(Longid){longbeginSystem。currentTimeMillis();Stringurlhttp:Useruserthis。restTemplate。getForObject(url,User。class);longendSystem。currentTimeMillis();记录访问用时:logger。info(访问用时:{},endbegin);}publicUserqueryUserByIdFallback(Longid){UserusernewUser();user。setId(id);user。setName(用户信息查询出现异常!);}}HystrixCommand(fallbackMethodqueryUserByIdFallback):声明一个失败回滚处理函数queryUserByIdFallback,当queryUserById执行超时(默认是1000毫秒),就会执行fallback函数,返回错误提示。为了方便查看熔断的触发时机,我们记录请求访问时间。ServicepublicclassUserService{AutowiredprivateUserDaouserDpublicListqueryUserByIds(Listids){ListusersnewArrayList();ids。forEach(id{我们测试多次查询,users。add(this。userDao。queryUserById(id));});}}pre 1。3。3。改造服务提供者 改造服务提供者,随机休眠一段时间,以触发熔断:ServicepublicclassUserService{AutowiredprivateUserMapperuserMpublicUserqueryById(Longid)throwsInterruptedException{为了演示超时现象,我们在这里然线程休眠,时间随机02000毫秒Thread。sleep(newRandom()。nextInt(2000));returnthis。userMapper。selectByPrimaryKey(id);}} 1。3。4。启动测试 然后运行并查看日志: id为9、10、11的访问时间分别是: id为12的访问时间 因此,只有12是正常访问,其它都会触发熔断,我们来查看结果: 1。3。5。优化 虽然熔断实现了,但是我们的重试机制似乎没有生效,是这样吗? 其实这里是因为我们的Ribbon超时时间设置的是1000ms: 而Hystix的超时时间默认也是1000ms,因此重试机制没有被触发,而是先触发了熔断。 所以,Ribbon的超时时间一定要小于Hystix的超时时间。 我们可以通过hystrix。command。default。execution。isolation。thread。timeoutInMilliseconds来设置Hystrix超时时间。hystrix:command:default:execution:isolation:thread:timeoutInMillisecond:6000设置hystrix的超时时间为6000ms