alibaba / Sentinel

A powerful flow control component enabling reliability, resilience and monitoring for microservices. (面向云原生微服务的高可用流控防护组件)
https://sentinelguard.io/
Apache License 2.0
22.42k stars 8.03k forks source link

[Feature] Support setting the universal default rule for all resources #66

Closed evenin closed 2 years ago

evenin commented 6 years ago

据了解,目前的规则只能针对某个资源进行设置。希望提供支持全局规则设置,或资源名可通配符表达。 应用场景:所有资源默认错误率达到多少自动降级,有特殊需求的资源另外设置。

CarpenterLee commented 6 years ago

很好的建议,对减少用户规则设置的工作量有很大帮助。

我们不支持规则通配符主要有两个考虑:

全局默认降级规则的想法不错,可以再深入讨论一下,比如把全局规则存储在哪里、跟用户的规则是什么关系等等。

evenin commented 6 years ago

目前规则与统计插槽(ClusterBuilderSlot)是强关系……针对这样设计,我认为可以以这种方式实现(改动最小):复制全局规则以初始化某资源规则。经过我初步测试是可行的。以下是我修改DegradeRuleManager.checkDegrade()的代码,供参考:

/ 修改支持全局规则 - shenjian / private static final String GLOBAL = "*";

public static void checkDegrade(ResourceWrapper resource, Context context, DefaultNode node, int count) throws BlockException {
    if (degradeRules == null) {
        return;
    }
    List<DegradeRule> rules = getRules(resource.getName());
    if (rules == null) {
        return;
    }
    for (DegradeRule rule : rules) {
        if (!rule.passCheck(context, node, count)) {
            throw new DegradeException(rule.getLimitApp());
        }
    }
}

private static List<DegradeRule> getRules(String resourceName) {
    List<DegradeRule> rules = degradeRules.get(resourceName);
    if (rules != null) {
        return rules;
    }
    rules = degradeRules.get(GLOBAL);
    if (rules == null || rules.isEmpty()) {
        return null;
    }
    // 使用全局规则初始化资源规则
    rules = copyRules(rules, resourceName);
    List<DegradeRule> rules2 = degradeRules.putIfAbsent(resourceName, rules);
    if (rules2 != null && !rules2.equals(rules)) {// 没有添加成功:规则已存在
        return rules2;
    }
    return rules;
}

private static List<DegradeRule> copyRules(List<DegradeRule> rules, String newResourceName) {
    List<DegradeRule> list = new ArrayList<DegradeRule>(rules.size());
    for (DegradeRule rule : rules) {
        list.add(copyRule(rule, newResourceName));
    }
    return list;
}

private static DegradeRule copyRule(DegradeRule rule, String newResourceName) {
    DegradeRule newRule = new DegradeRule();
    newRule.setResource(newResourceName);
    newRule.setCount(rule.getCount());
    newRule.setGrade(rule.getGrade());
    newRule.setLimitApp(rule.getLimitApp());
    newRule.setTimeWindow(rule.getTimeWindow());
    return newRule;
}
CarpenterLee commented 6 years ago

It's inappropriate to set default rules in sentinel-core, instead, let some kind of sentinel-extension do this work could be considered.

lixiao1995 commented 5 years ago

我在想能不能这个降级规则加入类似于分组的这种概念,不同服务的的降级业务处理一般来说都是不同的,但是不排除存在某部分的业务他们的降级处理业务大同小异,那么它们的降级服务便可以纳入一个奖及服务分组,而这个分组的代码只需要在一处维护,不同的服务可以动态的去选择某个分组作为自己默认的服务降级处理方式,当然也是可以实现自己特有的服务降级逻辑。 也不知道这种想法现不现实、可不可行。

linlinisme commented 5 years ago

我觉得这相当于给每个资源的降级规则的加载和生效增加了层级和优先级关系。 规则加载: 1、每个资源都默认加载全局配置的降级规则。 2、每个资源有单独的用户降级规则配置。

生效规则: (1) 把加载的全局配置失效掉,只保留的单独配置。 (2) 继续保留全局配置,并且生效,但优先校验用户配置。

同时在这里我提一些关于全局配置的一些想法: 1、每个类型的全局规则配置应有且只有一个。 2、支持持久化 3、全局规则配置可存放在对应的Manager中,加一个新的静态属性标注。 4、增加一个配置开关,控制是否开启全局规则配置,兼容旧逻辑,默认是关闭状态。 5、dashboard开辟一个新的配置页面,专门配置全局规则。

如何实现: 我的理解应该是不用做在sentinel-extension里面,在对应规则的Manager里面进行管理就可以了。因为这更贴近于规则管理的范畴

sczyh30 commented 5 years ago

@linlinisme The issue title might be confusing... In this thread, we were actually discussing the universal default rule for all resources. That is, when a new resource is created, if there're no rules for this resource, then a default rule will be created and added for the resource. As soon as there are user-defined rules for this resource, the default rule will be deprecated.

The "global rule" (aka. for each type it has the only one and it represents all resources) is also useful in some scenarios. We could discuss with it (and the PR #956) in a new issue :)

linlinisme commented 5 years ago

emm.... It does not matter. We can tread it like "global default rule", We can still implement in "global manager". I think all the rules should share same "global rule", it is unnecessary to a default rule will be created and added for the resource. As soon as there are user-defined rules for this resource, the default rule will be deprecated. First we can save memory, Second We keep *RuleManager original logic.

sczyh30 commented 5 years ago

emm.... It does not matter. We can tread it like "global default rule", We can still implement in "global manager". I think all the rules should share same "global rule", it is unnecessary to a default rule will be created and added for the resource. As soon as there are user-defined rules for this resource, the default rule will be deprecated. First we can save memory, Second We keep *RuleManager original logic.

In fact, each rule may have its own additional statistic data (i.e. it's not stateless: for FlowRule it's handled in the inner TrafficController, and for DegradeRule the data is in the rule directly due to legacy design). The pure rule entity can be only single in global scope, but its relevant data should be handled separately. This should be carefully considered.

linlinisme commented 5 years ago

Thanks for reminding. Flow Rule's TrafficControllers some are stateless, some not..... What trouble is DegradeRule, it is not totally stateless . Because cut state is global share...... The design is really should be carefully considered..

linlinisme commented 5 years ago

How about this? Take downgrade as an example, We add default rule when build process chain.

  public ProcessorSlotChain build(ResourceWrapper resource) {
        ProcessorSlotChain chain = new DefaultProcessorSlotChain();
        chain.addLast(new NodeSelectorSlot());
        chain.addLast(new ClusterBuilderSlot());
        chain.addLast(new LogSlot());
        chain.addLast(new StatisticSlot());
        chain.addLast(new SystemSlot());
        chain.addLast(new AuthoritySlot());
        chain.addLast(new FlowSlot());
        chain.addLast(new DegradeSlot(resource));

        return chain;
    }
  public DegradeSlot(ResourceWrapper resource){
         DegradeRuleManager.setDefaultDegrade(resource.getName());
    }
  public static void setDefaultDegrade(String resource) {
        if (degradeRules.get(resource) == null && SentinelConfig.globalRuleOpen()) {
            Set<DegradeRule> newRules = new HashSet<>(1);
            newRules.add(createDefaultRule(resource));
            setRulesForResource(resource, newRules);
        }
    }
linlinisme commented 5 years ago

@linlinisme The issue title might be confusing... In this thread, we were actually discussing the universal default rule for all resources. That is, when a new resource is created, if there're no rules for this resource, then a default rule will be created and added for the resource. As soon as there are user-defined rules for this resource, the default rule will be deprecated.

The "global rule" (aka. for each type it has the only one and it represents all resources) is also useful in some scenarios. We could discuss with it (and the PR #956) in a new issue :)

the PR PR #956 I had closed, And I push a new PR https://github.com/alibaba/Sentinel/pull/966

anjia0532 commented 5 years ago

like hystrix.command.default.*

wangazhang commented 4 years ago

结合feign 对下游业务做限流,也很有必有有针对某一个服务的限流

jiuli commented 4 years ago

1,全局规则配置,如果对一个api资源用户自定义配置了规则优先执行这个 目前有个需求是通过gateway做路由,因为业务中需要拼装数据下载文件,使用了r4j实现熔断是针对整个服务的,改用sentinel,但发现规则不是根据api最小资源来执行优先级的,能不能api分组规则定义的是qps是1,具体api定义规则qps是3,不管是定义多少只要定义了最小资源api级别的按它来执行?

pigercc commented 4 years ago

like hystrix.command.default.*

yeah,we plan use sentinel to replace hystrix, the default hystrix settings can meet our system requirements,but find sentinel cannot set it

anjia0532 commented 4 years ago

Any progress?

zaki-liu commented 3 years ago

Any update?

ccwxl commented 3 years ago

Any update?

anjia0532 commented 3 years ago

上古贴 [捂脸] ,惊喜的发现还没有fixed

zaiym commented 2 years ago

然后呢,没有后续了? 怎么实现“全局默认降级规则”呢?

zaki-liu commented 2 years ago

你好,你的邮件我已收到。

sczyh30 commented 2 years ago

Finally resolved via #2232 and https://github.com/alibaba/Sentinel/commit/bb281042cb25533a4b97f4618a391ac0a2f6b5d6 Universal default circuit breaker rules will be supported in Sentinel 2.0.0. Cheers!

zaki-liu commented 2 years ago

你好,你的邮件我已收到。

xiangtianyu commented 1 year ago

当前只支持了全局熔断,后续会实现全局限流吗?全局限流能够用同种方式实现吗? @sczyh30 @zaki-liu

zaki-liu commented 1 year ago

你好,你的邮件我已收到。

changshang1 commented 2 months ago

全局限流能够用同种方式实现吗?大佬们

zaki-liu commented 2 months ago

你好,你的邮件我已收到。