zoukankan      html  css  js  c++  java
  • Hystrix

    @HystrixCommand命令修饰的方法有2种执行方式:

    1.同步:调用其他服务等待返回结果

    2.异步:异步调用其他服务,返回Future对象,通过Future.get()获取返回结果。场景:当前服务需要调用多个其他服务然后汇总返回结果

    ---------------

    服务降级

    不用添加fallback服务降级方法的接口:

    1.该接口返回类型为void,即不是查询类操作而是写操作,当写操作失败时要告诉调用者

    2.接口执行批处理操作,报了异常不需要降级,只需要将异常返回给调用者就行

    -----------------

    命令分组、命令所属线程池

    执行Hystrix命令默认使用的线程池是按照命令所在的分组划分的,一个命令分组公用一个线程池,在注解参数中指定分组,也可以更细粒度地指定所属线程池,如果指定了线程池,它的优先级更高,命令就不会用所在分组的默认线程池

    配置方式:@HystrixCommand(fallbackMethod = "helloFallback", groupKey = "Group1", threadPoolKey = "HystrixFooServiceGaGa")

    1.当上面3个属性都不配置的时候,比如study-spring-cloud-consumer中的HystrixUserService 这个类中所有标明了@HystrixCommand标的方法,都是使用1个线程池(线程名用的是类名hystrix-HystrixUserService-1 ),而如果有HystrixUserService2,里面也有@HystrixCommand标的方法,那么执行的时候使用的是另一个线程池,所以默认就已经是线程池隔离的

    2.如果同时配置了groupKey 和 threadPoolKey ,那么具有相同的threadPoolKey的使用同一个线程池;

    3.如果只配置了groupKey ,那么具有相同的groupKey 的使用同一个线程池;比如如果配置的是@HystrixCommand(fallbackMethod = "helloFallback", groupKey = "Group1"),那么线程名就是hystrix-Group1-*

    -----------------

    请求缓存

    将命令请求获得的结果按照指定的key存储起来,key可以通过方法生成也可通过注解指定

        @CacheResult(cacheKeyMethod = "getUserCatchKey")
        @HystrixCommand
        public User getUserById(Long id) {
            return restTemplate.getForEntity("http://hello-provider/user", User.class).getBody();
        }
    
        public Long getUserCatchKey(Long id) {
            return id;
        }
    方式一:指定key生成方法
        @CacheResult
        @HystrixCommand
        public User getUserById(@CacheKey("id") Long id) {
            return restTemplate.getForEntity("http://hello-provider/user", User.class).getBody();
        }
    ---------------
        @CacheResult
        @HystrixCommand
        public User getUserById(@CacheKey("id") User user) {// 自动获取user的id属性值
            return restTemplate.getForEntity("http://hello-provider/user", User.class).getBody();
        }
    方式二:在方法参数中用@CacheKey指定

    缓存清理

        @CacheResult
        @HystrixCommand
        public User getUserById(@CacheKey("id") Long id) {
            return restTemplate.getForEntity("http://hello-provider/user", User.class).getBody();
        }
    
        @CacheRemove(commandKey = "getUserById")
        @HystrixCommand
        public int update(@CacheKey("id") User user) {
            return restTemplate.postForEntity("http://hello-provider/user",user,Integer.class).getBody();
        }
    @CacheRemove 在更新时设置缓存失效

    --------------------

    请求合并

    在延时时间窗口10ms内,对同一个接口的多次请求合并成一个请求,底层是通过将多个请求的参数进行合并,变成一个请求,只占用线程池中的一条线程,前提是被调用服务要提供批量查询接口,比如getAll(List<Stirng> ids)

    接收到回复后再做拆分响应给不同的请求

    手写合并命令稍微麻烦点,要同时实现具体命令和合并器,参考P168

    使用注解实现:

        @HystrixCollapser(batchMethod = "findAll", collapserProperties = {
                @HystrixProperty(name = "timeDelayInMilliseconds", value = "100") })
        @HystrixCommand
        public User find(Long id) {
            return null;
        }
    
        @HystrixCommand
        public List<User> findAll(List<Long> ids) {
            return restTemplate.getForEntity("http://hello-provider/users?ids={1}", List.class, StringUtils.join(ids, ","))
                    .getBody();
        }
    @HystrixCollapser

     ------------------

    是否开启请求合并

    请求合并有延迟时间窗,会造成请求延迟

    1.若请求链路本身延迟较高,可开启请求合并,时间窗的10ms延迟可忽略不计了

    2.若请求接口本身没什么并发量,不要开启

    -------------------

    仪表盘

     引入turbine构建监控聚集服务,将多个服务节点的信息进行汇总监控

    还可在turbine前加入MQ,先将服务发送的监控信息-》MQ-》turbine异步消费汇总-》DashBoard仪表盘展示

    --------------------

    整体流程:

    请求接口-》创建命令HystrixCommand-》触发命令执行-》命令结果是否被缓存-》(是,直接返回缓存结果)否-》断路器是否打开-》(是,走服务降级处理)否-》线程池是否有资源-》(否,走服务降级逻辑)是-》HystrixCommand.run()真正开始执行命令处理逻辑,调用服务提供者-》(如果超时,走服务降级逻辑)-》断路器统计命令执行情况(成功、失败、超时、拒绝)-》断路器维护10s内的统计时间窗,在此时间窗内若统计数据同时满足一下两个条件则打开断路器: “错误百分比超过50%”&&"请求总数超过20"-》断路器有5s休眠时间,5s内断路器状态是打开,期间的命令请求全部走服务降级逻辑,5s后断路器状态是半开,允许新请求进来测试服务是否恢复正常,若命令执行成功则关闭断路器,若失败进入下一个5s睡眠期

    ------------------

    配置:https://www.cnblogs.com/zhangwanhua/p/7742703.html

  • 相关阅读:
    https原理:证书传递、验证和数据加密、解密过程解析
    java web项目的https配置
    防止表单重复提交的八种简单有效的策略
    nginx.conf
    Java打war包or打jar包
    WarUtil
    MyBatis动态SQL第一篇之实现多条件查询(if、where、trim标签)
    Spring使用注解实现AOP
    Spring添加声明式事务
    spring配置文件拆分策略及方法
  • 原文地址:https://www.cnblogs.com/yfzhou528/p/13532097.html
Copyright © 2011-2022 走看看