SpringCloud项目(六)Hystrix断路器

作者:陆金龙    发表时间:2019-08-02 11:27   

关键词:Hystrix断路器  雪崩效应  服务熔断  服务降级  FallbackFactory  

应对雪崩效应的一种微服务链路保护机制。当链路中某个微服务不可用或者响应时间,会进行服务的降级,进而熔断该节点微服务的调用。快速返回“错误”的响应信息。

 

服务熔断:某个服务故障或异常引起,当某个异常条件被触发,直接熔断整个服务。

服务降级:当某个服务熔断之后,服务器将不再被调用。

服务熔断和降级的作用:

生产者服务异常时,如果所有接口请求都长时间等待直到服务超时,会导致消费者服务器大量的请求等待挂起,大面积占用服务器的资源,耗死消费者服务器。这样逐级传递可能引发服务器的雪崩效应。

通过熔断和降级,当客户端发现服务异常后,后续请求不再去访问不可用的服务,而是返回客户端自己定义的缺省值。这样避免出现大量的超时等待的请求,防止了服务器被耗死。

3.6.1 构建带熔断器的微服务

1.创建工程

创建一个maven module工程klblog-provider-hystrix,Packaging选择jar。

2.配置pom.xml

参照klblog-provider,新加一个hystrix的依赖项

<!-- hystrix -->

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-hystrix</artifactId>

</dependency>

3.从klblog-provider复制并修改yml文件

server:

  port: 8063

eureka:

  instance:

instance-id: klblog-provider-hystrix

4.主启动类

@SpringBootApplication

@EnableEurekaClient //本服务启动后会自动注册进eureka服务中

@EnableDiscoveryClient //服务发现

@EnableCircuitBreaker//对hystrixR熔断机制的支持

public class ProviderHystrixMainApplication {

public static void main(String[] args) {

SpringApplication.run(ProviderHystrixMainApplication.class, args);

}

}

5.控制器使用

@GetMapping("/sublist/{parentId}")

@HystrixCommand(fallbackMethod = "processHystrix4SubList")

public List<Category> getSubList(@PathVariable("parentId") String parentId) {

List<Category> list = service.findByParentId(parentId);

if (null == list || list.size() == 0) {

throw new RuntimeException(parentId + "没有下级类别信息");

}

return list;

}

 

public List<Category> processHystrix4SubList(String parentId) {

List<Category> list = new ArrayList<>();

list.add(new Category().setId("null").setName(parentId + "下没有类别信息").setRemark("该微服务没有返回结果"));

return list;

}

3.6.2 consumer工程实现服务降级处理

上述待熔断器的微服务方案,存在方法膨胀问题。借鉴AOP思想,实现业务方法与异常处理解耦。

 

服务降级处理是在客户端实现的,与服务端无关。这里在klblog-consumer-feign工程上实现。

1.添加FallbackFactory

@Component // 不要忘记添加

public class FeignClientServiceFallbackFactory implements FallbackFactory<FeignClientService>{

@Override

public FeignClientService create(Throwable cause) {

//统一处理FeignClientService中各接口的异常

return new FeignClientService() {

 

@Override

public Object discovery() {

// TODO Auto-generated method stub

return null;

}

 

@Override

public List<Category> getRootList() {

return null;

}

 

@Override

public Category getById(String id) {

Category category =new Category().setId("null").setName(id + "类别不存在");

return category;

}

}

}

}

2.修改FeignClientService的注解

在@FeignClient上添加属性fallbackFactory,赋值为刚才定义的FeignClientServiceFallbackFactory类

@FeignClient(value = "KLBLOG-PROVIDER",fallbackFactory=FeignClientServiceFallbackFactory.class)

public interface FeignClientService {

@GetMapping("/category/get/{id}")

public Category getById(@PathVariable("id") String id);

    ......//其他代码

}

 

@RestController

@RequestMapping("/category")

public class CategoryConsumerController {

@Autowired

private FeignClientService service;

@GetMapping("/get/{id}")

public Category getById(@PathVariable("id") String id) {

return this.service.getById(id);

}

......

}