阿飞Javaer,转载请注明原创出处。 谢谢你。
前言
今天,集团的伙伴lmdfnVIVO咨询一个问题。 ' dubbo界面怎么预热? 每次在线时,都有部分超时吗?' ,如果熟悉JVM,就知道JVM重启后有一个预热过程,必须运行一定时间,其性能才能达到最佳状态; 阿里JVM团队对该缺陷进行了优化。 其特性名称:点击jwarmup、Alibaba JVM创新效应被国际社区认可出现在JVM圈顶级会议上,对jwarmup略有了解;
而且,阿里大神知道jwarmup的大致原理,即主动触发JIT编译优化,而不是等待jvm运行一段时间后自己感知。
蚂蚁大厂可以这样做,但我们的小厂肿了吗? 其实dubbo作者清爽的衬衫大神就是考虑到这种情况,在dubbo中也引入了“warmup”特性。 (与蚂蚁的jwarmup还是完全不同的),核心来源位于) com.Alibaba.dubbo.RPC.cluster.load balance
protectedintgetweight (invoker invoker,Invocation invocation ) {
先得到提供者的权重
int weight=invoker.geturl (.getmethodparameter ) invocation.getmethodname ),Constants.WEIGHT_KEY,consts
if(Weight0) {
获得提供程序的启动时间戳
long timestamp=invoker.getUrl ().getparameter (constants.remote _ timestamp _ key,0L );
if(timestamp0L ) {
//provider已运行时间
intuptime=(int ) (System.currentTimeMillis ) )- timestamp;
得到warmup的值,默认为10分钟
int warmup=invoker.geturl (.getparameter (constants.warmup _ key,Constants.DEFAULT_WARMUP ) );
//provider的执行时间短于预热时间时,需要重新计算权重(即需要降级) )。
最大时间0最大时间(if ) {
weight=calculatewarmupweight (uptime,warmup,weight );
() ) ) ) )。
() ) ) ) )。
() ) ) ) )。
返回权重;
() ) ) ) )。
staticintcalculatewarmupweight (int uptime,int warmup,int weight )。
随着provider启动时间的延长,权重逐渐提高到weight
intww=(int ) ) (float ) uptime/) (float ) warmup/(float ) weight );
return ww 1? 1:(wwWeight? 微信: ww;
() ) ) ) )。
warnup权重计算流程:
根据calculateWarmupWeight ()方法的实现,随着provider启动时间的延长,权重逐渐提高到weight,且权重的最小值为1,因此:
如果provider运行了1分钟,则weight只有10个流量,即最终应该承担的10%
如果provider运行了2分钟,则weight只有20,即最终需要承担的流量的20%
如果provider运行了5分钟,则weight只有50%,即最终应该承担的50%的流量
.
请注意,缺省情况下,dubbo有三种负载平衡实现方式:随机、轮询和一致性散列。 其中,一致性散列不受权重的影响。 也就是说,选择一致性哈希的负载均衡后,可以参考14.dubbo源代码-负载均衡进行分析,因为它不再支持dubbo的预热特性;
问题
本来,dubbo就有预热功能,为什么每次重新启动都会那么超时呢? 之后,咨询合作伙伴lmdfnVIVO。 他们的dubbo是基于dubbox的自制分支,dubbox2.8.4和dubbo原生分支的代码略有不同:
dubboxdubboabstractloadbalance.Java差异
笔者在Github上搜索dubbo更新,发现从AbstractLoadBalance.java的提交记录中有fix,记录如下。
FIXwarmuptimestamp错误
记录更改如下。
the commit
真相
原来如此,因为dubbox基于dubbo的相对旧的分支,所以该错误fix是committed on 10 Oct 2017; 所以dubbox分支的bug依然存在。
既然提到了dubbo预热问题,也可以参考另一个优化点。 dubbo官方称之为延迟暴露:
#此声明的含义是在冲刺容器启动5s后暴露dubbo服务:
或者,延迟某个接口的曝光:
验证日志如下- -显示“Dubboserviceserverstarted”,即dubbo服务启动5s后服务暴露。
[ 28/04/18053360403360593360059 CST ] maininfosupport.defaultlistablebeanfactory : pre-instantiatingsingletonsinorg.spring framework.beans.factory.supp o-test,com.Alibaba.dubbo.config.registry config,com.Alibaba.dubbo.demo.registry config,com.alibabb.dubo.con 超级英雄
[ 28/04/18053360403360593360059 CST ] maininfocontainer.main : [ dubbo ] dubbospringcontainerstarted!dubbo version: 2.0.0、current host: 127.0.0.1
[ 2018-04-2817336040336059 ] dubboserviceserverstarted!
[ 28/04/18053360413360043360004 CST ] delayexportservicethreadinfoconfig.abstract config 3360 [ dubbo ] exportdubboservicecom.Alibaba.dubbo.demo.demoservicetolocalregistry,dubbo version: 2.0.0,currenthost3360127
[ 28/04/18053360413360043360004 CST ] delayexportservicethreadinfoconfig.abstract config 3360 [ dubbo ] exportdubboservicecom.Alibaba.dubbo.demo.testservicetolocalregistry,dubbo version: 2.0.0,currenthost3360127
总结
无论是dubbo的warmup特性还是延迟暴露服务,都对生产环境有很大的帮助,所以赶紧进行以下优化吧。
对于dubbox分支或旧的dubbo分支,请修复warmup特性时间戳问题;
延迟所有dubbo服务的发布
说明:根据dubbo的参数等效转换特性,可以用-Ddubbo.provider.deplay=5000代替,但笔者跟踪源代码发现这里存在一个bug,已经提交了issue,所以syster