分散式高併發IM伺服器從零架構思想 (一)
寫在前面:我寫本系列部落格的目的是自己打算研發一款基於JAVA的IM伺服器,文章用來記錄自己平時領悟到的一些設計思想,防止到開發的時候遺忘, 如對大家有幫助,同樣歡迎留言探討
(作者 孔令寬 2012年畢業於山科 從事Android原生/混合開發、前端VUE富客戶端開發、JAVA後臺開發等相關領域,目前專注於基於Netty的JAVA高併發後臺的研究)
綜述:目前我的總體設計思路已經有大體輪廓,初步迭代版本打算只實現文字聊天,後續實現圖片語音聊天,規劃支援的客戶端包括Android端、IOS端、Web端WebSocket協議支援、QT支援win和linux桌面端
1 大體分為四層服務外加多個數據儲存和叢集協調中心節點 ;
2 連線方式採用長短混合的模式 短連線使用HTTP,主要用於單點登入驗證、使用者好友關係獲取等介面 ;長連線採用TCP+自定義協議;基於Netty的Linux epoll實現單節點高連線數 。
3 應用層協議方面打算採用自定義協議,固定訊息頭+protobuf訊息體的方式
主要四大層:聯結器叢集--訊息路由業務邏輯叢集--快取叢集--DB持久層叢集
聯結器主要用來負責維持和客戶端的TCP連線
業務邏輯層主要負責訊息的轉發路由、離線訊息儲存、日誌記錄等
快取層快取臨時資料、加快讀速度
DB儲存使用者資訊、聊天記錄等
配套中心節點:單點登入節點、線上狀態儲存和檢索中心節點、叢集IP註冊和分配中心節點
單點登入節點負責使用者身份校驗、加密令牌的發放、令牌簽名合法性校驗等介面和功能
線上狀態節點負責統一儲存所有使用者的線上離線狀態、儲存使用者所連線的聯結器、給業務叢集提供檢索介面
叢集IP註冊和分配中心節點提供叢集負載均衡支援
下面是本篇的關注點:主要講解聯結器層的傳輸層通道安全、應用層身份校驗相關的設計思想,(僅為我的初步思路,感覺應該符合安全需求)
(一) 傳輸層安全設計: 為防止第三方進行重放攻擊非法訪問,防止第三方開發李鬼客戶端非法訪問伺服器,考慮在傳輸層至上增加雙向認證加密,但不使用https,去機構申請證書不現實,自簽名證書也算了 ,打算自己實現加密設計,要點如下
1 客戶端執行登入,向單點登入伺服器申請令牌,客戶端還要儲存一份事先從服務方授權獲取的非對稱金鑰對
2 客戶端建立和服務端的TCP層連線,建立後客戶端用本地私鑰加密一個隨機數連同公鑰傳送給服務端,服務端先驗證公鑰是不是授權的合法公鑰,然後用公鑰解密隨機數、解密成功則客戶端身份校驗完成;服務端像客戶端傳送公鑰;客戶端用收到的公鑰加密一個DES對稱金鑰傳輸給服務端,服務端私鑰解密出對稱金鑰並儲存,到此安全握手完成,下一步用對稱金鑰加密應用層協議資料包進行業務層通訊
3 應用層身份驗證步驟:
# 客戶端向服務端傳送從單點登入伺服器申請到的令牌;
# 服務端收到令牌後先進行本地令牌解密驗籤,然後向單點登入伺服器進行遠端令牌驗證,驗證通過後將返回的使用者資訊和令牌繫結到當前的傳輸層連線通道的狀態中去,為了支援一個傳輸層連線支援多個使用者登入(QQ手機app可以接收多個使用者的訊息,好像就是這樣的),一個連線可以繫結多個使用者;
# 服務端向線上狀態儲存和檢索中心節點發送使用者登入相關資訊來更新狀態
# 只要連線未斷,後續客戶端傳送的應用層資料包可選繼續攜帶令牌,但服務端無需再向單點登入中心進行令牌驗證,連線斷開後重連,需要重新驗證令牌
寫原創文章真累,先到這 --- 孔令寬 2018年7月28日 上午 天氣晴