SpringCloud项目(六)Hystrix断路器
应对雪崩效应的一种微服务链路保护机制。当链路中某个微服务不可用或者响应时间,会进行服务的降级,进而熔断该节点微服务的调用。快速返回“错误”的响应信息。
服务熔断:某个服务故障或异常引起,当某个异常条件被触发,直接熔断整个服务。
服务降级:当某个服务熔断之后,服务器将不再被调用。
服务熔断和降级的作用:
生产者服务异常时,如果所有接口请求都长时间等待直到服务超时,会导致消费者服务器大量的请求等待挂起,大面积占用服务器的资源,耗死消费者服务器。这样逐级传递可能引发服务器的雪崩效应。
通过熔断和降级,当客户端发现服务异常后,后续请求不再去访问不可用的服务,而是返回客户端自己定义的缺省值。这样避免出现大量的超时等待的请求,防止了服务器被耗死。
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);
}
......
}