偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

時(shí)鐘輪在 RPC 中的應(yīng)用

開發(fā)
今天我們主要講解了時(shí)鐘輪的機(jī)制,以及時(shí)鐘輪在 RPC 框架中的應(yīng)用。

今天這篇文章介紹一下RPC中如何使用時(shí)鐘輪實(shí)現(xiàn)定時(shí)任務(wù),比如調(diào)用端的超時(shí)處理、定時(shí)心跳....

定時(shí)任務(wù)帶來了什么問題?

在講解時(shí)鐘輪之前,我們先來聊聊定時(shí)任務(wù)。相信你在開發(fā)的過程中,很多場(chǎng)景都會(huì)使用到定時(shí)任務(wù),在 RPC 框架中也有很多地方會(huì)使用到它。就以調(diào)用端請(qǐng)求超時(shí)的處理邏輯為例,下面我們看一下 RPC 框架是如果處理超時(shí)請(qǐng)求的。

在講解 Future 的時(shí)候說過:無論是同步調(diào)用還是異步調(diào)用,調(diào)用端內(nèi)部實(shí)行的都是異步,而調(diào)用端在向服務(wù)端發(fā)送消息之前會(huì)創(chuàng)建一個(gè) Future,并存儲(chǔ)這個(gè)消息標(biāo)識(shí)與這個(gè) Future 的映射,當(dāng)服務(wù)端收到消息并且處理完畢后向調(diào)用端發(fā)送響應(yīng)消息,調(diào)用端在接收到消息后會(huì)根據(jù)消息的唯一標(biāo)識(shí)找到這個(gè) Future,并將結(jié)果注入給這個(gè) Future。

那在這個(gè)過程中,如果服務(wù)端沒有及時(shí)響應(yīng)消息給調(diào)用端呢?調(diào)用端該如何處理超時(shí)的請(qǐng)求?

沒錯(cuò),就是可以利用定時(shí)任務(wù)。每次創(chuàng)建一個(gè) Future,我們都記錄這個(gè) Future 的創(chuàng)建時(shí)間與這個(gè) Future 的超時(shí)時(shí)間,并且有一個(gè)定時(shí)任務(wù)進(jìn)行檢測(cè),當(dāng)這個(gè) Future 到達(dá)超時(shí)時(shí)間并且沒有被處理時(shí),我們就對(duì)這個(gè) Future 執(zhí)行超時(shí)邏輯。

那定時(shí)任務(wù)該如何實(shí)現(xiàn)呢?

有種實(shí)現(xiàn)方式是這樣的,也是最簡(jiǎn)單的一種。每創(chuàng)建一個(gè) Future 我們都啟動(dòng)一個(gè)線程,之后 sleep,到達(dá)超時(shí)時(shí)間就觸發(fā)請(qǐng)求超時(shí)的處理邏輯。

這種方式吧,確實(shí)簡(jiǎn)單,在某些場(chǎng)景下也是可以使用的,但弊端也是顯而易見的。就像剛才我講的那個(gè) Future 超時(shí)處理的例子,如果我們面臨的是高并發(fā)的請(qǐng)求,單機(jī)每秒發(fā)送數(shù)萬(wàn)次請(qǐng)求,請(qǐng)求超時(shí)時(shí)間設(shè)置的是 5 秒,那我們要?jiǎng)?chuàng)建多少個(gè)線程用來執(zhí)行超時(shí)任務(wù)呢?超過 10 萬(wàn)個(gè)線程,這個(gè)數(shù)字真的夠嚇人了。

別急,我們還有另一種實(shí)現(xiàn)方式。我們可以用一個(gè)線程來處理所有的定時(shí)任務(wù),還以剛才那個(gè) Future 超時(shí)處理的例子為例。假設(shè)我們要啟動(dòng)一個(gè)線程,這個(gè)線程每隔 100 毫秒會(huì)掃描一遍所有的處理 Future 超時(shí)的任務(wù),當(dāng)發(fā)現(xiàn)一個(gè) Future 超時(shí)了,我們就執(zhí)行這個(gè)任務(wù),對(duì)這個(gè) Future 執(zhí)行超時(shí)邏輯。

這種方式我們用得最多,它也解決了第一種方式線程過多的問題,但其實(shí)它也有明顯的弊端。

同樣是高并發(fā)的請(qǐng)求,那么掃描任務(wù)的線程每隔 100 毫秒要掃描多少個(gè)定時(shí)任務(wù)呢?如果調(diào)用端剛好在 1 秒內(nèi)發(fā)送了 1 萬(wàn)次請(qǐng)求,這 1 萬(wàn)次請(qǐng)求要在 5 秒后才會(huì)超時(shí),那么那個(gè)掃描的線程在這個(gè) 5 秒內(nèi)就會(huì)不停地對(duì)這 1 萬(wàn)個(gè)任務(wù)進(jìn)行掃描遍歷,要額外掃描 40 多次(每 100 毫秒掃描一次,5 秒內(nèi)要掃描近 50 次),很浪費(fèi) CPU。

在我們使用定時(shí)任務(wù)時(shí),它所帶來的問題,就是讓 CPU 做了很多額外的輪詢遍歷操作,浪費(fèi)了 CPU,這種現(xiàn)象在定時(shí)任務(wù)非常多的情況下,尤其明顯。

什么是時(shí)鐘輪?

這個(gè)問題也不難解決,我們只要找到一種方式,減少額外的掃描操作就行了。比如我的一批定時(shí)任務(wù)是 5 秒之后執(zhí)行,我在 4.9 秒之后才開始掃描這批定時(shí)任務(wù),這樣就大大地節(jié)省了 CPU。這時(shí)我們就可以利用時(shí)鐘輪的機(jī)制了。

我們先來看下我們生活中用到的時(shí)鐘。

圖片

很熟悉了吧,時(shí)鐘有時(shí)針、分針和秒針,秒針跳動(dòng)一周之后,也就是跳動(dòng) 60 個(gè)刻度之后,分針跳動(dòng) 1 次,分針跳動(dòng) 60 個(gè)刻度,時(shí)針走動(dòng)一步。

而時(shí)鐘輪的實(shí)現(xiàn)原理就是參考了生活中的時(shí)鐘跳動(dòng)的原理。

圖片

在時(shí)鐘輪機(jī)制中,有時(shí)間槽和時(shí)鐘輪的概念,時(shí)間槽就相當(dāng)于時(shí)鐘的刻度,而時(shí)鐘輪就相當(dāng)于秒針與分針等跳動(dòng)的一個(gè)周期,我們會(huì)將每個(gè)任務(wù)放到對(duì)應(yīng)的時(shí)間槽位上。

時(shí)鐘輪的運(yùn)行機(jī)制和生活中的時(shí)鐘也是一樣的,每隔固定的單位時(shí)間,就會(huì)從一個(gè)時(shí)間槽位跳到下一個(gè)時(shí)間槽位,這就相當(dāng)于我們的秒針跳動(dòng)了一次;

時(shí)鐘輪可以分為多層,下一層時(shí)鐘輪中每個(gè)槽位的單位時(shí)間是當(dāng)前時(shí)間輪整個(gè)周期的時(shí)間,這就相當(dāng)于 1 分鐘等于 60 秒鐘;當(dāng)時(shí)鐘輪將一個(gè)周期的所有槽位都跳動(dòng)完之后,就會(huì)從下一層時(shí)鐘輪中取出一個(gè)槽位的任務(wù),重新分布到當(dāng)前的時(shí)鐘輪中,當(dāng)前時(shí)鐘輪則從第 0 槽位從新開始跳動(dòng),這就相當(dāng)于下一分鐘的第 1 秒。

為了方便你了解時(shí)鐘輪的運(yùn)行機(jī)制,我們用一個(gè)場(chǎng)景例子來模擬下,一起看下這個(gè)場(chǎng)景。

假設(shè)我們的時(shí)鐘輪有 10 個(gè)槽位,而時(shí)鐘輪一輪的周期是 1 秒,那么我們每個(gè)槽位的單位時(shí)間就是 100 毫秒,而下一層時(shí)間輪的周期就是 10 秒,每個(gè)槽位的單位時(shí)間也就是 1 秒,并且當(dāng)前的時(shí)鐘輪剛初始化完成,也就是第 0 跳,當(dāng)前在第 0 個(gè)槽位。

圖片

好,現(xiàn)在我們有 3 個(gè)任務(wù),分別是任務(wù) A(90 毫秒之后執(zhí)行)、任務(wù) B(610 毫秒之后執(zhí)行)與任務(wù) C(1 秒 610 毫秒之后執(zhí)行),我們將這 3 個(gè)任務(wù)添加到時(shí)鐘輪中,任務(wù) A 被放到第 0 槽位,任務(wù) B 被放到第 6 槽位,任務(wù) C 被放到下一層時(shí)間輪的第 1 槽位,如下面這張圖所示。

圖片

當(dāng)任務(wù) A 剛被放到時(shí)鐘輪,就被即刻執(zhí)行了,因?yàn)樗环诺搅说?0 槽位,而當(dāng)前時(shí)間輪正好跳到第 0 槽位(實(shí)際上還沒開始跳動(dòng),狀態(tài)為第 0 跳);600 毫秒之后,時(shí)間輪已經(jīng)進(jìn)行了 6 跳,當(dāng)前槽位是第 6 槽位,第 6 槽位所有的任務(wù)都被取出執(zhí)行;1 秒鐘之后,當(dāng)前時(shí)鐘輪的第 9 跳已經(jīng)跳完,從新開始了第 0 跳,這時(shí)下一層時(shí)鐘輪從第 0 跳跳到了第 1 跳,將第 1 槽位的任務(wù)取出,分布到當(dāng)前的時(shí)鐘輪中,這時(shí)任務(wù) C 從下一層時(shí)鐘輪中取出并放到當(dāng)前時(shí)鐘輪的第 6 槽位;1 秒 600 毫秒之后,任務(wù) C 被執(zhí)行。

圖片

看完了這個(gè)場(chǎng)景,相信你對(duì)時(shí)鐘輪的機(jī)制已經(jīng)有所了解了。在這個(gè)例子中,時(shí)鐘輪的掃描周期仍是 100 毫秒,但是其中的任務(wù)并沒有被過多的重復(fù)掃描,它完美地解決了 CPU 浪費(fèi)的問題。

這個(gè)機(jī)制其實(shí)不難理解,但實(shí)現(xiàn)起來還是很有難度的,其中要注意的問題也很多.

時(shí)鐘輪在 RPC 中的應(yīng)用

通過剛才對(duì)時(shí)鐘輪的講解,相信你可以看出,它就是用來執(zhí)行定時(shí)任務(wù)的,可以說在 RPC 框架中只要涉及到定時(shí)相關(guān)的操作,我們就可以使用時(shí)鐘輪。

那么 RPC 框架在哪些功能實(shí)現(xiàn)中會(huì)用到它呢?

剛才我舉例講到的調(diào)用端請(qǐng)求超時(shí)處理,這里我們就可以應(yīng)用到時(shí)鐘輪,我們每發(fā)一次請(qǐng)求,都創(chuàng)建一個(gè)處理請(qǐng)求超時(shí)的定時(shí)任務(wù)放到時(shí)鐘輪里,在高并發(fā)、高訪問量的情況下,時(shí)鐘輪每次只輪詢一個(gè)時(shí)間槽位中的任務(wù),這樣會(huì)節(jié)省大量的 CPU。

調(diào)用端與服務(wù)端啟動(dòng)超時(shí)也可以應(yīng)用到時(shí)鐘輪,以調(diào)用端為例,假設(shè)我們想要讓應(yīng)用可以快速地部署,例如 1 分鐘內(nèi)啟動(dòng),如果超過 1 分鐘則啟動(dòng)失敗。我們可以在調(diào)用端啟動(dòng)時(shí)創(chuàng)建一個(gè)處理啟動(dòng)超時(shí)的定時(shí)任務(wù),放到時(shí)鐘輪里。

除此之外,你還能想到 RPC 框架在哪些地方可以應(yīng)用到時(shí)鐘輪嗎?還有定時(shí)心跳。RPC 框架調(diào)用端定時(shí)向服務(wù)端發(fā)送心跳,來維護(hù)連接狀態(tài),我們可以將心跳的邏輯封裝為一個(gè)心跳任務(wù),放到時(shí)鐘輪里。

這時(shí)你可能會(huì)有一個(gè)疑問,心跳是要定時(shí)重復(fù)執(zhí)行的,而時(shí)鐘輪中的任務(wù)執(zhí)行一遍就被移除了,對(duì)于這種需要重復(fù)執(zhí)行的定時(shí)任務(wù)我們?cè)撊绾翁幚砟??在定時(shí)任務(wù)的執(zhí)行邏輯的最后,我們可以重設(shè)這個(gè)任務(wù)的執(zhí)行時(shí)間,把它重新丟回到時(shí)鐘輪里。

總結(jié)

今天我們主要講解了時(shí)鐘輪的機(jī)制,以及時(shí)鐘輪在 RPC 框架中的應(yīng)用。

這個(gè)機(jī)制很好地解決了定時(shí)任務(wù)中,因每個(gè)任務(wù)都創(chuàng)建一個(gè)線程,導(dǎo)致的創(chuàng)建過多線程的問題,以及一個(gè)線程掃描所有的定時(shí)任務(wù),讓 CPU 做了很多額外的輪詢遍歷操作而浪費(fèi) CPU 的問題。

時(shí)鐘輪的實(shí)現(xiàn)機(jī)制就是模擬現(xiàn)實(shí)生活中的時(shí)鐘,將每個(gè)定時(shí)任務(wù)放到對(duì)應(yīng)的時(shí)間槽位上,這樣可以減少掃描任務(wù)時(shí)對(duì)其它時(shí)間槽位定時(shí)任務(wù)的額外遍歷操作。

在時(shí)間輪的使用中,有些問題需要你額外注意:

  • 時(shí)間槽位的單位時(shí)間越短,時(shí)間輪觸發(fā)任務(wù)的時(shí)間就越精確。例如時(shí)間槽位的單位時(shí)間是 10 毫秒,那么執(zhí)行定時(shí)任務(wù)的時(shí)間誤差就在 10 毫秒內(nèi),如果是 100 毫秒,那么誤差就在 100 毫秒內(nèi)
  • 時(shí)間輪的槽位越多,那么一個(gè)任務(wù)被重復(fù)掃描的概率就越小,因?yàn)橹挥性诙鄬訒r(shí)鐘輪中的任務(wù)才會(huì)被重復(fù)掃描。比如一個(gè)時(shí)間輪的槽位有 1000 個(gè),一個(gè)槽位的單位時(shí)間是 10 毫秒,那么下一層時(shí)間輪的一個(gè)槽位的單位時(shí)間就是 10 秒,超過 10 秒的定時(shí)任務(wù)會(huì)被放到下一層時(shí)間輪中,也就是只有超過 10 秒的定時(shí)任務(wù)會(huì)被掃描遍歷兩次,但如果槽位是 10 個(gè),那么超過 100 毫秒的任務(wù),就會(huì)被掃描遍歷兩次。

結(jié)合這些特點(diǎn),我們就可以視具體的業(yè)務(wù)場(chǎng)景而定,對(duì)時(shí)鐘輪的周期和時(shí)間槽數(shù)進(jìn)行設(shè)置。

在 RPC 框架中,只要涉及到定時(shí)任務(wù),我們都可以應(yīng)用時(shí)鐘輪,比較典型的就是調(diào)用端的超時(shí)處理、調(diào)用端與服務(wù)端的啟動(dòng)超時(shí)以及定時(shí)心跳等等。

責(zé)任編輯:趙寧寧 來源: 碼猿技術(shù)專欄
相關(guān)推薦

2022-03-24 10:23:51

時(shí)間輪方法任務(wù)

2020-10-15 17:38:00

Time Wheel

2024-12-27 09:32:19

2009-02-27 16:22:34

AjaxProAjax.NET

2023-03-24 09:07:22

SignalsJavaScript應(yīng)用

2017-09-04 14:40:00

LimitLatchTomcat線程

2020-05-22 10:40:33

ContinuatioJS前端

2011-09-15 13:25:18

IOS應(yīng)用

2014-08-08 16:50:21

AB 測(cè)試安卓推送

2010-07-07 17:24:39

BGP協(xié)議

2011-05-18 16:02:08

XML

2021-12-07 18:35:08

物聯(lián)網(wǎng)執(zhí)法應(yīng)用IOT

2019-05-21 06:00:29

物聯(lián)網(wǎng)體育IOT

2017-10-27 16:19:23

語(yǔ)音識(shí)別CNN

2024-09-30 09:48:41

RabbitMQ消息中間件

2009-06-25 15:54:18

設(shè)計(jì)模式EJB

2010-08-09 10:21:56

XMLFlex

2011-06-23 09:14:52

CRM云計(jì)算

2010-08-03 11:07:34

NFSVMware快照

2009-02-03 10:19:45

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)