• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-4  評(píng)論-40  文章-117  trackbacks-0


            轉(zhuǎn)載自http://www.libing.net.cn/post/Cluster-Game-Server-development.php


             

             

             

            自從2003年開發(fā)VOIP Radius Server以及修改Gnugk依賴,從事服務(wù)器開發(fā)已經(jīng)近五年了,對(duì)服務(wù)器開發(fā)也有一些自己獨(dú)到的看法以及見解。當(dāng)擺脫了技術(shù)本身的束縛之后,才理解重要的并不是某種技術(shù)的運(yùn)用,而是整體設(shè)計(jì)的考慮,也慢慢明白了設(shè)計(jì)是開發(fā)的靈魂的道理。

            從技術(shù)層面來看,各個(gè)平臺(tái)都有一些自己特有的東西,比如Windows 平臺(tái)下面的IOCP技術(shù),可以說為了支持大的并發(fā),IOCP是一個(gè)Windows平臺(tái)的必選方案。而在Linux下面Epoll又是所有開發(fā)人員需要掌握的技術(shù)。當(dāng)然還有FreeBSD下面Kqueue的應(yīng)用了。一些其他平臺(tái)也有自己獨(dú)有的AIO庫。

            隨著網(wǎng)絡(luò)開發(fā)的進(jìn)一步理念加深,跨平臺(tái)庫也吸引了越來越多的使用者的眼光。比如行業(yè)里面最出名的莫過于ACEASIO(Boost公司)兩大支持庫。新的版本中都對(duì)IOCP支持,使用的是Proactor設(shè)計(jì)模式實(shí)現(xiàn)的。

            當(dāng)我們擁有了以上的知識(shí)背景后,我們就可以開始著手設(shè)計(jì)了。而這僅僅是一個(gè)必要條件,而不是重復(fù)條件。為什么呢?

            我們先來提一下集群式服務(wù)器開發(fā)的常用幾個(gè)技術(shù)知識(shí)。

            1:線程                    

            2:線程池

            3:內(nèi)存池

            4:數(shù)據(jù)庫連接池

            5:為了達(dá)到1:10000的連接,可以采用Server-Client的連接方式,而為了達(dá)到1:10000*100的連接,我們?cè)趺崔k呢?一般會(huì)采用Client-> ConnServer -> LogicServer。這是技術(shù)背景。ConnServer在接受完Client 的連接后,將Logic Server 暴露給Client,并立刻斷開連接。以后的數(shù)據(jù)交互就和Conn Server沒有關(guān)系了,這種架構(gòu)有很多的優(yōu)勢(shì)。

            [圖一:標(biāo)準(zhǔn)集群GameServer架構(gòu)方案]

            首先要說的是線程,在服務(wù)器開發(fā)中,線程是一個(gè)非常重要的概念,尤其是現(xiàn)在多核服務(wù)器的發(fā)展。當(dāng)然,提到了線程自然應(yīng)該說到線程之間的互斥。這也是服務(wù)器開發(fā)者們?cè)陂_發(fā)最初最容易出現(xiàn)的問題。體現(xiàn)在一個(gè)資源或者多個(gè)資源在多個(gè)線程中共享使用如何避免出現(xiàn)臟數(shù)據(jù)的問題。

                   線程池,池,顧名思義,是一個(gè)存儲(chǔ)容器,一個(gè)淺顯的比方,我們把水事先存放在水池里面,當(dāng)我們需要的時(shí)候,就去里面取,用完了就還給池(其實(shí)這里并不是非常合適的例子,畢竟我們用完了水是丟掉)。這是一個(gè)由多個(gè)線程組成的一個(gè)隊(duì)列,當(dāng)有事情發(fā)生時(shí)候,我們把當(dāng)前的空閑的線程丟給他,為他服務(wù)。當(dāng)下一個(gè)事件發(fā)生的時(shí)候,我們又從池里面取一個(gè)空閑的線程丟給他,為他服務(wù)。當(dāng)服務(wù)完畢,把線程丟回池中。起到反復(fù)利用的目的。

                   內(nèi)存池,同樣也是一個(gè)池。這個(gè)概念的產(chǎn)生是為了避免服務(wù)器頻繁的分配內(nèi)存,而采取預(yù)先分配一定數(shù)目的對(duì)象,并將對(duì)象們放到隊(duì)列中,當(dāng)需要的時(shí)候,從該隊(duì)列中取出,當(dāng)用完,就返回池中。比如我們的Server可能會(huì)存在10000個(gè)連接,我們預(yù)先開辟10000個(gè)Client對(duì)象,存儲(chǔ)在list<Client *> pFreeClientsList中,當(dāng)需要的時(shí)候,從隊(duì)列中pop一個(gè)出來,當(dāng)使用完畢就丟回pFreeClientsList。這種機(jī)制很好的起到了避免頻繁開辟內(nèi)存對(duì)象的目的,可以很好的提高系統(tǒng)的性能。

                   數(shù)據(jù)庫連接池,同上面一致的道理,在服務(wù)器中,數(shù)據(jù)庫訪問也是一個(gè)很大的瓶頸,所以同樣采取上面的道理,使用連接池的概念。當(dāng)然在數(shù)據(jù)庫連接方面也有一個(gè)特殊的問題存在。就是數(shù)據(jù)庫的連接不宜過多,所以傳統(tǒng)的來一個(gè)處理,就開一個(gè)連接是不合理的,必須采用控制適當(dāng)?shù)倪B接次數(shù)。

                   當(dāng)然另外一些需要提到的是內(nèi)存數(shù)據(jù)庫。硬盤的訪問速度和內(nèi)存的訪問速度不是一個(gè)數(shù)量級(jí)的,而且隨著內(nèi)存的硬件價(jià)格越來越低,內(nèi)存數(shù)據(jù)庫的可行性也越來越高,尤其是實(shí)時(shí)性要求高的系統(tǒng),完全可以采用內(nèi)存數(shù)據(jù)庫和物理數(shù)據(jù)庫想結(jié)合的方法來處理。

                   當(dāng)系統(tǒng)的連接數(shù)量從萬上百萬級(jí)別的時(shí)候,服務(wù)器程序就超越了服務(wù)器本身,我們需要考慮的問題將從一下幾個(gè)方面開展:

                   1:如何劃分系統(tǒng)中功能?

                   2:如何保證整個(gè)系統(tǒng)的性能可控,直觀的說就是系統(tǒng)每一步時(shí)候瓶頸在哪里?

                   3:如何保證當(dāng)系統(tǒng)的瓶頸凸顯時(shí)候,簡(jiǎn)單的添加一組服務(wù)器,就可以達(dá)到分壓目的?

                   4:系統(tǒng)的災(zāi)難部分出現(xiàn)的時(shí)候,如何保證系統(tǒng)依然可以完整運(yùn)行?

            第一個(gè)問題是如何劃分系統(tǒng)中的功能。在軟件開發(fā)中,我們追求的是每個(gè)函數(shù)功能盡量簡(jiǎn)單,易學(xué)里面的道理叫做大道至簡(jiǎn)。軟件開發(fā)中同樣適用,在服務(wù)器開發(fā)中,同樣適用。如何將整個(gè)系統(tǒng)中的需求抽象為功能,并如何更好的劃分功能,將極大減少系統(tǒng)開發(fā)的難度,并能夠使得系統(tǒng)的可擴(kuò)展性非常強(qiáng)。

            第二個(gè)問題是瓶頸問題。從物理上面來分析,性能在硬盤,內(nèi)存,CPU是三個(gè)決定因素的地方。而從軟件的角度就包含了數(shù)據(jù)庫系統(tǒng),操作系統(tǒng),服務(wù)器軟件系統(tǒng)三個(gè)方面,更細(xì)節(jié)方面拿游戲服務(wù)器來說,Conn Server 的壓力,Logic Server的壓力,還是DB Server的壓力了。

            第三個(gè)問題還體現(xiàn)在分組方面。比如當(dāng)Conn Server出現(xiàn)壓力的時(shí)候,如何簡(jiǎn)單的添加一個(gè)Conn Server就達(dá)到分壓目的。當(dāng)Logic Server出現(xiàn)壓力,或者DB Server出現(xiàn)壓力。另外就是如果服務(wù)器設(shè)計(jì)以組的方式出現(xiàn),應(yīng)該如何管理組以達(dá)到分壓目的。

            第四個(gè)問題是災(zāi)難恢復(fù)。在重要的系統(tǒng)中,由于涉及到的系統(tǒng)、硬件、軟件非常多,很容易某個(gè)系統(tǒng)出現(xiàn)故障,這個(gè)時(shí)候,系統(tǒng)應(yīng)該具有很好的伸縮性,故障出現(xiàn)后,系統(tǒng)必須依然運(yùn)行順利。

                   所以在設(shè)計(jì)服務(wù)器時(shí)候,應(yīng)該考慮上面的因素。下面我提出在集群服務(wù)器開發(fā)中的兩種可行的方案。



            [圖二:基于功能劃分的集群GameServer架構(gòu)]

             

            [圖三:組劃分的集群服務(wù)器架構(gòu)]

             

            在圖二中,系統(tǒng)按照功能方式劃分系統(tǒng),當(dāng)壓力增加的時(shí)候,按照功能方式添加某服務(wù)器,可以簡(jiǎn)單的達(dá)到分壓的目的。在Conn Server中保存所有有效Hall Server的連接,以及當(dāng)前該Hall Server的當(dāng)前連接數(shù)。代碼示意如下:

            class THallServer 

            {

            public:

                   THallServer();

                   virtual ~THallServer();

                   THallServer(int port);

             

            public:

                   SOCKET _hallServer; //保持同HallServer連接的Socket對(duì)象

                   int _maxConn; //HallServer的最大連接數(shù)量

                   int _currentConn; //當(dāng)前連接數(shù)量

                   int GetCurrentConn();

                   char _hallServerAddr[32];

                   int _hallServerPort;

             

            };

             

            class THallServerList 

            {

            public:

                   THallServerList();

                   virtual ~THallServerList();

                  

            public:

                   list<THallServer *> pHallServerList;

                   SOCKET _listenHallServer;

                   HANDLE ListenThread;

             

            public:

                   void Start();

                   THallServerList(int port);

                   //Accept線程

                   static unsigned __stdcall ListenThreadFunc(LPVOID lpVoid);

            };

             

            上面的代碼是該設(shè)計(jì)方案的類代碼。從代碼中我們可以理解出思想如下:

                   Conn Server里面存在一個(gè)THallServerList對(duì)象,該對(duì)象監(jiān)聽端口,當(dāng)有HallServer連接過來,將該HallServer存入隊(duì)列,并實(shí)時(shí)獲取該Server當(dāng)前的壓力情況,可以起到一個(gè)負(fù)載均衡的作用。而保持的HallServer隊(duì)列,當(dāng)客戶端連接過來,Conn Server則從pHallServerList中將當(dāng)前currentConn最小的服務(wù)器發(fā)送給客戶端,以后客戶端將同該Hall Server發(fā)起連接。

                   在該系統(tǒng)中,當(dāng)我們的Conn Server不夠的時(shí)候,可以考慮架設(shè)多臺(tái)Conn Server,當(dāng)客戶端無法連接時(shí)候,程序自動(dòng)連接下一臺(tái)Conn Server.比如conn1.doserver.netconn2.doserver.netconn3.doserver.netconnn.doserver.net

             

                   圖三中是按照組劃分的系統(tǒng)組成。該方案目前來說,我還并沒有實(shí)施過,只是在方案上面進(jìn)行過探討。希望有時(shí)間我可以設(shè)計(jì)一個(gè)案例出來再做展示。



            [圖四:改進(jìn)的功能劃分集群GameServer架構(gòu)二]

            在項(xiàng)目的實(shí)施過程中,我發(fā)現(xiàn)了Hall Server其實(shí)并不需要同Logic Server進(jìn)行交互,如果Hall Server在保留同Client1W多連接的情況下依然保持過多的同Logic Server的連接,勢(shì)必壓力非常大,這時(shí)候如果在之間使用ISServer來交互,就可以減少很多的連接數(shù)量,也使得系統(tǒng)更加清晰。

                   Hall Server只需要獲取所有的Logic Server的名稱,Logic Server的地址,Logic Server的端口,以及當(dāng)前的連接數(shù)量。所以通過之間的一個(gè)信息服務(wù)器作為橋梁,就可以很好的解決這個(gè)問題。這種架構(gòu)就可以達(dá)到非常完美的解決上面提到的4個(gè)難點(diǎn)的問題了。

                  

            后記:封閉開發(fā)之余,很想把自己的在服務(wù)器開發(fā)的經(jīng)驗(yàn)分享一下,所以就借用了2個(gè)小時(shí)整理此小文,希望大家喜歡。同時(shí)歡迎大家指點(diǎn),建議。也歡迎轉(zhuǎn)載,但是無比保留版權(quán)以及原作者信息。非常感謝。

             

                                                                                                       胡章優(yōu) 2008-12-3 于北京

             

            作者:胡章優(yōu),吉林大學(xué)機(jī)械學(xué)院教師。長(zhǎng)春優(yōu)狐科技開發(fā)有限公司董事長(zhǎng)兼總經(jīng)理。

            Tel: 13596199043

            Mail: huzhangyou2002@gmail.com (huzhangyou@jlu.edu.cn)

            Site: http://doserver.net

            MSN:huzhangyou2002@gmail.com

            QQ: 3803308


            posted on 2009-03-05 12:39 李陽 閱讀(2104) 評(píng)論(0)  編輯 收藏 引用 所屬分類: 游戲開發(fā)
            久久久久久精品无码人妻| 久久久中文字幕| 久久精品无码一区二区WWW| 久久午夜夜伦鲁鲁片免费无码影视| 久久婷婷午色综合夜啪| 九九久久自然熟的香蕉图片| 久久久久亚洲精品中文字幕| 国产aⅴ激情无码久久| 国产三级久久久精品麻豆三级| 久久强奷乱码老熟女| 精品久久香蕉国产线看观看亚洲| 麻豆久久久9性大片| 久久国产乱子伦精品免费强| 久久午夜福利无码1000合集| 国产精品岛国久久久久| 久久久久青草线蕉综合超碰| 丁香久久婷婷国产午夜视频| 久久久久人妻一区二区三区vr| 亚州日韩精品专区久久久| 色综合色天天久久婷婷基地| 国产精品99久久99久久久| 伊人久久无码中文字幕| 久久综合视频网站| 国产福利电影一区二区三区,免费久久久久久久精 | 狠狠综合久久AV一区二区三区| 久久精品国产一区| 乱亲女H秽乱长久久久| 国色天香久久久久久久小说| 污污内射久久一区二区欧美日韩 | 国产激情久久久久影院小草| 91精品国产色综合久久| 日产精品99久久久久久| 久久水蜜桃亚洲av无码精品麻豆| 久久久久免费精品国产| 精品久久人人爽天天玩人人妻| 久久久午夜精品福利内容| 久久亚洲精品国产精品婷婷 | 国产午夜精品理论片久久影视 | 久久精品成人免费网站| 日本精品久久久中文字幕| 久久99国产精品99久久|