網絡負載平衡改造(續)

  昨晚, 構思了一下, 稍微寫了一些, 總結一下經驗和遇到的問題.

 

  首先, 爲了既能平衡調度各個連接, 又能保持對epoll_wait的接受, 需要額外增加一個調度線程, 而原有調用epoll_wait的線程只用於投遞請求, 請求模式依然使用LT, 這裏使用ET模式可能會引發一些不必要的BUG.

  多增加了線程, 就要更加註意防範引用到野指針的危險, 這裏對net_buff增加引用計數, 初始計數2, 當網絡錯誤, 或對端關閉時, 逐步關閉socket通信, 先關閉read信道, 等發送隊列數據全部發送完畢後, 再關閉write信道, 檢查引用計數, 當其爲0時, 清理net_buff內存, close socket fd, 從而完成了整個關閉流程.

 

  不過這裏又引發了另外一個問題, 引用計數的增減放在網絡層處理recv和send的函數內, 但是如果邏輯層, 有異步操作, 此時有可能還有請求沒有返回, 但是如果這時又要關閉連接, 勢必會造成對野指針的訪問, 從而引起服務崩潰.

 

  不過有一點我們很清楚, 邏輯層很清楚該鏈接是否可以被刪除, 因爲邏輯層可以統計到發起異步請求和響應的數量是否匹配. 爲了解決這個問題, 而能有效的隔離邏輯層對網絡層產生不必要的耦合, 採用網絡層增加一個回調函數, 在引用計數爲0, 嘗試關閉連接時, 調用該回調函數詢問邏輯層是否可以刪除該net_buff, 如果可以刪除則立即清除就好, 如果不能刪除, 則放入一個待刪隊列, 這個隊列可以用一個timer來定期輪詢, 以便後面繼續詢問邏輯層是否可以刪除.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章