前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >响应式编程实现异步RPC,提升xxl-job调度吞吐量

响应式编程实现异步RPC,提升xxl-job调度吞吐量

作者头像
吴就业
发布2021-12-31 17:48:45
1K0
发布2021-12-31 17:48:45
举报
文章被收录于专栏:Java艺术Java艺术

在xxl-job中,RPC即用于调度中心请求执行器执行job、kill job,也用于执行器请求调度中心主动注册、执行结果上报。

xxl-job实现的RPC类似Feign框架,是基于http这种七层协议实现的,而http协议是无状态的,因此一个连接不能同时被用于多个线程发送请求,只能等待一个请求响应后再放入连接池被其它线程使用。

对于执行器而言,由于只与调度中心交互,请求量也少,因此这种RPC实现不会对执行器性能有什么影响。

调度中心则不同,它需要同时与多个执行器交互,如果同一时刻需要下发几百个执行job的请求给执行器,使用这种阻塞的RPC,意味着需要开启几百个线程,使用几百个连接发送请求,而这几百个线程都需要阻塞等待响应,Job越多,需要的线程数就会越多,对调动中心的性能影响就越大。

xxl-job即便更新到最新的2.x版本,也存在性能问题,无非就是使用了分布式锁与使用同步阻塞的RPC调用。

知道了为什么同步RPC会影响调度中心的性能,再来理解为什么异步RPC能解决这个问题的原因就容易很多。

响应式编程通过事件触发回调解决同步阻塞问题,要求整条链路上都无阻塞,即无I/O阻塞(数据库操作、网络请求响应等)。

我们重构后的新版本调度中心(xxl-job),我们使用了reactor-netty-http框架实现异步RPC,当然,我们需要解决的只是调度中心的性能问题,因此执行器是可以不用改动的、兼容旧版本的。

reactor-netty-http并非解决http这种协议的无状态问题,依然一个连接同时只能用于发送一个请求,需要等待响应后才能被用于发送其它请求。但reactor-netty-http不会创建一个线程去阻塞等待,而是通过事件轮询方式,去消费响应,释放连接回连接池。

在使用reactor-netty-http之后,我们只需要配置CPU核心数个工作线程处理向执行器发送RPC请求,reactor-netty-http在一个线程上完成请求发送后,就会继续处理其它请求发送,当轮询到某些连接收到客户端响应事件后,再处理这些响应,释放连接回连接池,调回doNext。

最终从效果上看,基于reactor-netty-http实现的RPC,类似于dubbo使用长连接实现的异步RPC。

reactor-netty-http可能会创建大量连接,但不会创建大量线程,可用使用netstat观察连接数的增长,使用jstack工具观察reactor-netty-http创建的线程数。

要解决调度的性能问题,除了异步RPC是不够的,异步RPC只能帮我们解决下发请求的阻塞问题。而且响应式编程要求整个链路上必须无阻塞。那么异步回调的事件消费也必须是异步的。

同时,我们将执行器节点信息、Job数据也完全存储在内存中,让触发->job查询->执行器查询->执行器节点查询->日记打印->调度下发整条链路都完全无阻塞。而数据的一致性,则通过分布式一致性算法保证,为了稳定以及开发简单,我们基于zookeeper实现。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-12-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java艺术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档