partysip框架優化計劃
Partysip優化計劃
先說一下服務器構成,是使用開源的partysip項目,底層協議棧用的osip。修改了裏麵的注冊服務器,在注冊服務器上,連接mysql數據庫。現在初步作了一些測試,但是感覺partysip處理過程並不滿意,測試結果如下
客戶端數量 |
客戶並發數 |
持續時間(分鍾) |
服務器狀態 |
備注 |
1 |
100 |
90 |
運行正常 |
單CPU占用為40%,注冊服務器內存消耗為24M |
1 |
200 |
12 |
不能處理數據 |
注冊服務器器無響應,mysql數據無問題 |
2 |
100 |
10 |
不能處理數據 |
注冊服務器器無響應,mysql數據無問題 |
2 |
50 |
30 |
運行正常 |
|
測試服務器的配置如下
硬件:4G memory, CPU 4核1.6GHZ,網卡:1000M雙網卡
操作係統:windows2003+sp1
測試環境:注冊服務器,mysql服務器同時運行。
總體上來說,注冊服務器並發在200/秒時(還是客戶端),隻能同時保證5000人左右在線,這個數據太不理想了。這個過程肯定和數據庫的訪問有一定的關係,因為在注冊服務器上,每有一個注冊用戶都需要首先遍曆數據庫中的表,之後根據遍曆結果,決定是把用戶記錄寫入數據庫,還是修改數據庫裏麵的記錄,同時,在返回ACK時,需要再次遍曆數據庫,找到此用戶的contect信息,並返回。訪問mysql數據庫的模塊為單線程的。
研究過partysip,osip朋友可能知道,partysip裏麵對於每個插件,都開啟一個線程,另有一個管理線程。整個處理過程是串行處理的,所以執行效率並不是很高,我知道基於以上的測試結果提出優化方案是比較草率的,我也需要更深入的測試,我也將進行更深入的測試,但是這需要我們充分了解partysip框架,隻是現在我隻是忽略了解一下,但是發現不少問題,所以,提出此優化方案,當然隨著理解的深入,測試結果的詳細,可能在很多細節上修改我的認識,但是從大的方麵來說,partysip設計並不適合做一個產品服務器(我的個人認識),因為在代碼分析中,發現了很多問題(也不能說是問題,因為partysip並沒有保證說這是一個完美的服務器,確切的講不太適合對於大並發量的數據處理),比如沒有采用內存池,線程池,基於係統級別的優化(比如完成端口,epoll),所以我想從大的方麵開始逐步優化,也需要然後逐步驗證我的設計方案是否真實有效。
1:增加buffer(cache)
主要使用方向是:對於頻繁操作數據由文件係統,轉移到內存統一管理,減少訪問磁盤I/O的次數,從而所以數據訪問時間。
主要應用點是對數據庫信息的緩存。從而減少二次訪問數據庫的時間消耗。
原理:對於數據庫中表數據進行緩存,對於注冊信息首先從此buffer中檢索,如果沒有找到再進行數據庫查詢,並把查詢結果保存到buffer表中。
適用性:主要是為了優化,數據庫訪問功能模塊,減少數據庫的訪問。從另一方麵來說,我還考慮過把訪問數據庫的功能模塊做成多線程的,並采用線程池進行管理,不過現在的首要目標可能是建立一個此buffer
2:內存池策略
目的:對內存空間的統一分配和管理,減少直接對內存的分配和銷毀的操作,較少內存碎片的產生,保障服務器長時間高效運行,要在多線程間運行,需要采用好的信號,互斥體等機製做保障,內存池策略並非內存垃圾回收策略,對於內存泄露,內存池策略無法解決。
內存池策略的概要設計
程序首次運行時,首先獲取一定容量的內存,所以其他內存內存申請,都從這個內存中獲得,當內存空間不足時,再次申請一定容量的內存。其內部實現時,可以把內存空間按大小不同的結構進行劃分,並用一張空閑分配表(鏈)進行管理,分配算法可以參考操作係統內存分配算法(最佳分配算法),關於內存分配表的建立可以參考sccot meyer《more effective C++》上麵的內存池策略,令網上有大量內存池方麵的論文可以參考。
適用性:使用partysip時,發現其所有的內存申請和內存釋放采用的函數均為osip_malloc和osip_free,而不是直接調用C中的malloc和free。osip_malloc和osip_free函數隻是對malloc和free的簡單封裝。這樣我們創建內存池策略時,隻需修改osip_malloc和osip_free函數即可,可以非常方麵應用。
3線程池
目的:增加服務器的響應時間,增大服務器的吞吐量,減少線程創建銷毀和切換的時間損失。
線程池的概要設計
基於線程池的設計,目前比較流行的有兩種1:生產者/消費者策略2:Loader/Follower策略,基於服務器特性考慮(需要並發處理大量數據)以及參考一些成功例子,決定采用2策略:L/F策略的主要方式時,程序啟動時創建一組線程,並通過一組策略來管理,其中一個線程為loader線程,此線程處於活動狀態,當有信息到來時有loader線程處理,如果此時有來一個信息,線程池中一個被掛起的線程,被喚醒,來處理這個數據,處理完成後,如果還有活動線程就掛起,否則此線程講作為loader線程,等待數據的到來,更詳細的設計,參考同目錄下的lf.pdf文檔
適用性:partysip采用為每個插件創建線程的方式,如果增加線程池,必須在數據到來的端口出,雖然有多個線程處理數據,但是由於每個插件隻有一個線程,所以在具體處理數據時也必須等待插件線程處理完畢後,再次調用,所以如果快速實現,也需要把每插件有單一線程修改為每插件線程池策略,修改這兩部分,幾乎是partysip底層流程的修改。雖然增加線程池策略是服務器提速的最好方法,但是考慮其修改的複雜性,需要仔細partysip框架以及sip協議,分析後修改。
4基於係統的優化
說明:係統的優化,主要針對操作係統所提供的高級I/O訪問功能的優化,比如windows
下的完成端口,linux下的epoll,比使用簡單的socket機製,要快很多。普通的綁定端口,監聽機製,並發總數隻有幾百個,而采用完成端口或epoll後,處理並發的數量在幾萬個左右,參考msdn上的完成端口性能測試。
簡單實現:
由於基於係統的優化是與操作係統息息相關的,不同操作係統下,具體實現方式不同,所以,為了有更好的適用性,需要提供windows下和linux下兩種機製。
適用性:根據目前掌握的資料來看,由socket機製轉換為linux下的epoll和windows下完成端口,並不是很難,本質上講完成端口或者epoll都是在socket綁定端口的基礎增加了線程池(lp策略),可以方便異步調用。因為修改涉及到partysip底層邏輯的修改,所以需要仔細分析partysip框架以及sip協議。
我知道從整體上來說,提高係統得並發數是一項非常係統的優化工作,涉及到硬件選擇,操作係統的支持,輔助工具的優化,軟件的設計等多方麵工作。因此在具體過程中,並不是簡單的通過更新硬件,更換操作係統,優化輔助工具,更改部分軟件設計就可以解決。需要係統級別的架構和設計,在具體操作過程中,隻修改一部分,並不會馬上看到優化結果,需要一個長期的測試過程。所以,基於這些考慮,服務器端的設計必須建立一個良好的設計框架之上,以及具有足夠的優化餘地。
在這裏希望各位做過基於partysip服務器的朋友,多多提建議,並且談談你們服務器在具體設計過程中碰到的問題,以及是如何解決。同時希望做過服務器的朋友,多多給我提到的優化方案提建議,談談你們做服務器時的一些心得,並且在不影響商業版權的情況,僅可能的多告知一些技術,非常感謝大家。同時也希望本文能夠對正在做partysip或者在項目中打算使用partysip的朋友提供借鑒的作用。
參考資料:
在即時通信軟件中,如何提高服務器支持的最大連接數
(https://www.linuxforum.net/forum/gshowthreaded.php?Cat=&Board=program&Number=529852&page=1&view=expanded&sb=5&o=all)
Writing Windows NT Server Applications in MFC Using I/O Completion Ports
(https://msdn2.microsoft.com/en-us/library/ms810436.aspx)
Win32 Multithreading Performance
(https://msdn2.microsoft.com/en-us/library/ms810437.aspx)
網絡的基礎架構: ACE
www.chinaunix.net上的大量文章
《UNIX網絡編程》I卷
Linux下通用線程池的構建(https://blog.csdn.net/tingya/archive/2004/12/23/226614.aspx)
微軟msn服務器設計思想初步理解
(https://blog.csdn.net/fangzhengzhu/archive/2005/01/21/262886.aspx)
高性能服務器軟件開發
The C10K problem
(https://www.kegel.com/c10k.html)
MMORPG遊戲服務器端的設計
(https://blog.csdn.net/yahle/archive/2005/01/12/250034.aspx)
線程池的介紹及簡單實現
(https://blog.csdn.net/IOKE/archive/2004/10/25/150874.aspx)
部分參考資料,參考同目錄下的pdf文件
用完成端口開發大響應規模的Winsock應用程序(1)(2)(3)(4)(5)
(https://dev.csdn.net/develop/article/15/15211.shtm)
Write Scalable Winsock Apps Using Completion Ports
(https://msdn.microsoft.com/msdnmag/issues/1000/Winsock/Winsock.asp)
Improving Runtime Performance with the Smooth Working Set Tool
(https://msdn.microsoft.com/msdnmag/issues/1000/Bugslayer/)
UDP並發服務器設計討論一:一台主機、一個CPU,實現單位時間內最大並發數
最後更新:2017-04-02 00:06:15