sofastack / sofa-rpc

SOFARPC is a high-performance, high-extensibility, production-level Java RPC framework.
https://www.sofastack.tech/sofa-rpc/docs/Home
Apache License 2.0
3.83k stars 1.18k forks source link

获取预热权重算法对比疑惑 #83

Closed SteNicholas closed 6 years ago

SteNicholas commented 6 years ago

您好,获取预热权重是根据AbstractLoadBalancer类的int getWeight(providerInfo)方法从provider中或得到相关权重(默认值100),对比Dubbo目前预热权重的算法来说,代码如下:

protected int getWeight(Invoker<?> invoker, Invocation invocation) {
        int weight = invoker.getUrl().getMethodParameter(invocation.getMethodName(), Constants.WEIGHT_KEY, Constants.DEFAULT_WEIGHT);
        if (weight > 0) {
            long timestamp = invoker.getUrl().getParameter(Constants.REMOTE_TIMESTAMP_KEY, 0L);
            if (timestamp > 0L) {
                int uptime = (int) (System.currentTimeMillis() - timestamp);
                int warmup = invoker.getUrl().getParameter(Constants.WARMUP_KEY, Constants.DEFAULT_WARMUP);
                if (uptime > 0 && uptime < warmup) {
                    weight = calculateWarmupWeight(uptime, warmup, weight);
                }
            }
        }
        return weight;
    }
static int calculateWarmupWeight(int uptime, int warmup, int weight) {
        int ww = (int) ((float) uptime / ((float) warmup / (float) weight));
        return ww < 1 ? 1 : (ww > weight ? weight : ww);
    }

是不是按照Provider启动时间增长逐渐放量提高权重直到Weight的算法效果更佳?另外,服务预热时间能否按照Provider启动时间动态调整设置,因为此处没有比较官方推荐的预热时间,也不太好推荐毕竟每个接入的系统情况不一样,所以能做成动态调整设置而不是自己预估一个可接受的范围去设置?

leizhiyuan commented 6 years ago

是不是按照Provider启动时间增长逐渐放量提高权重直到Weight的算法效果更佳?

如果是衡量预热的效果,逐渐放量/不放量都能让系统代码完成预热,不过这种逐步放量的效果是会更好,这样会让流量更加平稳,欢迎提 pr

另外,服务预热时间能否按照Provider启动时间动态调整设置,因为此处没有比较官方推荐的预热时间,也不太好推荐毕竟每个接入的系统情况不一样,所以能做成动态调整设置而不是自己预估一个可接受的范围去设置?

这个现在支持动态调整的,com.alipay.sofa.rpc.bootstrap.DefaultProviderBootstrap.ProviderAttributeListener 可以看下这个类.对应用例 com.alipay.sofa.rpc.test.bootstrap.bolt.BoltProviderBootstrapTest#testAttrUpdate

当服务端收到一些动态信息的时候,是可以调整这个信息,并重新发送给客户端的.但是动态调整触发的能力,需要有分布式的资源管理/全局的配置管理中心支持入口的管理(怎么触发这个配置变更). 以 zk 为例,com.alipay.sofa.rpc.registry.zk.ZookeeperConfigObserver 这里的 todo是触发之后的变更,会在稍后完善.

预热时间要根据系统自己的能力去设置,如果之前系统启动期间的抖动时间是5s, 那么就设置为5s, 类似这样.

SteNicholas commented 6 years ago

逐步放量这块我能提交PR?com.alipay.sofa.rpc.registry.zk.ZookeeperConfigObserver 这里的 todo是触发之后的变更,能跟你们一起完善吗?

leizhiyuan commented 6 years ago

逐步放量这块可以的. 改动影响范围也比较小.直接提 pr 即可.

ZookeeperConfigObserver todo 的变更也可以的.可以开个新 issue 来讨论.

SteNicholas commented 6 years ago

感谢 @leizhiyuan 解答。我会尽快提交PR以及开个新issue讨论ZookeeperConfigObserver todo的变更

ujjboy commented 6 years ago

@SteNicholas 首先欢迎参与完善。

关于这个动态权重逐步放量的算法,建议不要每次get的时候算一下,单独启动线程完成自动计算,然后通过 ProviderInfo.setDynamicAttr(ProviderInfoAttrs.ATTR_WARMUP_WEIGHT, 20) 更新即可。

服务预热时间能否按照Provider启动时间动态调整设置?

这个如果业务服务端要启动服务预热功能,对自己的业务情况还是有一定了解的,框架直接给一个默认值更加不合适。

SteNicholas commented 6 years ago

@ujjboy 您好,我还是有点没理解为啥不要每次get的时候算下?每次get算的话完全就根据Provider启动的时间动态变更权重了呀,是不是哪里没考虑到。

ujjboy commented 6 years ago

@SteNicholas 例如预热600s,从0递增到100,那应该6s递增一次。 6s内的请求计算一次,然后设置到 ProviderInfo 里即可,而不需要6s内的所有请求都计算。

SteNicholas commented 6 years ago

@ujjboy ,Okay,那我按照这个改下代码,感谢解答。