当前位置: 代码迷 >> 综合 >> Spring Cloud学习|第四篇:熔断器-Hystrix
  详细解决方案

Spring Cloud学习|第四篇:熔断器-Hystrix

热度:25   发布时间:2023-11-06 04:50:56.0

目录

    • 1.Hystrix简介
    • 2.入门案例1-RestTemplate上使用熔断器
    • 3.入门案例2-Feign上使用熔断器
    • 4.Hystrix异常处理
      • 4.1 注解形式异常处理
      • 4.2 Feign调用异常处理
    • 5.参考资料

1.Hystrix简介

在分布式系统中,服务间调用关系错综复杂,则可能会存在某个或某些服务出现故障,导致依赖于它们的其它服务出现调用服务不可用而遭成线程阻塞。Hystrix提供的熔断器功能,能阻止分布式系统出现级联故障。Hystrix通过隔离服务访问点阻止联运故障,并提供了故障解决方案,从而提高整个分布式系统弹性

2.入门案例1-RestTemplate上使用熔断器

入门案例使用第二篇文章中RestTemplate和Ribbon实现负载均衡案例中改造,服务基本信息如下,注册中心在些更换为consul

服务名 端口 用途
eureka-ribbon-client 8764 ribbon客户端
eureka-client 8762 服务提供者
consul 192.168.1.100:8500 注册中心
  • eureka-ribbon-client工程引入依赖
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency>
  • 配置bootstrap.yml,注册中心配置与上篇文章配置相同,只修改端口及服务名即可,在些不赘述

  • 启动类增加@EnableHystrix

@SpringBootApplication
@EnableHystrix
@EnableDiscoveryClient
public class EurekaRibbonClientApplication {
    public static void main(String[] args) {
    SpringApplication.run(EurekaRibbonClientApplication.class, args);}@LoadBalanced@Beanpublic RestTemplate restTemplate(){
    return new RestTemplate();}
}
  • 调用方法增加@HystrixCommand

@HystrixCommand,其中fallbackMethod表示调用远程服务出现故障时将要执行的异常处理方法

@Service
public class RibbonService {
    @Resourceprivate RestTemplate restTemplate;@HystrixCommand(fallbackMethod = "hiError")public String hi(String name){
    return restTemplate.getForObject("http://eureka-client/hi?name={1}", String.class, name);}public String hiError(String name){
    return "sorroy,request user name:"+name +",has error";}
}
  • 访问http://localhost:8764/hi?name=zhangsan出现如下结果

hi zhangsan, i am from port:8762

  • 关闭eureka-client服务,再次访问http://localhost:8764/hi出现如下结果,表示Hystrix启作用

sorroy,request user name:zhangsan ,has error

3.入门案例2-Feign上使用熔断器

  • 案例结构
服务名 服务端口 作用
consul 8500 注册中心
eureka-client 8762 服务提供者
eureka-feign-client 8765 feign客户端
  • 案例依赖

由于Feign起步依赖中已经引入了hystrix依赖,依赖信息如下,因此Feign中使用Hystrix不需要额外引入依赖

<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-hystrix</artifactId>
</dependency>
<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-java8</artifactId>
</dependency>
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-ribbon</artifactId><optional>true</optional>
</dependency>
  • 配置application.yml中开启Hystrix支持
feign:hystrix:enabled: true
  • @FeignClient中配置fallback

    定义调用远程服务时处理回退信息类HiError,其中HiError必须实现@FeignClient修饰接口

@FeignClient(name = "eureka-client",fallback = HiError.class)
public interface EurekaFeignclientService {
    @GetMapping("/hi")String sayHello(@RequestParam String name);
}
  • 书写回退处理对象HiError
@Component
public class HiError implements EurekaFeignclientService {
    @Overridepublic String sayHello(String name) {
    return "sorry,your name:"+name+"has error";}
}
  • 启动服务eureka-clienteureka-feign-client,访问http://localhost:8765/feign/hi?name=lisi,出现如下信息
hi lisi, i am from port:8762
  • 关闭eureka-client,再次访问http://localhost:8765/feign/hi?name=list,出现如下信息,表示Hystrix启作用
sorry,your name:list has error

4.Hystrix异常处理

4.1 注解形式异常处理

1.注解形式异常处理,要求fallback与@HystrixCommand在同一个类中
2.方法中使用Threable获取异常

@Service
public class UserService{
    @Resourceprivate RestTemplate restTemplate;private static final Logger logger = LoggerFactory.getLogger(UserService1.class);@HystrixCommand(fallbackMethod = "defaultUser")public String getUser(String username) {
    return restTemplate.getForObject("http://provider-service/getUser", String.class, username);}public String defaultUser(String username,Throwable throwable) {
    logger.error("发生异常:{}", throwable.getMessage());return "the user:" + username + " does not exist in this system";}
}

查看错误日志如下:
在这里插入图片描述

4.2 Feign调用异常处理

  • 使用FallbackFactory方式处理异常

@FeignClient中属性使用fallbckFactory,注意不要使用成fallback否则报错

1.feign调用设置fallbackfactory

@FeignClient(name = "provider-service", fallbackFactory = UserServiceFallback.class)
public interface UserService {
    @GetMapping("/getUser")String getUser(@RequestParam("username") String username);
}

2.书写fallbackFactory实现类UserServiceFallback

@Component
public class UserServiceFallback implements FallbackFactory<UserService> {
    private static final Logger logger = LoggerFactory.getLogger(UserServiceFallback.class);@Overridepublic UserService create(Throwable throwable) {
    return new UserService() {
    @Overridepublic String getUser(String username) {
    logger.error("feign调用发生异常:{}", throwable.getMessage());return "the user" + username + " does not exist in this system,please confirm username"+throwable.getMessage();}};}
}

3.异常日志如下
在这里插入图片描述

  • feign调用异常处理还可以使用ErrorCoder处理

5.参考资料

  • 《重新定义Springcloud实战》
  • 《Springcloud微服务实战》
  • 《深入理解Spring Cloud与微服务构建》
  相关解决方案