Muduo 網路編程樣本(八)用 Timing wheel 踢掉空閑串連

來源:互聯網
上載者:User

本文介紹如何使用 timing wheel 來踢掉閒置串連,一個串連如果若干秒沒有收到資料,就認為 是空閑串連。

本文的代碼見 http://code.google.com/p/muduo/source/browse/trunk/examples/idleconnection

在嚴肅的網路程式中,應用程式層的心跳協議是必不可少的。應該用心跳訊息來判斷對方進程是否能正 常工作,“踢掉空閑串連”只是一時權宜之計。我這裡想順便講講 shared_ptr 和 weak_ptr 的用法。

如果一個串連連續幾秒鐘(後文以 8s 為例)內沒有收到資料,就把它斷開,為此有兩種簡單 粗暴的做法:

每個串連儲存“最後收到資料的時間 lastReceiveTime”,然後用一個定時器,每秒鐘遍曆一遍所 有串連,斷開那些 (now - connection.lastReceiveTime) > 8s 的 connection。這種做法全域只 有一個 repeated timer,不過每次 timeout 都要檢查全部串連,如果串連數目比較大(幾千上萬), 這一步可能會比較費時。

每個串連設定一個 one-shot timer,逾時定為 8s,在逾時的時候就斷開本串連。當然,每次收到 資料要去更新 timer。這種做法需要很多個 one-shot timer,會頻繁地更新 timers。如果串連數目比 較大,可能對 reactor 的 timer queue 造成壓力。

使用 timing wheel 能避免上述兩種做法的缺點。timing wheel 可以翻譯為“時間輪盤”或“刻度 盤”,本文保留英文。

連線逾時不需要精確定時,只要大致 8 秒鐘逾時斷開就行,多一秒少一 秒關係不大。處理連線逾時可以用一個簡單的資料結構:8 個桶組成的迴圈隊列。第一個桶放下一秒將 要逾時的串連,第二個放下 2 秒將要逾時的串連。每個串連一收到資料就把自己放到第 8 個桶,然後 在每秒鐘的 callback 裡把第一個桶裡的串連斷開,把這個空桶挪到隊尾。這樣大致可以做到 8 秒鐘 沒有資料就逾時中斷連線。更重要的是,每次不用檢查全部的 connection,只要檢查第一個桶裡的 connections,相當於把任務分散了。

Timing wheel 原理

《Hashed and hierarchical timing wheels: efficient data structures for implementing a timer facility》這篇論文詳細比 較了實現定時器的各種資料結構,並提出了層次化的 timing wheel 與 hash timing wheel 等新結構 。針對本文要解決的問題的特點,我們不需要實現一個通用的定時器,只用實現 simple timing wheel 即可。

Simple timing wheel 的基本結構是一個迴圈隊列,還有一個指向隊尾的指標 (tail), 這個指標每秒鐘移動一格,就像鐘錶上的時針,timing wheel 由此得名。

以下是某一時刻 timing wheel 的狀態,格子裡的數字是倒計時(與通常的 timing wheel 相反),表示這個格子(桶 子)中的串連的剩餘壽命。

相關文章

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。