关于BFD(双向转发检测)开发的总结
? ? ? ?前一陣子因為業務需要,需要設備提供高可靠性(HA), ? ? ?高可靠性指的是設備出故障的時候能夠不影響業務的運行,我們部門產品的高可靠性的實現方案是雙機備份,就是一臺機器出故障的時候另一臺設備能夠接替出故障的設備繼續運行,雙機之間是主備模式。正常情況下,主設備上線運行,備設備監測主設備狀態,一旦檢測到主設備出故障,就立即切換狀態。這里就用到了BFD。
? ? ? ? ?BFD(Bidirectional Forwarding Detection,[RFC5880])全稱雙向轉發檢測協議。提供了一種鏈路之間聯通性檢測的方式,優勢是檢測速度快、另一點就是因為是標準協議,各家的方案對接起來不會太難。如果不用BFD的話,設備之間檢測時間級別是秒級,也就是主機器出故障到備機上線運行,中間有幾秒時間業務是中斷的,舉個栗子,當你和女友通電話的時候, 天空正在下雨,一個雷擊,正好擊中了附近的電信基站,這時信號中斷,等到你重新接通電話的時候,等待的時間就是切換時間。對于某些情況,損失幾秒不是太大的問題,最多就是再來一次。但是對于一些重要行業的關鍵應用,業務停擺帶來的損失巨大,比如說金融業,證券系統。BFD的好處就是它檢測的時間精度很高,一般來說都支持毫秒級,雖然協議的標準是微妙,但是對于常見的嵌入式設備,微秒的精度會給系統cpu帶來很大的壓力,所以毫秒更常見一些。
? ? ? ?BFD的協議雖然很簡單,但是對于沒有網絡協議棧實現經驗的人來說,還是有點困難的。比如我這種..
首先就是去看協議,標準的協議,反復的看。看過多遍之后就去閱讀已有的實現方案,可以在github、SourceForge?等網站找到一些。借鑒現有的實現來實現自己的BFD。最初看到一個實現是kbfd,它是在內核態實現的,并且內核版本有點老,2.6.x。我們的系統版本基于openwrt,內核3.4.39。所以就決定移植出來,中間涉及到的知識包括內核態套接字編程、內核高精度定時器hrtimer的使用、工作隊列以及延遲工作隊列等。移植不是重點,重點在于對協議棧、狀態機的實現。雖然BFD的狀態機簡單,只有三個狀態Down, Init, Up。但是狀態機的變遷管理還是很痛疼的。
? ? ? ? 但是,這樣開發出來的功能有風險。不能使用。風險?在哪。
? ? ? ?相較于用戶層層面開發,內核態的一個好處就是效率高,不用頻繁在內核態和用戶態之間通信。但是風險也大,稍微一個kernel panic,整個系統就掛了,所以決定將整個BFD在用戶層實現。這中間涉及到了Linux用戶態編程的相關知識,包括多線程、消息隊列、網絡套接字和異步通信等。這部分代碼是c完成的。產品的業務層代碼是用go寫的,因為要和其它模塊交互通信,所以學習了Go語言(順便夸一下Go語言,并發編程真的好棒!)。最終的實現就是BFD的核心功能以c庫的形式提供,Go實現封裝調用。
? ? ? ? BFD核心功能的實現框架大概是這樣一個樣子,每個會話由一個獨立線程控制,另外有一個獨立線程進行消息分發?。總體架構大概是如下這幅圖:
監聽線程的實現采用的是epoll監聽,包括定時器超時事件、套接字收發等。有消息的話就發送到對應的會話線程里的消息隊列中。而BFD會話線程的任務就是監聽自身的消息隊列,循環處理。沒有消息的話就等待。消息隊列的實現有兩種,一種是linux提供的Posix消息隊列,另一種是自定義的消息隊列,系統提供的消息隊列限制太多,例如一個進程創建的消息隊列個數有限,其次就是消息隊列的長度。所以這里采用了自定義的消息隊列,利用條件變量與互斥鎖來實現。
? ? ? ? ?關于BFD協議的開發基本上就是這個樣子,期間經歷了三次大的更改。一次是內核態實現、一次是用戶態實現最后就是CGo的方式實現。各項功能運行良好。還有就是并沒有完全實現協議里面定義的各項功能,例如加密、查詢模式、ECHO模式等。這一部分在下個版本更新中再考慮。
? ? ? ?通信協議的實現很重要的一點就是讀協議,掌握了協議內容才能夠開發。最好讀原版,大部分通信的協議RFC都是英文版。
? ? ? ?またね!
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的关于BFD(双向转发检测)开发的总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IPv6扩展头部 (一) 扩展头部格式、
- 下一篇: 钱站上征信吗(钱站上征信)