Hystrix熔断

Hystrix熔断

具有服务降级(HystrixCommand注解指定/fallbackMethod回退函数实现降级逻辑),服务熔断,依赖隔离,监控的作用,防雪崩的利器

        <!--添加Hystrix依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
           <!-- <version>2.0.2.RELEASE</version>-->
        </dependency>
        <!--添加Hystrix dashboard依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
            <!-- <version>2.0.2.RELEASE</version>-->
        </dependency>
        <!--如果有了不用再引入-->
        <!--<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>-->
在主函数上添加注解
@EnableCircuitBreaker //启动Hystrix
@EnableHystrixDashboard

@HystrixCommand
如果我们使用的是@HystrixCommand注解,那么可以在注解中直接指定超时时间,如下:

@HystrixCommand(fallbackMethod="fallback",
    commandProperties = {
         @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000" )
    }
)

当然也可以指定commandKey,然后在配置文件中配置超时时间,如下:

@HystrixCommand(fallbackMethod="fallback",commandKey="userGetKey")
配置文件给commandKey配置超时时间:
hystrix.command.userGetKey.execution.isolation.thread.timeoutInMilliseconds = 13000

全局配置
如果只是想全局的配置,可以配置默认的超时时间:

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=3000

接口级别配置
假如我们的Feign Client定义如下:

@FeignClient(value = "user-service", fallbackFactory = UserRemoteClientFallbackFactory.class)
public interface UserRemoteClient {

    @GetMapping("/user/get")
    public ResponseData<UserDto> getUser(@RequestParam("id") Long id);

}

那么配置如下:

hystrix.command.UserRemoteClient#getUser(Long).execution.isolation.thread.timeoutInMilliseconds = 300

为什么要配置成上面的方式呢?

其实就是对commandKey进行配置,只要我们知道commandKey的生成规则就可以对接口级别进行配置,接口级别的规则是 Client名称#方法名(参数类型)

源码在feign.hystrix.SetterFactory.Default中:

String commandKey = Feign.configKey(target.type(), method);
服务级别配置
1.在Zuul中针对服务级别的话,直接配置service-id,如下:

hystrix.command.service-id.execution.isolation.thread.timeoutInMilliseconds=3000
Zuul中之所以要配置service-id原因是commandKey就是用的service-id, 通过源码分析可以得到结论。

首先进入的是RibbonRoutingFilter中的run方法,然后我们看核心的forward方法:

ClientHttpResponse response = forward(commandContext);
在forward中有下面的代码:

RibbonCommand command = this.ribbonCommandFactory.create(context);
通过create可以定位到具体的实现,这边就看你用的什么Http客户端,默认有三种实现,默认定位到org.springframework.cloud.netflix.zuul.filters.route.apache.HttpClientRibbonCommandFactory.create(RibbonCommandContext)方法。
所以service-id就是commandKey。

2.在Feign中针对服务级别的话,需要对commandKey进行定制,可以用service-id, 也可以用Feign Client Name,如下:

@Bean
@Scope("prototype")
@ConditionalOnMissingBean
@ConditionalOnProperty(name = "feign.hystrix.enabled")
public Feign.Builder feignHystrixBuilder() {
    return HystrixFeign.builder().setterFactory(new SetterFactory() {

        @Override
        public Setter create(Target<?> target, Method method) {
            String groupKey = target.name();
            String commandKey = Feign.configKey(target.type(), method);
            return HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(groupKey))
                        //.andCommandKey(HystrixCommandKey.Factory.asKey(commandKey))
                        //.andCommandKey(HystrixCommandKey.Factory.asKey(groupKey))
                        .andCommandKey(HystrixCommandKey.Factory.asKey(target.type().getSimpleName()));
            }
    });
}
.andCommandKey(HystrixCommandKey.Factory.asKey(commandKey))
默认的接口方式

.andCommandKey(HystrixCommandKey.Factory.asKey(groupKey))
service-id方式

.andCommandKey(HystrixCommandKey.Factory.asKey(target.type().getSimpleName()));
Feign Client Name方式

配置的话根据不同的配置填写不通的commandKey就可以了:

hystrix.command.Feign Client Name.execution.isolation.thread.timeoutInMilliseconds=3000

You must be logged in to post a comment