• <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 開源項(xiàng)目:https://github.com/davyxu

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

            近期在寫基于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)單, 高效(開發(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查詢大量的不同分類的數(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之類的. 自動(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ù)器, 同種類的不同服務(wù)器互相連接起來(lái), 斷線自動(dòng)重連.

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

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

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

            后面覺得這套東西實(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)完工, 等待編寫邏輯后的實(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)論
              

            久久久久99精品成人片| 国产精品一区二区久久不卡| 精品国产乱码久久久久久1区2区 | 99热热久久这里只有精品68| 国产成人久久精品激情| 国产成人无码精品久久久性色| 亚洲精品高清一二区久久| 久久精品国产黑森林| 精品无码人妻久久久久久| 久久播电影网| 中文字幕无码久久精品青草 | 亚洲第一永久AV网站久久精品男人的天堂AV | 日本免费久久久久久久网站| 久久久久国产一级毛片高清版| 久久精品国产亚洲一区二区| 91久久九九无码成人网站| 国内精品久久久久久不卡影院 | 一级a性色生活片久久无| 四虎国产精品成人免费久久| 欧美牲交A欧牲交aⅴ久久| 精品国产VA久久久久久久冰| 久久九九久精品国产| 一级女性全黄久久生活片免费 | 久久无码AV一区二区三区| 日韩精品久久久久久久电影蜜臀| 久久婷婷国产综合精品| 一本大道加勒比久久综合| 精品99久久aaa一级毛片| 亚洲色欲久久久久综合网| 久久99精品国产自在现线小黄鸭| 国产精品美女久久久久AV福利| 性欧美大战久久久久久久| 国产aⅴ激情无码久久| 嫩草影院久久99| 无码8090精品久久一区| 久久香综合精品久久伊人| 嫩草影院久久99| 嫩草伊人久久精品少妇AV| 狠狠色综合网站久久久久久久| 99精品国产免费久久久久久下载| 精品久久久久久无码专区不卡|