spring-cloud(6)、熔断器 — Hystrix

  前面说过了客户端服务端调用的两种方式RibbonFeign,对于客户端调用服务端的方式是多种的,无论是什么方式,会因为各种因素导致某一次调用服务不可用,或者超时,如果因为这些因素导致客户端的调用一直在进行,这样就浪费网络和系统资源,来维持这个没有意义的请求,所以,本次介绍的是熔断器,也就是出现上述情况时,直接返回错误结果,而不重试请求,傻傻等待服务响应。

  熔断器主要作用于客户端,下面还是基于客户端Module(Client Module)来做集成,也因为我们之前有两种客户端调用服务端的方式,下面就针对两种方式来分别说明,而且针对Ribbon要对以前的代码做部分改写。

  • Ribbon调用改写

  将原来直接调用RestTemplate调用封装到一个Service内,然后在Controller里面调用Service来获取结果。抽取Service代码如下

package com.fzhsh.cloud.clent.service;

@Service
public class RibbonService {

    @Autowired
    private RestTemplate restTemplate;

    public String get() {
        return restTemplate.getForObject("http://server/home", String.class);
    }
}

  然后修改Controller调用代码,由Service接口获取结果

package com.fzhsh.cloud.clent.web;

@RestController
public class IndexController {

    @Autowired
    private RibbonService ribbonService;

    @GetMapping("/get")
    public String get(){
        return ribbonService.get();
    }
}
  • Ribbon的Hystrix使用

  首先,对于Ribbon的话需要加入依赖

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
        </dependency>

  然后,在启动主类中增加@EnableCircuitBreaker

package com.fzhsh.cloud.clent;

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@EnableCircuitBreaker
public class ClientApp {

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(ClientApp.class, args);
    }
}

  接着,改写RibbonService,增加错误时调用的方法,使用HystrixCommand加入熔断器判断,并指定调用方法

package com.fzhsh.cloud.clent.service;

@Service
public class RibbonService {

    @Autowired
    private RestTemplate restTemplate;

    @HystrixCommand(fallbackMethod = "timeout")
    public String get() {
        return restTemplate.getForObject("http://server/home", String.class);
    }

    public String timeout(){
        return "time out call";
    }
}

  最后,访问http://localhost:8080/get,结果如下

time out call
  • Feign的Hystrix的使用

  因为Feign是支持Hystrix的,所以POM中不需要增加对其依赖,但是如果需要将feign.hystrix.enabled=true,又因为CallClient是一个接口,所以需要实现该接口,做超时的默认处理。

  首先,在application.yml设置feign.hystrix.enabled=true(不同版本是有区别的

feign:
  hystrix:
    enabled: true

  接着,在启动主类中增加@EnableCircuitBreaker

package com.fzhsh.cloud.clent;

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@EnableCircuitBreaker
public class ClientApp {

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(ClientApp.class, args);
    }
}

  再接着,实现CallClient接口,并实现错误时的默认方法

package com.fzhsh.cloud.clent.service;

@Component
public class CallClientHystrix implements CallClient {
    @Override
    public String concat(@RequestParam("str")String str){
        return "time out " + str;
    }
}

  然后,在FeignClient注解指定超时调用类

package com.fzhsh.cloud.clent.service;

@FeignClient(value = "server", fallback = CallClientHystrix.class)
public interface CallClient {

    @PostMapping("/concat")
    String concat(@RequestParam("str")String str);

}

  最后,访问http://localhost:8080/concat?str=Linda,显示结果如下

time out Linda
  • 参考资料

http://cloud.spring.io/spring-cloud-static/Dalston.SR1/#_circuit_breaker_hystrix_clients

posted @ 2017-06-13 11:47  風之殤  阅读(139)  评论(0)    收藏  举报