断路器hystrix原理及使用
2017-09-04 15:08
369 查看
原理
在微服务架构中,服务之间形成调用链路,链路中的任何一个服务提供者都可能面临着相应超时、宕机等不可用的情况,在高并发的情况下,这种情况会随着并发量的上升恶化,形成“雪崩效应”,而断路器hystrix正是用来解决这一个问题的组件。断路器基本原理为:
- 正常情况下,断路器关闭,服务消费者正常请求微服务
- 一段事件内,失败率达到一定阈值(比如50%失败,或者失败了50次),断路器将断开,此时不再请求服务提供者,而是只是快速失败的方法(断路方法)
- 断路器打开一段时间,自动进入“半开”状态,此时,断路器可允许一个请求方法服务提供者,如果请求调用成功,则关闭断路器,否则继续保持断路器打开状态。
断路器hystrix是保证了局部发生的错误,不会扩展到整个系统,从而保证系统的即使出现局部问题也不会造成系统雪崩。
本文示例代码:helloworld+helloworldfeign+hello+world
主要见springcloud-demo下
hello/
world/
helloworld/
helloworldfeign项目。
配置/使用
下面讲解在restTemplate和feign中断路器的配置和使用步骤restTemplate+ribbon整合Hystrix
引入hystrix依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency>
虽然Eureka依赖了ribbon,ribbon依赖了hystrix-core,但还是要引用了上面的maven依赖,因为下面用到的@HystrixCommand注解用到了hystrix-javanica包
启动类加上@EnableCircuitBreaker注解(@EnableHystrix也可以)
修改HelloWorldController的入口请求方法
@GetMapping("/message") @HystrixCommand(fallbackMethod = "getMessageFallback") public HelloworldMessage getMessage() { HelloMessage hello = getMessageFromHelloService(); WorldMessage world = getMessageFromWorldService(); HelloworldMessage helloworld = new HelloworldMessage(); helloworld.setHello(hello); helloworld.setWord(world); log.debug("Result helloworld message:{}", helloworld); return helloworld; } /** * 断路方法 * @return */ public HelloworldMessage getMessageFallback(){ HelloMessage helloMessage=new HelloMessage(); helloMessage.setName("hello"); helloMessage.setMessage("error occurs"); WorldMessage worldMessage=new WorldMessage(); worldMessage.setMessage("world error occurs"); HelloworldMessage helloworldMessage=new HelloworldMessage(); helloworldMessage.setHello(helloMessage); helloworldMessage.setWord(worldMessage); return helloworldMessage; }
通过@HystrixCommand注解的fallbackMethod指向断路方法,该方法会在调用hello服务或者world服务失败时被调用。
@HystrixCommand 注解还可以配置超时事件等其他属性。
测试
1)依次启动eureka server:
discovery/
trace/
hello/
world/
helloword项目
2)在浏览器输入地址
http:\\localhost:8020/message,则返回正确的结果
3)停止hello项目,再次输入上述地址,则执行断路器中的方法。
feign下整合Hystrix
- feign禁用Hystrix
在Spring Cloud中,只要Hystrix在项目的classpath中,Feign就会用断路器包裹Feign客户端的所有方法,如果要禁用Hystrix则可以通过自定义feign的配置来解决。
@Configuration public class FeignConfiguration{ @Bean @Scope("prototype") public Feign Builder feignBuilder(){ return Feign.builder(); } }
要禁用Hystrix的接口引用该配置即可
@FeignClient(name="hello",configuration=FeignConfiguration.class) public interface HelloService{ ...... }
**feign使用Hystrix**
- 启用Hystrix
默认情况下feign已经整合了Hystrix,在配置文件中开启即可(本人用的的`Dalston.SR2`版本的Spring Cloud,需要在配置文件开启)
feign: hystrix: enabled: true
接口指定回退类
在HelloService中修改FeignClient类,指定fallback的类
package com.example.helloworldfeign.service; import com.example.helloworldfeign.model.HelloMessage; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; /** * @author billjiang 475572229@qq.com * @create 17-8-23 */ @FeignClient(value="hello",fallback = HelloServiceFallback.class) public interface HelloService { @GetMapping("/message") HelloMessage hello(); }
实现了接口fallback的类的实现:
package com.example.helloworldfeign.service; import com.example.helloworldfeign.model.HelloMessage; import org.springframework.stereotype.Component; /** * @author billjiang 475572229@qq.com * @create 17-8-28 */ @Component public class HelloServiceFallback implements HelloService { @Override public HelloMessage hello() { HelloMessage helloMessage=new HelloMessage(); helloMessage.setName("hello"); helloMessage.setMessage("error occurs"); return helloMessage; } }
world项目同上
- 测试
1)依次启动eureka server:
discovery/
trace/
hello/
world/
helloword-feing项目
2)在浏览器输入地址
http:\\localhost:8030/message,则返回正确的结果
3)停止hello项目,再次输入上述地址,则执行断路器中的方法。
查看断路器错误日志
如果要查看详细的断路器的日志,可以通过注解@FeignClient的fallbackFactory来实现,如下代码所示:
import com.example.helloworldfeign.model.HelloMessage; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; /** * @author billjiang 475572229@qq.com * @create 17-8-23 */ @FeignClient(value="hello",fallbackFactory = HelloServiceFallbackFactory.class) public interface HelloService { @GetMapping("/message") HelloMessage hello(); }
HelloServiceFallbackFactory类:
package com.example.helloworldfeign.service; import com.example.helloworldfeign.model.HelloMessage; import feign.hystrix.FallbackFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; /** * @author billjiang 475572229@qq.com * @create 17-8-28 */ @Component public class HelloServiceFallbackFactory implements FallbackFactory<HelloService> { private final static Logger LOGGER= LoggerFactory.getLogger(HelloServiceFallbackFactory.class); @Override public HelloService create(Throwable throwable) { return new HelloService() { @Override public HelloMessage hello() { //print the error LOGGER.error("fallback ,the result is:",throwable); HelloMessage helloMessage=new HelloMessage(); helloMessage.setName("hello"); helloMessage.setMessage("error occurs"); return helloMessage; } }; } }
这样会在控制台把具体导致熔断的信息输出,以便跟踪错误。
相关文章推荐
- [转]spring cloud之熔断器 Hystrix 的原理与使用
- spring cloud 使用Hystrix 实现断路器进行服务容错保护的方法
- 防雪崩利器:熔断器 Hystrix 的原理与使用
- SpringCloud 学习 | 第五篇: ribbon断路器使用(hystrix)
- 防雪崩利器:熔断器 Hystrix 的原理与使用
- 防雪崩利器:熔断器 Hystrix 的原理与使用
- 防雪崩利器:熔断器 Hystrix 的原理与使用
- 熔断器Hystrix的原理与使用
- SpringCloud 学习 | 第八篇: 断路器监控使用(Hystrix Dashboard)
- 防雪崩利器:熔断器 Hystrix 的原理与使用
- 防雪崩利器:熔断器 Hystrix 的原理与使用
- 防雪崩利器:熔断器 Hystrix 的原理与使用
- 防雪崩利器:熔断器 Hystrix 的原理与使用
- 分布式熔断、限流与服务保护:深入 Hystrix 原理及使用
- 防雪崩利器:熔断器 Hystrix 的原理与使用
- 防雪崩利器:熔断器 Hystrix 的原理与使用
- SpringCloud 学习 | 第六篇: feign断路器使用(hystrix)
- Spring cloud系列十 使用@HystrixCommand使用Hystrix组件及@EnableCircuitBreaker原理介绍
- 防雪崩利器:熔断器 Hystrix 的原理与使用
- 服务容错保护断路器Hystrix之六:缓存功能的使用