• <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>

            戰(zhàn)魂小筑

            討論群:309800774 知乎關(guān)注:http://zhihu.com/people/sunicdavy 開(kāi)源項(xiàng)目:https://github.com/davyxu

               :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
              257 隨筆 :: 0 文章 :: 506 評(píng)論 :: 0 Trackbacks

            近期在寫(xiě)基于go的游戲服務(wù)器框架, 在全面脫離C/C++前, 需要對(duì)老架構(gòu)進(jìn)行一個(gè)總結(jié)

            基于C/C++游戲服務(wù)器框架總體設(shè)計(jì)的還是不錯(cuò)的, 兄弟們總體使用效果都是好評(píng). 因?yàn)樵诩夹g(shù)上喜歡"偷懶", 所以在很多設(shè)計(jì)上, 都是力求簡(jiǎn)單, 高效(開(kāi)發(fā)效率).

            基于任務(wù)的異步DB查詢系統(tǒng), 帶多重異步的同步

            代碼示例:

               1:   
               2:  void BatchQueryPlayerInfo( uint32 ClientID, const std::string& AccountName, int64 CharID )
               3:  {
               4:      GDBExecutor->Commit
               5:          (    
               6:          dynamic_cast<DBDataTask*>( (new DBQueryCharInfo(  ClientID, CharID ) ) 
               7:          ->LinkAtomTask( new DBQueryQuest( ClientID, CharID ) )
               8:          ->LinkAtomTask( new DBQuerySkill( ClientID, CharID ) )
               9:          ->LinkAtomTask( new DBQueryHero( ClientID, CharID ) )
              10:          ->LinkAtomTask( new DBQueryAccountInfo( ClientID, AccountName ) )
              11:          ->LinkAtomTask( new DBQueryEquip( ClientID, CharID ) )
              12:          ->LinkAtomTask( new DBQueryObject( ClientID ,CharID ) )
              13:          ->LinkAtomTask( new DBQueryLevel(ClientID, CharID))
              14:          ->LinkAtomTask( new DBQueryChapter(ClientID, CharID))
              15:          ->LinkAtomTask( new DBQueryActivity( ClientID, CharID ))
              16:          )
              17:          );
              18:   
              19:  }

            這段主要處理玩家在登陸時(shí), 需要從DB查詢大量的不同分類(lèi)的數(shù)據(jù). 為了保證效率, 我讓每個(gè)Task并行執(zhí)行, 然后通過(guò)一個(gè)機(jī)制, 讓所有任務(wù)完成后, 回調(diào)第一個(gè)任務(wù)的一個(gè)函數(shù). 這樣就無(wú)需手動(dòng)實(shí)現(xiàn)很多粘合代碼, 避免了反復(fù)調(diào)試和錯(cuò)誤

            基于protobuf反射機(jī)制的語(yǔ)句自動(dòng)合成

               1:  DBUpdateCharInfo::DBUpdateCharInfo( int64 CharID, const std::string& Buffer )
               2:  {
               3:      char buffer[256];
               4:   
               5:      sprintf( buffer, "update tb_char set $FIELD$ where charid = %lld;", CharID );
               6:          
               7:      ExecuteCommand( buffer, Buffer, dbopr::FET_Equation );
               8:  }

            這段就是一個(gè)典型的DB任務(wù), 構(gòu)造函數(shù)提供了CharID和一個(gè)由結(jié)構(gòu)體序列化好的buffer, $FIELD$字段, 是通過(guò)反射根據(jù)Buffer內(nèi)容, 自動(dòng)填充字段

            這段例子中, $FIELD$可以填充為 hp=100, mp=100之類(lèi)的. 自動(dòng)填充避免了因?yàn)樘砑幼侄蔚牡教幪砑哟a, 還需要調(diào)試, 容易搞錯(cuò)

             

            配置系統(tǒng)概念

            基于同一個(gè)配置系統(tǒng), 分層實(shí)現(xiàn)不同的需求. 更簡(jiǎn)單的說(shuō), 解決的1個(gè)實(shí)際問(wèn)題是:

            自己改了配置文件中的ip, 上傳svn后, 覆蓋了別人的配置, 很多人的解決方法都是, 本地配置不提交. 但同時(shí)問(wèn)題又來(lái)了:

            當(dāng)配置中有別人新加的系統(tǒng)配置, 怎么保證每個(gè)人都能更新到?

            上線后, 服務(wù)器交付運(yùn)維, 他們會(huì)對(duì)配置有一定程度的修改, 這個(gè)時(shí)候怎么合并程序配置和運(yùn)維配置?

            其實(shí)對(duì)于沖突的需求, 只要對(duì)系統(tǒng)進(jìn)行分層就可以解決問(wèn)題,我的處理方式:

            配置分為:

            全局配置: 所有服務(wù)的總體配置

            單服務(wù)配置: 本服務(wù)的配置, 涉及網(wǎng)絡(luò)及邏輯

            本地配置: 這個(gè)配置每個(gè)人一份, 不上傳SVN

            命令行配置: 格式和前面的一致, 這塊就可以通過(guò)運(yùn)維進(jìn)行配置

            總體結(jié)構(gòu)其實(shí)就是OO的派生概念, 下層可以覆蓋, 修改上層的配置

             

            服務(wù)器互聯(lián)及識(shí)別框架

            基本功能: 基于一些簡(jiǎn)單的配置就可以將多臺(tái)服務(wù)器, 同種類(lèi)的不同服務(wù)器互相連接起來(lái), 斷線自動(dòng)重連.

            服務(wù)器連接后, 所有服務(wù)器可知曉并可自動(dòng)按需連接

            邏輯端也很方便的進(jìn)行廣播或者單獨(dú)發(fā)送等

            也就是說(shuō), 每個(gè)服務(wù)器的連接和接受端都是帶識(shí)別名稱(chēng)或id的.

            后面覺(jué)得這套東西實(shí)在是做的復(fù)雜, 多整出一臺(tái)中心服務(wù)器來(lái)做. 但好歹框架穩(wěn)定下來(lái)了, 也就好了.

             

            基于lua的服務(wù)器web后臺(tái)框架

            思想是很不錯(cuò)的,  C++ 配合lua本身絕對(duì)是個(gè)失敗

            問(wèn)題出在web處理,本身都是一個(gè)同步阻塞過(guò)程, 而這個(gè)后臺(tái)框架是異步方式來(lái)做, 所以特別別扭

            不過(guò)比起以前的本地GM系統(tǒng), 這塊的設(shè)計(jì)是偉大的進(jìn)步

             

            現(xiàn)在正在設(shè)計(jì)基于golang的服務(wù)器框架, 基本框架已經(jīng)完工, 等待編寫(xiě)邏輯后的實(shí)戰(zhàn)測(cè)試

            以上的很多思想在golang的服務(wù)器框架都有改進(jìn), 特別是golang本身做web也是優(yōu)秀的, 外加martini這種牛X框架, 更是水到渠成

            如果你對(duì)服務(wù)器框架設(shè)計(jì)有特別的認(rèn)識(shí), 或者想碰撞思想, 可以加博客群 309800774或者我的qq: 20998333討論


            評(píng)論

            # re: C/C++服務(wù)器架構(gòu)機(jī)制設(shè)計(jì)總結(jié) 2016-12-05 15:58 思月行云
            關(guān)于“基于lua的服務(wù)器web后臺(tái)框架”,不明白“問(wèn)題出在web處理,本身都是一個(gè)同步阻塞過(guò)程”您這句所表述的含義。。
            如果從web服務(wù)器(比如nginx)的內(nèi)核角度考慮,每一次的web請(qǐng)求處理機(jī)制應(yīng)該是異步的,而所謂同步處理,應(yīng)該是客戶端加入某種限定之后所產(chǎn)生的假象。。
            如果需求是“基于lua的超高效率web服務(wù)器”,建議選用openresty,沒(méi)有之一 ^^  回復(fù)  更多評(píng)論
              

            久久这里只有精品首页| 很黄很污的网站久久mimi色| 精品久久人人爽天天玩人人妻| 亚洲中文字幕无码久久2017| 亚洲国产小视频精品久久久三级| 国产精品永久久久久久久久久| 狠狠狠色丁香婷婷综合久久俺| 97久久精品无码一区二区| 亚洲国产另类久久久精品黑人 | 国内精品人妻无码久久久影院导航| 久久国产精品国语对白| 久久se这里只有精品| 午夜精品久久久久久| 久久亚洲AV无码精品色午夜麻豆 | 久久久精品久久久久特色影视| 国产精品99久久久久久人| 久久精品国产精品亚洲毛片| 久久天天躁狠狠躁夜夜网站| 精品蜜臀久久久久99网站| 国产亚洲美女精品久久久久狼| 久久青青草原国产精品免费| 97久久精品人人澡人人爽| 欧美亚洲日本久久精品| 伊人久久无码中文字幕| 精品久久久久久无码专区| 999久久久国产精品| 久久综合亚洲色一区二区三区| 色婷婷综合久久久久中文 | 久久精品无码一区二区无码 | 色综合久久无码五十路人妻| 精品无码久久久久久午夜| 99久久伊人精品综合观看| 久久综合成人网| 精品久久久久久中文字幕人妻最新| 国产一区二区精品久久凹凸| 中文成人久久久久影院免费观看| 久久无码人妻一区二区三区午夜| 999久久久国产精品| 久久香蕉国产线看观看精品yw| 久久久精品无码专区不卡| 久久Av无码精品人妻系列|