游戏开发论坛

 找回密码
 立即注册
搜索
查看: 8466|回复: 1

C/C++服务器架构机制设计总结

[复制链接]

1万

主题

1万

帖子

2万

积分

管理员

中级会员

Rank: 9Rank: 9Rank: 9

积分
20356
QQ
发表于 2016-2-6 22:53:25 | 显示全部楼层 |阅读模式
201501122050134365903.jpg

作者: 徐波 来自:战魂小筑 - C++博客

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

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

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

代码示例:


  1. void BatchQueryPlayerInfo( uint32 ClientID, const std::string& AccountName, int64 CharID )
  2. {
  3.         GDBExecutor->Commit
  4.    (   
  5.        dynamic_cast<DBDataTask*>( (new DBQueryCharInfo(  ClientID, CharID ) )
  6.        ->LinkAtomTask( new DBQueryQuest( ClientID, CharID ) )
  7.        ->LinkAtomTask( new DBQuerySkill( ClientID, CharID ) )
  8.        ->LinkAtomTask( new DBQueryHero( ClientID, CharID ) )
  9.        ->LinkAtomTask( new DBQueryAccountInfo( ClientID, AccountName ) )
  10.        ->LinkAtomTask( new DBQueryEquip( ClientID, CharID ) )
  11.        ->LinkAtomTask( new DBQueryObject( ClientID ,CharID ) )
  12.        ->LinkAtomTask( new DBQueryLevel(ClientID, CharID))
  13.        ->LinkAtomTask( new DBQueryChapter(ClientID, CharID))
  14.        ->LinkAtomTask( new DBQueryActivity( ClientID, CharID ))
  15.       )
  16.     );
  17. }
复制代码
这段主要处理玩家在登陆时,需要从DB查询大量的不同分类的数据。为了保证效率,我让每个Task并行执行,然后通过一个机制,让所有任务完成后,回调第一个任务的一个函数。这样就无需手动实现很多粘合代码,避免了反复调试和错误。

基于protobuf反射机制的语句自动合成
  1. DBUpdateCharInfo::DBUpdateCharInfo( int64 CharID, const std::string& Buffer )
  2. {
  3.     char buffer[256];
  4.     sprintf( buffer, "update tb_char set $FIELD$ where charid = %lld;", CharID );
  5.     ExecuteCommand( buffer, Buffer, dbopr::FET_Equation );
  6. }
复制代码
这段就是一个典型的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框架,更是水到渠成。

1

主题

32

帖子

55

积分

注册会员

Rank: 2

积分
55
发表于 2016-2-14 11:27:35 | 显示全部楼层
过度设计,大概率失败开始向你靠近。因为你已经没有时间完成内容设计推敲。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2024-5-20 06:51

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表