服务断路hystrix详细使用

HystrixCommand : 用在依赖的服务返回单个操作结果的时候

HystrixObservableCommand:用在依赖的服务返回多个操作结果的时候,调用Observable.from

可以传入多个命令,返回多条结果

 

 

如果于命令相关的线程池和请求队列,或者信号量(不使用线程池的时候)已经占满,那么hystrix也不会执行命令

这里hystrix 所判断的线程池并非容器的线程池,而是每个依赖服务的专有线程池

hystrix 使用舱壁模式实现线程池的隔离,它会为一个依赖服务创建一个独立的线程池,这样就算某个依赖服务出现延迟过高的情况,也只是对该依赖服务的调用产生影响,而不会拖慢其他的依赖服务

 

hystrix会将“成功”,“失败”,“超时”等信息报告给断路器,而断路器会维护一组计数器来统计这些数据

断路器会使用这些统计数据来决定是否要将断路器打开,来对某个依赖服务的请求进行“熔断/断路”,直到恢复

 

 

fallback 处理

当命令执行失败的时候,hystrix会进入fallback尝试回退处理,我们通常也称该操作为"服务降级"。而能够引起服务降级处理可能有

a 当命令处于“熔断/短路”状态,断路器是打开的时候

b 当前命令的线程池,请求队列或者信号量被占满的时候

c hystrixObservableCommand.construct或hystrixcommand.run() 抛出异常的时候

 

 

如果降级执行发现失败的时候,hystrix会根据不同的执行方法做出不同的处理

a execute() 抛出异常

b queue() 正常返回future 对象,但是当调用get()来获取结果的时候会抛出异常

c observe() 正常返回observable对象,当订阅它的时候,将立即通过调用订阅的onError()方法来通知中止请求

d toObservable() 正常返回Observable对象,当订阅它的时候,将通过调用订阅者的onError方法来通知中止请求

 

版本 spring boot 1.5.14

 

异常传播

在HystrixCommand实现run()方法中抛出异常时,除了HystrixBadRequestException之外,其他异常均会被hystrix认为命令执行失败并触发服务降级的处理逻辑,通过设置HystrixCommand 注解的ignoreExceptions 参数,可以忽略指定异常类型功能

 

@HystrixCommand(fallbackMethod = "helloFallback",ignoreExceptions = {NumberFormatException.class})

public String helloService(){

return restTemplate.getForEntity("http://HELLO-SERVICE/hello",String.class).getBody();

}

如上,当方法跑出了类型为NumberFormatException的异常时,hystrix会将它包装在HystrixBadRequestException中抛出,

这样就不会触发后续的fallback逻辑

 

 

异常获取

只需要在fallback实现方法的参数中增加Throwable e 对象的定义,这样在方法内部就可以获取触发服务降级的具体异常内容了

public String helloFallback(Throwable e){

return "error:"+e.getMessage();

}

 

 

命令名称,分组以及线程池划分

hystrix 会根据组来组织和统计命令的告警,仪表盘等信息。

如果没有特别指定threadPoolKey的情况下,会使用命令组的方式来划分线程池。

@HystrixCommand(commandKey = "helloService",

groupKey = "hellogroup",

threadPoolKey = "hellothread",

fallbackMethod = "helloFallback",

ignoreExceptions = {HystrixBadRequestException.class})

public String helloService(){

return restTemplate.getForEntity("http://HELLO-SERVICE/hello",String.class).getBody();

}

 

请求缓存

hystrix 会根据 调用依赖服务,传入的key是否相同,而决定是否使用缓存,假如调用方调用了

getUserById(long key),key 为1 ,那么会先去看是否有该key为一的缓存,有则返回,

没有则调用请求,这样就可以减少重复的请求数,降低依赖服务的并发度

 

/*

由于该方法被@CacheResult注解修改,所以hystrix会将该结果置入请求缓存中,而它的缓存Key

值会使用所以的参数,也就是这里Long类型的id值

*/

@CacheResult

@HystrixCommand

public User getUserById(Long id){

return restTemplate.getForObject("http://USER-SERVICE/users/{1}",User.class,id);

}

/*

指定缓存key

*/

@CacheResult(cacheKeyMethod = "getUserByIdCacheKey")

@HystrixCommand

public User getUserById(Long id){

return restTemplate.getForObject("http://USER-SERVICE/users/{1}",User.class,id);

}

 

private Long getUserByIdCacheKey(Long id){

return id;

}

/*

指定缓存key ,优先级比cacheKeyMethod 低

*/

@CacheResult

@HystrixCommand

public User getUserById(@CacheKey("id") Long id){

return restTemplate.getForObject("http://USER-SERVICE/users/{1}",User.class,id);

}

/*

缓存清理

当我们通过@CacheResult注解将请求结果置入hystrix的请求缓存之中,若该内容调用了更新操作,那么此时请求

缓存中的结果与实际结果会产生不一致,所有我们需要在更新操作上对失效的缓存进行清理

*/

@CacheRemove(commandKey = "getUserById")

@HystrixCommand

public void update(@CacheKey("id") User user){

restTemplate.postForObject("http://USER-SERVICE/users/{1}",user,User.class);

}

 

 

 

请求合并

在高并发的情况下,因通信次数的增加,总的通信时间消耗将会变得不那么理想。请求合并,可以将一定时间内的请求,合并起来,发起一个批量请求。例如 一定时间内所有的请求都是 查询单个用户 假设为

getUserById(String key),那么请求合并即将所有请求合并为一个批量查询 假如为getUserBatch(List<Long> ids),前提是服务提供方要提供该方法

 

@Autowired

RestTemplate restTemplate;

 

@HystrixCollapser(batchMethod = "findAll",collapserProperties = {

@HystrixProperty(name = "timerDelayInMilliseconds",value = "100")

})

public User find(Long id){

return null;

}

 

@HystrixCommand

public java.util.List<User> findAll(java.util.List<Long> ids){

return restTemplate.getForObject("http://USER-SERVICE/users?ids={1}"

,java.util.List.class,

StringUtils.join(ids,","));

}

 

 

属性

public class HystrixCommandConfiguration 记录了hystrix 基本的属性

如 command属性 execution配置

HystrixCommandExecutionConfig

 

private final int semaphoreMaxConcurrentRequests;

//执行隔离策略

private final HystrixCommandProperties.ExecutionIsolationStrategy isolationStrategy;

//超时 时是否打断

private final boolean threadInterruptOnTimeout;

private final String threadPoolKeyOverride;

//是否启用超时时间

private final boolean timeoutEnabled;

//配置hystrixcommand的超时时间

private final int timeoutInMilliseconds;

private final boolean fallbackEnabled;

private final int fallbackMaxConcurrentRequest;

private final boolean requestCacheEnabled;

private final boolean requestLogEnabled;

 

参考 spring cloud微服务实战

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值