注:本文為轉載,原文請檢視
star7th
的個人部落格。
一、什麼是 HTQ
先介紹下基本概念。
我們在編寫程式時,偶爾會遇到需要用到非同步佇列的情況。比如說,我傳送一萬封郵件,如果單純使用一個for迴圈來傳送,則執行時間要很長,要等很久才能發完,同時很容易導致阻塞、超時等問題。當郵件更多,比如一百萬封的時候,問題會更加明顯。這時最好的解決方案就是把這十萬封郵件排隊,一一發出去。這就是任務佇列的概念。
並且,我們並不需要等到十萬封郵件都傳送完畢後才在網站前臺通知使用者。我們可以把郵件一入佇列,就通知使用者。這樣,使用者等待的時間就不是漫長的“發十萬封郵件”的時間,而是“把十萬封郵件排隊”的時間。因此能明顯地縮短了使用者等待時間。這就是非同步的概念。
HTQ ,全稱 Http Task Queue ,是一個以Http方式執行非同步任務的佇列服務。你可以推送若干url進HTQ佇列,HTQ會以Http GET 的方式訪問這些url。如果url所在的指令碼寫上各種具體的任務操作,如傳送郵件等,便可以實現非同步操作了。HTQ使用node.js編寫,可跟各種後臺語言如PHP、java配合使用以增強非同步處理能力。目前支援的佇列型別有實時非同步佇列、定時非同步佇列、可變非同步佇列。
如果你依然對HTQ陌生,則可往下看詳細的應用場景以加深瞭解。
二、應用場景
1、實時非同步佇列
所謂實時,指的是把任務一推進佇列就馬上執行。一個典型的應用場景就是我們上面所說的傳送郵件。郵件推送進任務佇列,佇列馬上把它發出去。如果它推進佇列後有其他郵件正在傳送中,它則等待當前郵件傳送完畢後才傳送。
除了發郵件,我們在發文章、發微博、發評論的時候都可以用得上HTQ的實時任務佇列,尤其是數量非常大的時候。比如評論使用者太多,如果一瞬間讓伺服器處理,伺服器可能因為支撐不了太高的併發從而造成阻塞。這個時候就可以讓評論們進入佇列再一一處理。
2、定時非同步佇列
定時,顧名思義,就是在特定的時間執行任務佇列。這種佇列服務可用於定時郵件、定時簡訊。需要說明的是,這裡的定時,不一定是精準的定時。假如你設定了明天12點執行某個任務,那麼,它在明天12點的時候將進入佇列。假如佇列中已經有任務在執行,那麼它會等待到前面的任務完畢才執行。此時可能是12點01分鐘才執行。
3、可變佇列
我們推送10個任務進佇列,這10個佇列會反覆迴圈地執行,並且它們的執行快慢能夠根據返回情況進行調整,這就是可變佇列。比如,我們做掃描監控,會反覆地執行“掃描”這個任務。我們希望,在有異常情況的時候,能加快掃描的速度以便更快速地發現問題;而在沒有長期異常的情況能減慢一下掃描速度以節省機器資源。
再舉一個場景例子,通過API拉取微博新動態。我們網站上有10萬繫結了新浪微博的使用者,我們需要時常獲取他們的最新動態以展示在我們的網站的使用者主頁上。 如果是採用定時獲取動態的方式,那麼,假設1分鐘能獲取1千個使用者的動態(因為受API使用頻率和網路等原因限制,我們獲取不了太快。這裡先假設一個數字),那麼,獲取完所有使用者狀態需要100分鐘。對使用者來說,他在微博更新動態後,100分鐘後才顯示到我們網站。這明顯滯後太多。有沒有辦法加快點呢?此時可以使用HTQ的可變佇列。可變佇列會對長期沒有更新動態的那部分不活躍使用者進行減緩速度,減緩對他們微博的獲取頻率,同時加大對活躍使用者的獲取頻率。這樣,一個活躍使用者更新微博後,可能10分鐘就能同步到我們網站了。對於不活躍使用者,可能獲取時間會變長了些,但不要緊,我們願意分配更多的資源去滿足活躍使用者的需求。
使用可變佇列,能讓我們有所側重地使用我們的資源,以減少浪費、增加利用率。