響應(yīng)式編程實(shí)現(xiàn)異步 RPC,提升 Xxl-Job 調(diào)度吞吐量
在xxl-job中,RPC即用于調(diào)度中心請(qǐng)求執(zhí)行器執(zhí)行job、kill job,也用于執(zhí)行器請(qǐng)求調(diào)度中心主動(dòng)注冊(cè)、執(zhí)行結(jié)果上報(bào)。
xxl-job實(shí)現(xiàn)的RPC類似Feign框架,是基于http這種七層協(xié)議實(shí)現(xiàn)的,而http協(xié)議是無狀態(tài)的,因此一個(gè)連接不能同時(shí)被用于多個(gè)線程發(fā)送請(qǐng)求,只能等待一個(gè)請(qǐng)求響應(yīng)后再放入連接池被其它線程使用。
對(duì)于執(zhí)行器而言,由于只與調(diào)度中心交互,請(qǐng)求量也少,因此這種RPC實(shí)現(xiàn)不會(huì)對(duì)執(zhí)行器性能有什么影響。
調(diào)度中心則不同,它需要同時(shí)與多個(gè)執(zhí)行器交互,如果同一時(shí)刻需要下發(fā)幾百個(gè)執(zhí)行job的請(qǐng)求給執(zhí)行器,使用這種阻塞的RPC,意味著需要開啟幾百個(gè)線程,使用幾百個(gè)連接發(fā)送請(qǐng)求,而這幾百個(gè)線程都需要阻塞等待響應(yīng),Job越多,需要的線程數(shù)就會(huì)越多,對(duì)調(diào)動(dòng)中心的性能影響就越大。
xxl-job即便更新到最新的2.x版本,也存在性能問題,無非就是使用了分布式鎖與使用同步阻塞的RPC調(diào)用。
知道了為什么同步RPC會(huì)影響調(diào)度中心的性能,再來理解為什么異步RPC能解決這個(gè)問題的原因就容易很多。
響應(yīng)式編程通過事件觸發(fā)回調(diào)解決同步阻塞問題,要求整條鏈路上都無阻塞,即無I/O阻塞(數(shù)據(jù)庫操作、網(wǎng)絡(luò)請(qǐng)求響應(yīng)等)。
我們重構(gòu)后的新版本調(diào)度中心(xxl-job),我們使用了reactor-netty-http框架實(shí)現(xiàn)異步RPC,當(dāng)然,我們需要解決的只是調(diào)度中心的性能問題,因此執(zhí)行器是可以不用改動(dòng)的、兼容舊版本的。
reactor-netty-http并非解決http這種協(xié)議的無狀態(tài)問題,依然一個(gè)連接同時(shí)只能用于發(fā)送一個(gè)請(qǐng)求,需要等待響應(yīng)后才能被用于發(fā)送其它請(qǐng)求。但reactor-netty-http不會(huì)創(chuàng)建一個(gè)線程去阻塞等待,而是通過事件輪詢方式,去消費(fèi)響應(yīng),釋放連接回連接池。
在使用reactor-netty-http之后,我們只需要配置CPU核心數(shù)個(gè)工作線程處理向執(zhí)行器發(fā)送RPC請(qǐng)求,reactor-netty-http在一個(gè)線程上完成請(qǐng)求發(fā)送后,就會(huì)繼續(xù)處理其它請(qǐng)求發(fā)送,當(dāng)輪詢到某些連接收到客戶端響應(yīng)事件后,再處理這些響應(yīng),釋放連接回連接池,調(diào)回doNext。
最終從效果上看,基于reactor-netty-http實(shí)現(xiàn)的RPC,類似于dubbo使用長連接實(shí)現(xiàn)的異步RPC。
圖片
reactor-netty-http可能會(huì)創(chuàng)建大量連接,但不會(huì)創(chuàng)建大量線程,可用使用netstat觀察連接數(shù)的增長,使用jstack工具觀察reactor-netty-http創(chuàng)建的線程數(shù)。
要解決調(diào)度的性能問題,除了異步RPC是不夠的,異步RPC只能幫我們解決下發(fā)請(qǐng)求的阻塞問題。而且響應(yīng)式編程要求整個(gè)鏈路上必須無阻塞。那么異步回調(diào)的事件消費(fèi)也必須是異步的。
同時(shí),我們將執(zhí)行器節(jié)點(diǎn)信息、Job數(shù)據(jù)也完全存儲(chǔ)在內(nèi)存中,讓觸發(fā)->job查詢->執(zhí)行器查詢->執(zhí)行器節(jié)點(diǎn)查詢->日記打印->調(diào)度下發(fā)整條鏈路都完全無阻塞。而數(shù)據(jù)的一致性,則通過分布式一致性算法保證,為了穩(wěn)定以及開發(fā)簡單,我們基于zookeeper實(shí)現(xiàn)。