一光年

[SpringCloud-极简示例] 6. 添加Hystrix,拥有强大的容错机制

2019.06.20

在微服务系统中,常常是多个微服务协同完成一项或多项业务需求。一个Provider通常也可能是一个Consumer,它既接收上层的API请求也会请求其它微服务的数据。

如一个业务调用中,多个微服务的调用依赖关系是

A -> B -> C -> D。

如果因为某种原因导致D服务不可能,C发出的请求就会得不到响应,继而服务C的资源耗尽会让自身也变得不可响应。由此类推,逐渐影响到了B和A的服务可用性。这种现象被称作雪崩效应

为了避免这种情况的发生,需要设计一种容错机制,达到纠错的目的:

  1. 超时机制。当服务不可用时,要及时超时并释放相关的资源。
  2. 熔断机制。当服务不可用时,大量的请求已经没有转发的必要,可以直接返回。

本例中,我们实现Consumer和Provider之间的断路保护,当Provider变得不可用时,Consumer会进行降级处理,取得一个模拟的返回值。

demo4-framework

加入Hystrix

导入Hystrix包,如下:

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

添加@EnableHystrix

在Consumer的主程序上,添加@EnableHystrix标注使得Hystrix生效。

package com.example.springcloud.comsumer;
...

@SpringBootApplication
@EnableFeignClients
@EnableHystrix
public class WsConsumerAApplication {
	
    public static void main(String[] args) {
        SpringApplication.run(WsConsumerAApplication.class, args);
    }
}

在application.yml加入使hystrix生效的设置

...
feign:
  hystrix:
    enabled: true

加入降级处理

在前例中我们已经加入了Feign组件,SpringCloud在Feign组件中已经内置了对Hystrix功能的支持。

先添加降级处理。

package com.example.springcloud.comsumer.client;
...

/**
 * ProviderClient不可用时的降级处理
 */
@Component
public class ProviderClientFallback implements ProviderClient {

    @Override
    public Object findProductById(Long id) {
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("id", -1);
        result.put("name", "无名称");
        return result;
    }
}

在ProviderClient中,加入对该服务降级实现的引用。

package com.example.springcloud.comsumer.client;
...

@FeignClient(name="ms-provider", fallback=ProviderClientFallback.class )
public interface ProviderClient {

    @GetMapping(value="/{id}")
    public Object findProductById(@PathVariable("id") Long id);
}

确认结果

重启Consumer服务,在地址栏中输入 http://localhost:8080/product/1,可以看到服务正常返回。

{"id":1,"name":"Name-1"}

关闭Provider服务程序,再次在地址栏中输入 http://localhost:8080/product/1,可以看到服务返回的数据是降级后的返回数据:

{"name":"无名称","id":-1}