教程:一起学习Hystrix–Hystrix命令名称、分组、线程池

Java基础

浏览数:160

2020-7-3


目录

  • Hystrix本系列
  • 命令名称
  • 命令分组
  • 命令线程池
  • 惊喜

Hystrix本系列

     点击查看 Hystrix入门

    点击查看 Hystrix命令执行

    点击查看 Hystrix处理异常机制(降级方法)

命令名称

    默认情况下,命令名称来源于类名。

getClass().getSimpleName();

    如果要显示定义名称的话,可以通过 HystrixCommand 或者 HystrixObservableCommand 的构造函数:

    public HystrixHelloWorldCommand(String name) {
        super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("Command Group: Hello World"))
                .andCommandKey(HystrixCommandKey.Factory.asKey("Command Name: Hello World")));
        this.name = name;
    }

    为了给每个命令集合保存Setter配置,可以缓存Setter,示例如下:

    private static final Setter cachedSetter =
            Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"))
                    .andCommandKey(HystrixCommandKey.Factory.asKey("Cache Setter: Hello World"));
    public HystrixHelloWorldCommand(String name) {
        super(cachedSetter);
        this.name = name;
    }

     HystrixCommandKey 是一个接口,可以作为枚举或者普通类实现。其实它有一个辅助工厂类,示例如下:

HystrixCommandKey.Factory.asKey("Command Name: Hello World")

    HystrixCommandKey 源码如下:

public interface HystrixCommandKey extends HystrixKey {
    public static class Factory {
private static final InternMap<String, HystrixCommandKey.Factory.HystrixCommandKeyDefault> intern = new InternMap(new ValueConstructor<String, HystrixCommandKey.Factory.HystrixCommandKeyDefault>() {
            public HystrixCommandKey.Factory.HystrixCommandKeyDefault create(String key) {
                return new HystrixCommandKey.Factory.HystrixCommandKeyDefault(key);
            }
        });

        private Factory() {
        }

        public static HystrixCommandKey asKey(String name) {
            return (HystrixCommandKey)intern.interned(name);
        }

        static int getCommandCount() {
            return intern.size();
        }

        private static class HystrixCommandKeyDefault extends HystrixKeyDefault implements HystrixCommandKey {
            public HystrixCommandKeyDefault(String name) {
                super(name);
            }
        }
    }
}

点击查看源码和单元测试

命令分组

        Hystrix使用命令分组将一起的命令进行管理,比如报告、警报、仪表盘或组/库。默认情况下,Hystrix使用 HystrixCommandGroupKey 来定义命令线程池,除非单独定义线程池。

         HystrixCommandGroupKey 是一个接口,可以作为枚举或者普通类实现。其实它有一个辅助工厂类,示例如下:

HystrixCommandGroupKey.Factory.asKey("Command Group: Hello World")

         HystrixCommandGroupKey 源码如下:

public interface HystrixCommandGroupKey extends HystrixKey {
    public static class Factory {
        private static final InternMap<String, HystrixCommandGroupKey.Factory.HystrixCommandGroupDefault> intern = new InternMap(new ValueConstructor<String, HystrixCommandGroupKey.Factory.HystrixCommandGroupDefault>() {
            public HystrixCommandGroupKey.Factory.HystrixCommandGroupDefault create(String key) {
                return new HystrixCommandGroupKey.Factory.HystrixCommandGroupDefault(key);
            }
        });

        private Factory() {
        }

        public static HystrixCommandGroupKey asKey(String name) {
            return (HystrixCommandGroupKey)intern.interned(name);
        }

        static int getGroupCount() {
            return intern.size();
        }

        private static class HystrixCommandGroupDefault extends HystrixKeyDefault implements HystrixCommandGroupKey {
            public HystrixCommandGroupDefault(String name) {
                super(name);
            }
        }
    }
}

点击查看源码和单元测试

命令线程池

    线程池主要体现是用于监测、指标发布、缓存和其他此类用途的HystrixThreadPool。 一个HystrixCommand与一个单独注入到它的HystrixThreadPoolKey所检索到的HystrixThreadPool相关联, 或者默认为使用HystrixCommandGroupKey的创建一个

    如果要显示定义名称的话,可以通过 HystrixCommand 或者 HystrixObservableCommand 的构造函数:

    public HystrixHelloWorldCommand(String name) {
        super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("Command Group: Hello World"))
                .andCommandKey(HystrixCommandKey.Factory.asKey("Command Name: Hello World"))
                .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("Command ThreadPool: Hello World")));
        this.name = name;
    }

HystrixThreadPoolKey 是一个接口,可以作为枚举或者普通类实现。其实它有一个辅助工厂类,示例如下:

HystrixThreadPoolKey.Factory.asKey("Command ThreadPool: Hello World")

    HystrixThreadPoolKey 源码如下:

public interface HystrixThreadPoolKey extends HystrixKey {
    class Factory {
        private Factory() {
        }
        private static final InternMap<String, HystrixThreadPoolKey> intern
                = new InternMap<String, HystrixThreadPoolKey>(
                new InternMap.ValueConstructor<String, HystrixThreadPoolKey>() {
                    @Override
                    public HystrixThreadPoolKey create(String key) {
                        return new HystrixThreadPoolKeyDefault(key);
                    }
                });
     
        public static HystrixThreadPoolKey asKey(String name) {
           return intern.interned(name);
        }

        private static class HystrixThreadPoolKeyDefault extends HystrixKeyDefault implements HystrixThreadPoolKey {
            public HystrixThreadPoolKeyDefault(String name) {
                super(name);
            }
        }

        static int getThreadPoolCount() {
            return intern.size();
        }
    }
}

    可能使用HystrixThreadPoolKey而不仅仅是不同的HystrixCommandGroupKey的原因是多个命令可能属于相同的所有权或逻辑功能的“组”,但是某些命令可能需要彼此隔离。

    简单示例如下:

  • 访问视频元数据的两个命令
  • 两个命令拥有同一个组名称”VideoMetadata”
  • 命令 A 与资源#1 互斥
  • 命令 B 与资源#2 互斥

如果命令A的线程池潜在并且饱和,它就不应该阻止命令B访问资源,因为他们互相命中不同的后端资源。因此,我们在逻辑上希望这些命令组合在一起,但希望它们以不同的方式隔离,并使用 HystrixThreadPoolKey 来给它们每个线程池提供一个不同的线程池。

点击查看源码和单元测试

惊喜

     转帖请注明原贴地址 : https://my.oschina.net/u/2342969/blog/1816623

 

作者:java_龙