赞
踩
在前面的博客中我已经将Eureka与Ribbon的使用展示了出来,但是如果将其中的某一个服务停止(Hello-Service)。你会发现Ribbon任然会去访问那个页面。
这就需要用到断路器的功能。
首先将Ribbon工程的pom文件中加入该jar包:
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
- </dependency>
再其主类工程中使用@EnableCircuitBreaker注解开启断路器功能:
- @EnableCircuitBreaker
- @EnableDiscoveryClient
- @SpringBootApplication
- public class EurekaRibbonApplication {
- @Bean
- @LoadBalanced
- RestTemplate restTemplate() {
- return new RestTemplate();
- }
-
- public static void main(String[] args) {
- SpringApplication.run(EurekaRibbonApplication.class, args);
- }
- }
也可以用@SpringCloudApplication注解来替代:
- @Target(ElementType.TYPE)
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- @Inherited
- @SpringBootApplication
- @EnableDiscoveryClient
- @EnableCircuitBreaker
- public @interface SpringCloudApplication {
- }
然后改造其服务的消费方式,新增Service层,注入RestTemplate实例。然后在其方法上添加@HystrixCommand注解来指定回调方法:
- @Service
- public class HelloService {
-
- @Autowired
- RestTemplate restTemplate;
-
- @HystrixCommand(fallbackMethod = "helloFallback")
- public String helloService() {
- ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://hello-service/hello", String.class);
- String body = responseEntity.getBody();
- return body;
- }
-
- public String helloFallback() {
- return "error";
- }
- }

Controller类改成如下:
- @RestController
- public class ConsumerController {
-
- @Autowired
- HelloService helloService;
-
- @RequestMapping("/ribbon-consumer")
- public String helloConsumer() {
- return helloService.helloService();
- }
- }
运行后:
然后中断一个服务
随后可以发现再请求http://localhost:8099/ribbon-consumer它不会再请求已经断开的服务。
除了断开服务实例来模拟节点无法访问的情况之外,我们还能模拟下服务阻塞(长时间未响应)如:
- @RestController
- public class HelloController {
-
- private final Logger logger=Logger.getLogger(getClass());
-
- @Autowired
- private DiscoveryClient client;
-
- @RequestMapping("/hello")
- public String index() throws InterruptedException {
- int sleepTime=new Random().nextInt(3000);
- logger.info("sleep:"+sleepTime);
- Thread.sleep(sleepTime);
- return "Hello";
- }
-
- }

修改Hello-Service中的服务提供者的代码,用Thread.sleep来进行模拟延时。
因为Hystrix默认的超时时间为1000毫秒,所以这里用0-3000的随机数进行了模拟,为了方便观察断路器的触发,在消费者调用函数也做了时间的记录:
- @HystrixCommand(fallbackMethod = "helloFallback")
- public String helloService() {
- long start=System.currentTimeMillis();
- ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://hello-service/hello", String.class);
- String body = responseEntity.getBody();
- long end=System.currentTimeMillis();
- logger.info("消耗时间:"+(start-end));
- return body;
- }
此时可以看到当sleep大于1000的时候它就会返回error,即服务消费者因调用服务超时从而触发熔断请求,并回调逻辑返回结果。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。