閱讀468 返回首頁    go 阿裏雲 go 技術社區[雲棲]


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 41.6GHZ,網卡:1000M雙網卡

操作係統:windows2003+sp1

測試環境:注冊服務器,mysql服務器同時運行。

總體上來說,注冊服務器並發在200/秒時(還是客戶端),隻能同時保證5000人左右在線,這個數據太不理想了。這個過程肯定和數據庫的訪問有一定的關係,因為在注冊服務器上,每有一個注冊用戶都需要首先遍曆數據庫中的表,之後根據遍曆結果,決定是把用戶記錄寫入數據庫,還是修改數據庫裏麵的記錄,同時,在返回ACK時,需要再次遍曆數據庫,找到此用戶的contect信息,並返回。訪問mysql數據庫的模塊為單線程的。

研究過partysiposip朋友可能知道,partysip裏麵對於每個插件,都開啟一個線程,另有一個管理線程。整個處理過程是串行處理的,所以執行效率並不是很高,我知道基於以上的測試結果提出優化方案是比較草率的,我也需要更深入的測試,我也將進行更深入的測試,但是這需要我們充分了解partysip框架,隻是現在我隻是忽略了解一下,但是發現不少問題,所以,提出此優化方案,當然隨著理解的深入,測試結果的詳細,可能在很多細節上修改我的認識,但是從大的方麵來說,partysip設計並不適合做一個產品服務器(我的個人認識),因為在代碼分析中,發現了很多問題(也不能說是問題,因為partysip並沒有保證說這是一個完美的服務器,確切的講不太適合對於大並發量的數據處理),比如沒有采用內存池,線程池,基於係統級別的優化(比如完成端口,epoll),所以我想從大的方麵開始逐步優化,也需要然後逐步驗證我的設計方案是否真實有效。

1:增加buffercache

       主要使用方向是:對於頻繁操作數據由文件係統,轉移到內存統一管理,減少訪問磁盤I/O的次數,從而所以數據訪問時間。

       主要應用點是對數據庫信息的緩存。從而減少二次訪問數據庫的時間消耗。

       原理:對於數據庫中表數據進行緩存,對於注冊信息首先從此buffer中檢索,如果沒有找到再進行數據庫查詢,並把查詢結果保存到buffer表中。

       適用性:主要是為了優化,數據庫訪問功能模塊,減少數據庫的訪問。從另一方麵來說,我還考慮過把訪問數據庫的功能模塊做成多線程的,並采用線程池進行管理,不過現在的首要目標可能是建立一個此buffer

2:內存池策略

       目的:對內存空間的統一分配和管理,減少直接對內存的分配和銷毀的操作,較少內存碎片的產生,保障服務器長時間高效運行,要在多線程間運行,需要采用好的信號,互斥體等機製做保障,內存池策略並非內存垃圾回收策略,對於內存泄露,內存池策略無法解決。

       內存池策略的概要設計

       程序首次運行時,首先獲取一定容量的內存,所以其他內存內存申請,都從這個內存中獲得,當內存空間不足時,再次申請一定容量的內存。其內部實現時,可以把內存空間按大小不同的結構進行劃分,並用一張空閑分配表(鏈)進行管理,分配算法可以參考操作係統內存分配算法(最佳分配算法),關於內存分配表的建立可以參考sccot meyermore effective C++》上麵的內存池策略,令網上有大量內存池方麵的論文可以參考。

       適用性:使用partysip時,發現其所有的內存申請和內存釋放采用的函數均為osip_mallocosip_free,而不是直接調用C中的mallocfreeosip_mallocosip_free函數隻是對mallocfree的簡單封裝。這樣我們創建內存池策略時,隻需修改osip_mallocosip_free函數即可,可以非常方麵應用。

3線程池

       目的:增加服務器的響應時間,增大服務器的吞吐量,減少線程創建銷毀和切換的時間損失。

       線程池的概要設計

       基於線程池的設計,目前比較流行的有兩種1:生產者/消費者策略2Loader/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下的epollwindows下完成端口,並不是很難,本質上講完成端口或者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,實現單位時間內最大並發數

https://www.linuxforum.net/forum/showflat.php?Cat=&Board=program&Number=599334&page=4&view=expanded&sb=9&o=all&fpart=all&vc=1

最後更新:2017-04-02 00:06:15

  上一篇:go STL學習筆記二(仿函式)
  下一篇:go 新手RoR十分鍾初體驗Step By Step