2012-09-04 44 views
2

我是新来的游戏服务器设计,现在分配给一个任务来重构我们的日志服务器。我为游戏服务器和日志服务器之间的通信创建了一个类日志。MMO游戏的设计日志服务器

class Log 
{ 
    public: 
     void encode(Encoder& encoder) const; 
     int  decode(Decoder& decoder); 
    private: 
     std::string sql_cmd; 
} 

在游戏服务器上,有一个用于向日志服务器发送日志请求的类。

class LogHelper 
{ 
public: 
     static void LogItemChange(const GameShare::GameItem& item, const PackageChangeDetails& pcd); 
     { 
       Log log(get_item_change_sql(item,pcd); 
       send_to_log_server(); 
     } 


private: 
     static std::string get_item_change_sql(const GameShare::GameItem& item, const PackageChangeDetails& pcd); 
} 

的问题是:

  1. 我应该生成游戏服务器上的SQL文本?如果在游戏服务器上生成sql文本,对游戏服务器的性能有没有影响?

  2. 如果不在游戏服务器上生成sql文本,那么应该在日志服务器上生成sql文本。我应该将GameItem和PackageChangeDetails实例数据发送到日志服务器,它会使日志服务器复杂化,是否有任何人拥有良好的身份?

+0

如果日志服务器控制日志的数据库,那么它也应该控制它的SQL语言。如果做得对,其余代码甚至不应该关心 - 更不用说知道 - 记录器背后的实现。日志记录可能会对性能产生巨大影响,并且由于您的经验不足,您必须向其他团队寻求帮助,并确保使用准备好的语句以避免SQL注入(请查看您的数据库选择C++如果你不知道这是什么意思)。 – pickypg

+0

感谢您的回复。日志服务器控制数据库的日志,并执行sql命令。问题是在游戏服务器上生成sql之间的选择,然后发送sql字符串到日志服务器或发送日志数据到日志服务器,并与数据服务器生成sql?对于sql注入部分,由于日志模块与玩家没有直接的交互,所以不必担心。 – ark

+0

问题是在游戏服务器上生成sql之间的选择,然后将sql字符串发送到日志服务器或发送日志数据到日志服务器并使用数据生成sql [server] - 这个词应该被删除,不知道如何编辑它,所以重播。 – ark

回答

1

如果游戏服务器生成的日志的SQL,则几乎不存在需要引起任何日志服务器的代码,因为它成为一个中继数据库管理器片,其游戏服务器几乎可以肯定已经知道(尽管我想他们可能是不同的数据库),或者可以轻松地进行交互。

日志服务器应该是一个单独的组件,以任何最适合您的格式(性能,详细程度,大小等)进行登录,只要API足够灵活,就可以编写基础在没有Game Server知道的情况下可以替换实现。

通过将底层实现的完整知识与Game Server代码结合起来,您不仅可以防止这样的未来事件,而且还可能将大量工作投入到可由独立线程完成的Game Server代码中在日志服务器上。更不用说,通过开放API的SQL,你可以将整个游戏服务器代码中的潜在错误都放在中心位置。

在设计面向对象的系统时,前瞻性的替代驱动方法非常理想。如果您可以避免与除API以外的其他任何东西耦合,那么您可以随时替换API以下的任何内容而不影响外部代码(忽略错误),但这需要考虑将其放入API中以确保它具有足够的未来灵活性。

在此说明中,我强烈建议您将Logging API作为纯虚拟接口实施,然后在其上编写与数据库交谈的实现,可能使用单独的实现来记录到文本文件为了便利的本地测试而无需访问数据库,如果这是一个问题)以及无所作为的实现。考虑到前两个问题,它应该有助于指导您更好的设计,并远离耦合。

这也可能导致您的其他类实现一些基本接口(例如,public: std::string to_log_string() const;),然后记录器可以使用它来引入任何实现对象并将其快速转换为记录的消息。

所有这一切都是说,把日志记录相关的SQL放入日志服务器,而不是在游戏服务器。游戏服务器不应该关心日志服务器除了一般的“日志记录”之外的功能。

+0

太棒了,答案就是我想要的!再次感谢! – ark

0

不要在游戏服务器上生成SQL文本。不要在日志服务器上执行它。SQL后知后觉只有已准备好语句。在运行时生成查询与在运行时生成索引一样疯狂。因此,将最终的SQL文本生成到数据库。

因此,游戏服务器和日志服务器之间的API应该只包含您想要记录的变量,而不是代码。

事实上,这完全避免SQL注入是一个副作用。但它仍然是一个真正的好处。如果你的用户名和日志一样多,你必须考虑SQL注入。

+0

感谢您的回答。我们的项目在输入中使用mysqlpp和同事过滤字符(例如用户名),如'%','='等。我不知道如何做sql预备陈述,你能否给我一些提示? – ark

+0

显然,对于mysqlpp他们被称为[模板查询](http://tangentsoft.net/mysql++/doc/html/userman/tquery.html) – MSalters

+0

感谢您的帮助! – ark