战魂小筑

讨论群:309800774 知乎关注:http://zhihu.com/people/sunicdavy 开源项目:https://github.com/davyxu

   :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  257 随笔 :: 0 文章 :: 506 评论 :: 0 Trackbacks

近期在写基于go的游戏服务器框架, 在全面脱离C/C++前, 需要对老架构进行一个总结

基于C/C++游戏服务器框架总体设计的还是不错的, 兄弟们总体使用效果都是好评. 因为在技术上喜欢"偷懒", 所以在很多设计上, 都是力求简单, 高效(开发效率).

基于任务的异步DB查询系统, 带多重异步的同步

代码示例:

   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:  }

这段主要处理玩家在登陆时, 需要从DB查询大量的不同分类的数据. 为了保证效率, 我让每个Task并行执行, 然后通过一个机制, 让所有任务完成后, 回调第一个任务的一个函数. 这样就无需手动实现很多粘合代码, 避免了反复调试和错误

基于protobuf反射机制的语句自动合成

   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:  }

这段就是一个典型的DB任务, 构造函数提供了CharID和一个由结构体序列化好的buffer, $FIELD$字段, 是通过反射根据Buffer内容, 自动填充字段

这段例子中, $FIELD$可以填充为 hp=100, mp=100之类的. 自动填充避免了因为添加字段的到处添加代码, 还需要调试, 容易搞错

 

配置系统概念

基于同一个配置系统, 分层实现不同的需求. 更简单的说, 解决的1个实际问题是:

自己改了配置文件中的ip, 上传svn后, 覆盖了别人的配置, 很多人的解决方法都是, 本地配置不提交. 但同时问题又来了:

当配置中有别人新加的系统配置, 怎么保证每个人都能更新到?

上线后, 服务器交付运维, 他们会对配置有一定程度的修改, 这个时候怎么合并程序配置和运维配置?

其实对于冲突的需求, 只要对系统进行分层就可以解决问题,我的处理方式:

配置分为:

全局配置: 所有服务的总体配置

单服务配置: 本服务的配置, 涉及网络及逻辑

本地配置: 这个配置每个人一份, 不上传SVN

命令行配置: 格式和前面的一致, 这块就可以通过运维进行配置

总体结构其实就是OO的派生概念, 下层可以覆盖, 修改上层的配置

 

服务器互联及识别框架

基本功能: 基于一些简单的配置就可以将多台服务器, 同种类的不同服务器互相连接起来, 断线自动重连.

服务器连接后, 所有服务器可知晓并可自动按需连接

逻辑端也很方便的进行广播或者单独发送等

也就是说, 每个服务器的连接和接受端都是带识别名称或id的.

后面觉得这套东西实在是做的复杂, 多整出一台中心服务器来做. 但好歹框架稳定下来了, 也就好了.

 

基于lua的服务器web后台框架

思想是很不错的,  C++ 配合lua本身绝对是个失败

问题出在web处理,本身都是一个同步阻塞过程, 而这个后台框架是异步方式来做, 所以特别别扭

不过比起以前的本地GM系统, 这块的设计是伟大的进步

 

现在正在设计基于golang的服务器框架, 基本框架已经完工, 等待编写逻辑后的实战测试

以上的很多思想在golang的服务器框架都有改进, 特别是golang本身做web也是优秀的, 外加martini这种牛X框架, 更是水到渠成

如果你对服务器框架设计有特别的认识, 或者想碰撞思想, 可以加博客群 309800774或者我的qq: 20998333讨论

posted on 2014-12-18 16:39 战魂小筑 阅读(8548) 评论(1)  编辑 收藏 引用 所属分类: 游戏开发技术网络 服务器技术C++/ 编程语言

评论

# re: C/C++服务器架构机制设计总结 2016-12-05 15:58 思月行云
关于“基于lua的服务器web后台框架”,不明白“问题出在web处理,本身都是一个同步阻塞过程”您这句所表述的含义。。
如果从web服务器(比如nginx)的内核角度考虑,每一次的web请求处理机制应该是异步的,而所谓同步处理,应该是客户端加入某种限定之后所产生的假象。。
如果需求是“基于lua的超高效率web服务器”,建议选用openresty,没有之一 ^^  回复  更多评论
  


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理