java warmup,20. dubbo源码-预热warmup过程

java warmup,20. dubbo源码-预热warmup过程阿飞 Javaer 转载请注明原创出处 谢谢 前言今天群里小伙伴黄晓峰 VIVO 咨询一个问题 dubbo 接口怎么做预热呢 每次上线 都会有一小部分超时 熟悉 JVM 都知道 JVM 重启后有一段预热过程 要运行一段时间 它的性能才能达到最佳状态 阿里 JVM 团队就针对这个缺陷进行了优化 其特性名曰 jwarmup 可以点击 AlibabaJVM 创新提效获国际社区认可登台 JVM 圈顶会 对 jwarmup 稍

阿飞Javaer,转载请注明原创出处,谢谢!

前言

今天群里小伙伴黄晓峰VIVO咨询一个问题:”dubbo接口怎么做预热呢,每次上线,都会有一小部分超时?”,熟悉JVM都知道,JVM重启后有一段预热过程,要运行一段时间,它的性能才能达到最佳状态;阿里JVM团队就针对这个缺陷进行了优化,其特性名曰:jwarmup,可以点击Alibaba JVM创新提效 获国际社区认可登台JVM圈顶会,对jwarmup稍微了解;

另外,在阿里大神你假笨那里了解到jwarmup的大概原理:针对上次JIT对应用的优化,主动去触发JIT编译优化,而不是等jvm运行一段时间自己去感知!

阿里大厂可以这么做,我们小厂肿么办?事实上dubbo作者梁飞大神考虑到了这种情况,在dubbo中也引入了”warmup”特性(和阿里的jwarmup还是完全不一样的),核心源码在”com.alibaba.dubbo.rpc.cluster.loadbalance.AbstractLoadBalance.java”中:

protected int getWeight(Invoker> invoker, Invocation invocation) {

// 先得到Provider的权重

int weight = invoker.getUrl().getMethodParameter(invocation.getMethodName(), Constants.WEIGHT_KEY, Constants.DEFAULT_WEIGHT);

if (weight > 0) {

// 得到provider的启动时间戳

long timestamp = invoker.getUrl().getParameter(Constants.REMOTE_TIMESTAMP_KEY, 0L);

if (timestamp > 0L) {

// provider已经运行时间

int uptime = (int) (System.currentTimeMillis() – timestamp);

// 得到warmup的值,默认为10分钟

int warmup = invoker.getUrl().getParameter(Constants.WARMUP_KEY, Constants.DEFAULT_WARMUP);

// provider运行时间少于预热时间,那么需要重新计算权重weight(即需要降权)

if (uptime > 0 && uptime < warmup) {

weight = calculateWarmupWeight(uptime, warmup, weight);

}

}

}

return weight;

}

static int calculateWarmupWeight(int uptime, int warmup, int weight) {

// 随着provider的启动时间越来越长,慢慢提升权重直到weight

int ww = (int) ( (float) uptime / ( (float) warmup / (float) weight ) );

return ww < 1 ? 1 : (ww > weight ? weight : ww);

}

warnup权重计算过程:

根据calculateWarmupWeight()方法实现可知,随着provider的启动时间越来越长,慢慢提升权重直到weight,且权重最小值为1,所以:

如果provider运行了1分钟,那么weight为10,即只有最终需要承担的10%流量;

如果provider运行了2分钟,那么weight为20,即只有最终需要承担的20%流量;

如果provider运行了5分钟,那么weight为50,即只有最终需要承担的50%流量;

… …

这里需要注意的是,dubbo默认有3种负载均衡实现方式:随机,轮询,一致性哈希;其中一致性哈希是不受权重影响的,也就是说,如果选择一致性哈希负载均衡,就不支持dubbo的预热特性了;可以参考14.dubbo源码-负载均衡,有对其进行分析;

问题

既然,dubbo有预热功能,为什么每次重启,还会有那么多的超时呢?后来咨询小伙伴黄晓峰VIVO,他们的dubbo是基于dubbox的自建分支,dubbox2.8.4和dubbo原生分支的代码是有一点出入的:

8e31a3f02e80

dubbox&dubbo AbstractLoadBalance.java差异性

笔者查找Github上dubbo更新,从AbstractLoadBalance.java的提交记录发现有过一次fix,记录如下:

8e31a3f02e80

Fix warmup timestamp bug

修改记录为如下所示:

8e31a3f02e80

the commit

真相

真相原来如此,由于dubbox基于dubbo比较老的分支,而这个bug fix是committed on 10 Oct 2017;所以dubbox分支的bug依然存在。

既然提到dubbo预热问题,另外一个优化点也可以参考一下,dubbo官方称之为延迟暴露:

# 这个申明的含义是等spring容器启动后过5s再暴露dubbo服务:

或者延迟暴露某个接口:

验证日志如下–可以看到”Dubbo service server started”即dubbo服务启动后,过了5s才暴露服务:

[28/04/18 05:40:59:059 CST] main INFO support.DefaultListableBeanFactory: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@6b927fb: defining beans [dubbo-test,com.alibaba.dubbo.config.RegistryConfig,com.alibaba.dubbo.config.ProviderConfig,demoService,testService,com.alibaba.dubbo.demo.DemoService,com.alibaba.dubbo.demo.TestService]; root of factory hierarchy

[28/04/18 05:40:59:059 CST] main INFO container.Main: [DUBBO] Dubbo SpringContainer started!, dubbo version: 2.0.0, current host: 127.0.0.1

[2018-04-28 17:40:59] Dubbo service server started!

[28/04/18 05:41:04:004 CST] DelayExportServiceThread INFO config.AbstractConfig: [DUBBO] Export dubbo service com.alibaba.dubbo.demo.DemoService to local registry, dubbo version: 2.0.0, current host: 127.0.0.1

[28/04/18 05:41:04:004 CST] DelayExportServiceThread INFO config.AbstractConfig: [DUBBO] Export dubbo service com.alibaba.dubbo.demo.TestService to local registry, dubbo version: 2.0.0, current host: 127.0.0.1

总结

无论是dubbo的warmup特性还是延迟暴露服务,对生产环境都有很大的帮助,所以,赶紧做如下的优化吧:

如果是dubbox分支,或者旧的dubbo分支,请修复warmup特性时间戳的问题;

配置延迟暴露所有dubbo服务;

说明:按照dubbo的参数等价转换特性,可以用-Ddubbo.provider.deplay=5000代替,但是笔者跟踪源码发现这里有个bug并已经提交了issue,请戳System property dubbo.service.delay invalid,所以目标老老实实用这种xml配置吧

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/221184.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午6:43
下一篇 2026年3月17日 下午6:44


相关推荐

  • 判断网站被搜索引擎降权

    怎么判断网站被降权了,觉得这篇文章写的很好。其实我一直觉得很多压力都是人自己给自己的,像我现在就没有压力,但我不知道为什么经理压力那么大,刚才测试自己的心理年龄,与我实际年龄一样一样的,我觉得自己变

    2021年12月25日
    38
  • telnet发电子邮件

    telnet发电子邮件

    2022年1月12日
    50
  • CSS隐藏元素五种方法

    CSS隐藏元素五种方法css 隐藏元素的方法 1 利用 opacity 透明度来隐藏 opacity 设置为 0 它只是一种视觉隐藏 元素本身依旧占用它的位置并对网页的布局起到作用 它也同样影响用户交互 在读屏软件中会被识别 2 visibility 规定元素是否可见 一般设置为 hidden 它可以很好的隐藏 不会影响用户的交互 在读屏软件中不会被识别 visibility 可能的值 visible

    2026年3月19日
    2
  • 2021 goland激活码【在线破解激活】[通俗易懂]

    2021 goland激活码【在线破解激活】,https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月15日
    78
  • 深入学习 Claude Code 的操作,高级教程

    深入学习 Claude Code 的操作,高级教程

    2026年3月15日
    2
  • sso单点登录系统实现原理(oauth2 单点登录原理)

    单点登录SSO(SingleSignOn)说得简单点就是在一个多系统共存的环境下,用户在一处登录后,就不用在其他系统中登录,也就是用户的一次登录能得到其他所有系统的信任。单点登录在大型网站里使用得非常频繁,例如像阿里巴巴这样的网站,在网站的背后是成百上千的子系统,用户一次操作或交易可能涉及到几十个子系统的协作,如果每个子系统都需要用户认证,不仅用户会疯掉,各子系统也会为这种重复认证授权的逻辑搞疯掉。实现单点登录说到底就是要解决如何产生和存储那个信任,再就是其他系统如何验证这个信任的有效性,因

    2022年4月14日
    178

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号