SpringCloud>07 - Hystrix 断路器

扯淡:

服务与服务之间有业务关联就需要调用,当被调用的服务发生故障(上线后多半是由于网路原因导致连接超时),必然会波及到服务调用者。通俗讲,断路器就是在低层级的服务发生故障时将服务间的连接断开。

springboot、springcloud、docker学习目录:【传送门】 

雪崩效应:

A、B、C、D四个服务依赖关系:A~>B~>C~>D,当D服务发生故障,若此时C、D之间的连接没有断开,那么D服务会将故障传递给C服务,导致C服务也不可以访问,随着时间的推移,B、A服务都会发生故障,在复杂的系统中甚至会波及到整个系统。

断路器 Hystrix

图片、翻译均来自官网。

Netiflix 公司创建了一个已实现断路器模式名为Hystrix 的内库,在微服务架构中通常会有多层级的嵌套调用,低层级服务的失败可能串联导致到用户层次的失败。当断路器断开或者错误时,上图中的Fallback 可以由开发人员指定。题外话:Hystrix :豪猪,浑身长满刺可以保护自己,所以用作断路器的名称。

断路器的使用:

分为 常规模式 和 Feign整合的模式,一般模式本节在Ribbon中实现,一般模式也可以在Feign中使用。

常规模式:

1、新建springcloud_user_ribbon_hystrix模块

复制user_ribbon模块,改名、父子pom依赖、导入工程、修改spring.application.name启动类。

2、官网基本使用

Ribbon 中使用 Hystrix,导入依赖、添加注解、指定回退方法。

3、springcloud_user_ribbon_hystrix中添加pom依赖:

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

4、修改 RibbonController:

​@Slf4j
@RestController
@RequestMapping(value = "/ribbon")
public class RibbonController {

    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private LoadBalancerClient loadBalancerClient;

    // Hystrix 断路器
    @HystrixCommand(fallbackMethod = "getArticleFallback",
            commandProperties = { 
                @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "5000") // 超时时间默认一秒
            })
    //@HystrixCommand(fallbackMethod = "getArticleFallback")
    @GetMapping("article/{id}")
    public ApiResult getArticle(@PathVariable("id") String id) {
        ApiResult apiResult = this.restTemplate.getForObject("http://springcloud-article/article/" + id, ApiResult.class);
        return apiResult;
    }
    /**
     * Hystrix 回退方法
     * 参数和返回值要和作用的方法一致 方法名称自定义
     */
    public ApiResult getArticleFallback(String id) {
        //return /* something useful */;
        return ApiResult.ok(id);
    }
}

配置属性:

如上RibbonController中使用commandProperties 配置超时时间。

5、测试:

5.1、启动Eureka、springcloud_user_ribbon_hystrix,文章微服务。

5.2、请求:http://127.0.0.1:8081/ribbon/article/1

5.2.1、文章微服务不打断点,可正常访问。

5.2.2、打上断点,5秒(设置的超时时间)后返回:

二、Feign整合Hystrix:

1、新建springcloud_user_feign_hystrix模块:

复制user_feign模块,改名、父子pom、导入工程、修改spring.application.name、启动类。

2、官网介绍:

如果你的classpath下已经有了Hystrix,并且 feign.hystrix.enable=true ,feign 将会使用断路器包装所有的方法。禁用一个feignclient 只需要添加如上配置。

3、feign中已经包含了Hystrix,不需要引依赖。

4、修改application.yml:

# 开启feign 的断路器
feign:
  hystrix:
    enabled: true

5、修改FeignArticleClient:

​@FeignClient(name = "springcloud-article", fallback = FeignArticleClientFallback.class )
public interface FeignArticleClient {
    /**
     * 根据id查询文章信息
     * @PathVariable(value = "id") 必须指定value参数,不然报错
     */
    @RequestMapping(value = "/article/{id}",method = RequestMethod.GET)
    public ApiResult getInfo(@PathVariable(value = "id") String id);
}

6、新建FeignArticleClientFallback,实现FeignArticleClient接口:

​/**
 * @Auther: xf
 * @Date: 2018/12/24 23:30
 * @Description:  Feignclient 断路器回退
 */
@Component
public class FeignArticleClientFallback implements FeignArticleClient {
    @Override
    public ApiResult getInfo(@PathVariable(value = "id") String id) {
        return ApiResult.ok("hystrix 熔断");
    }
}

注意:@Component注解、实现自己的FeignClient接口。

7、测试:

7.1、启动Eureka、springcloud_user_feign_hystrix,文章微服务。

7.2、请求接口:http://127.0.0.1:8081/feign/findArticleById/5

7.2.1、文章微服务不打断点,可正常访问。

7.2.2、打上断点返回:

8、若需要返回熔断的异常信息:

如果你需要得到fallback被触发的原因,那么需要在@FeignClient中使用fallbackFactory属性。

8.1、新建FallbackFactory:

/**
 * @Auther: xf
 * @Date: 2018/12/24 23:45
 * @Description:  Feignclient 断路器回退  factory 获取异常信息 
 */
@Slf4j
@Component
public class FeignArticleClientFallbackFactory implements FallbackFactory<FeignArticleClient> {
    @Override
    public FeignArticleClient create(Throwable throwable) {
        return new FeignArticleClient() {
            @Override
            public ApiResult getInfo(String id) {
               // return new Hello("fallback; reason was: " + cause.getMessage());
                log.info(">throwable, {}", throwable.getMessage());
                return ApiResult.ok("fallback; reason was: " + throwable.toString() + " : "+ throwable.getMessage());
            }
        };
    }
}

8.2、修改Feignclient 使用FallbackFactory属性:

@FeignClient(name = "springcloud-article", fallbackFactory = FeignArticleClientFallbackFactory.class )
//@FeignClient(name = "springcloud-article", fallback = FeignArticleClientFallback.class )
public interface FeignArticleClient {
    /**
     * 根据id查询文章信息
     * @PathVariable(value = "id") 必须指定value参数,不然报错
     */
    @RequestMapping(value = "/article/{id}",method = RequestMethod.GET)
    public ApiResult getInfo(@PathVariable(value = "id") String id);
}

8.3、测试:

8.3.1、修改文章微服务,知道"/0" 异常:

​    @GetMapping("/{id}")
    public ApiResult getInfo(@PathVariable(value = "id") String id){
        Article article = articleService.getInfo(id);
        log.info(">>>>文章微服务>>>被调用>>>");
        int i = 1/0;
        return ApiResult.ok(article);
    }

8.3.2、启动Eureka、当前服务、文章微服务。

8.3.3、请求:http://127.0.0.1:8081/feign/findArticleById/5

控制台同样会打印出异常信息的日志,得出:fallback 回退信息中包含了异常信息。

至此,常规模式和Feign整合Hystrix模式都已实现。

代码地址:

https://gitee.com/cpla026/springcloud/tree/master/springcloud_parent/springcloud_user_ribbon_hystrix


https://gitee.com/cpla026/springcloud/tree/master/springcloud_parent/springcloud_user_feign_hystrix


个人学习分享
更多 springboot、springcloud、docker 文章,关注微信公众号吧:

猜你喜欢

转载自blog.csdn.net/cp026la/article/details/86608686
今日推荐