升訊威微信營銷系統開發實踐:(2)中控服務器的詳細設計( 完整開源於 Github)


GitHubhttps://github.com/iccb1013/Sheng.WeixinConstruction
因為個人精力時間有限,不會再對現有代碼進行更新維護,不過微信接口比較穩定,經測試至今沒有變化,功能依然全部可用,你可以在此基礎上,二次開發,完成你的業務功能,也可以抽取本平台中的代碼復用在你的項目中,請遵循 MIT 開源協議保留我的版權聲明和網站鏈接即可。

GitHub
https://github.com/iccb1013/Sheng.WeixinConstruction.WeixinContract
微信協議包裝的項目還有一個單獨的工程,這個工程的版本稍新,我會進行一定的更新維護,如最近增加了幾個小程序開發需要使用到的接口。但是注意因為代碼結構經過優化調整,直接引用到升訊威微信平台中,需要修改一些類的引用和名稱。

升訊威微信營銷系統開發實踐系列

升訊威微信營銷系統開發實踐:(1)功能概要與架構設計
升訊威微信營銷系統開發實踐:(2)中控服務器的詳細設計
升訊威微信營銷系統開發實踐:(3)功能介紹與此項目推廣過程的一些體會
升訊威微信營銷系統開發實踐:(4)源代碼結構說明 與 安裝部署說明

 

 


 

在上一篇文章中,簡要介紹了升訊威微信營銷系統的功能設計和架構設計,限於篇幅只能拋磚引玉,從本章節開始將圍繞功能的設計和架構的設計進行詳細的論述。

 

中控服務器的設計

在上文中,我們談到需要一個中控服務器,用來維護公眾號的AccessToken等。本節首先圍繞這個內容討論。

 

背景

微信接口調用需要首先獲取一個AccessToken進行鑒權,目前每次獲取的AccessToken有效期為2個小時,每天獲取次數限制在2000次以下。當然我們不需要如此頻繁的請求新的AccessToken,我們只需要把它存儲起來,在過期前刷新即可。

對於只為單個公眾號服務的系統,中控服務器的設計實現可以從簡,只需定時刷新AccessToken,並為應用服務器提供獲取AccessToken的接口即可。

對於直接將AccessToken寫入Redis,在我實踐過程中發現不能100%保證寫入成功,存在寫入失敗,數據沒有更新的情況,這個問題是致命的,因為一旦獲取了新的AccessToken,舊的就會很快失效,如果不能寫入成功,應用服務器繼續使用舊的AccessToken,將導致微信API調用全部失敗。

我沒有找到相關資料說明是否Redis寫入機制不保證一定成功?如果有熟悉Redis的大神請指教,謝謝。

 

對於需要同時服務於多個公眾號的系統,中控服務器的設計要稍微復雜一些。

我們現在將問題放大一些,升訊威微信營銷系統,所需要維護和管理的數據很多,其中有一些數據,如公眾號的基本信息數據、個性化設置數據、授權數據、以及各種AccessToken、Ticket等,我將之打包稱之為“公眾號上下文”。中控服務器除了維護AccessToken,更重要的作用是維護起整個公眾號上下文。

 

設計目標

概括來說中控服務器有以下幾個職責:

1)  維護鑒權所需的各種AccessToken、Ticket。

2)  維護基本信息、授權信息等基礎數據。

3)  提供一套供應用服務器使用的API,用於同步用戶的個性化設置及其它需要動態更新的數據。

4)  提供基於 TCP/IP 的接口以提高通信能力。

5)  可通過增加服務器橫向擴展以提高承載能力。

 

架構設計

這里的架構設計是針對上一篇《功能設計及架構設計》中“架構設計”環節里中控服務器部分的展開。

中控服務器的具體實現方法我想放到后面的章節中介紹,本篇專注於架構的設計。

 

中控服務器最重要的核心即“域容器”。

 

對於我們的系統來說,要提供承載多個公眾號(100000+)的能力,所以需要將不同公眾號的上下文數據組織好之后,放到一個域容器中進行維護。為什么這里叫做“域容器”而不叫做“公眾號容器”?這里為了方便論述,我對相關的設計做了簡化,實際上單個公眾號上下文是被包含在一個“域”中的,“域”除了承載公眾號上下文數據之外,還需要承載並維護其它一些數據。

中控服務器在維護公眾號上下文時,有多種架構設計方案,根據項目的技術指標,由易到難。

 

入門級

 

入門級只需要單台中控服務器即可,維護所有的公眾號上下文,通過Http Web API 接口向應用服務器提供服務。

可以適用於一般小規模服務,如果中控服務器Out of Service,需要運維團隊及時響應,重啟服務或服務器,數據可以在啟動時從緩存中恢復,但是會造成短時間的服務中斷。

 

門廳級

鑒於中控服務器的重要性,我們不能接受它出現問題,我們的目標是達到服務99.999% 以上的可用時間。

進一步的方案是對中控服務器進行冗余,使用多台服務器維護公眾號上下文並提供服務。

在此方案中,每台中控服務器所維護的數據是一致的,都是彼此的副本。

規模不大時已經適用了,可以將部分接口基於TCP/IP來實現,主要是為應用服務器提供AccessToken的接口,請求頻率會非常高。

如果系統所需要服務的公眾號數量非常多,達到數萬甚至數十萬,單台中控服務器的承載能力將受到很大影響,甚至根本不能承受,我們需要對公眾號上下文數據的維護進行拆分。

 

客廳級

在客廳級方案中,最重要的目的是拆分中控服務器對公眾號上下文的維護,使系統的整體承載能力得到提高,並使之具有橫向擴展的能力。

舉例來說中控服務器1維護第1~3000個公眾號上下文,中控服務器2維護第3001~6000個公眾號上下文。具體維護數量根據服務器配置和網絡情況,以及你的中控服務器實現質量決定。

中控服務器對公眾號上下文的維護的拆分,帶來的問題當然是應用層怎么樣才能找到指定公眾號所需的上下文數據在哪台服務器上呢?偷懶的方案是在公眾號對接時直接定死,但是這個方案很容易造成運維階段的成本浪費,因為公眾號的活躍度是不同的,有很多公眾號在對接后可能長時間處於不活動狀態。而且定死的話你雖然能通過橫向擴展增加服務的承載能力,但是沒有辦法通過增加單台服務器的配置提高既有服務器的承載能力。所以在我們的具體實現中,中控服務器對於公眾號上下文的加載和維護都是懶加載的,單台可加載數量可以根據運維期的服務器配置進行調整。

如何使應用層的服務器找到指定公眾號上下文在哪台服務器上?其實很簡單,增加一個中控服務器路由即可,這個路由服務器必須知道公眾號上下文和中控服務器的對應關系,知道它在哪里。是不是每次請求中控服務器都需要經過路由服務器去定位哪?並不需要這樣做,只需要在應用層服務器初次定位時到路由服務器上查詢即可,后續的通信直接與中控服務器進行。

 

卧室級

 

客廳級的加強版,對所有中控服務器進行一對一的冗余,以防單台故障Out Of Service。

其實這里有一個技術點是要注意的,AccessToken的同步問題,這個問題在上文的門廳級方案中也是一樣存在的,冗余的服務器之間如何確保AccessToken是同步的,當然不能各自去調用微信API刷新,后刷新的就把先刷新的沖掉了,所以需要把刷新AccessToken的工作放到中控服務器對外代理中,在其中實現一個隊列來處理這件事,並在得到新的AccessToken后,分發到中控服務器。

 

陽台級

生活不只是眼前的苟且,還有遠方的苟且等着你,慢慢來……

 

 

中控服務器的設計實現可以采取不斷演進的方式進行,可以隨着運維規模的擴大適時迭代,但是必須在前期規划設計時考慮到這些問題,特別是橫向擴展的能力。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM