1.网络库的选择

从原始的网络操作api写的话,会花费很多精力,选择一个成熟的网络库是一个很不错的方案。

可选择的底层网络库很多,asio libevent ace等。

对应 两种高性能I/O设计模式(Reactor/Proactor)

Proactor典型例子是:IOCP,asio

Reactor 典型例子是EPOLL,libevent

相比之下更倾向于asio的proactor模型,框架设计起来更简单,每次网络都是已经接收完成了,只需要对其逻辑处理即可。

但是服务器在linux下运行,asio 效率会折扣,期望是windows下开发,linux下运维,因此要压榨服务器的性能,跨平台的话一个网络库就不太可能限定起来。

无论是哪种方式,网络消息的分发都可以由一个中间件来完成,可以是master也可以是mgr,这样切换不同的网络库对于服务器本身逻辑的编写不会有什么改动,kbe是支持epoll select等 io机制,他的做法也是如此,网络事件都有一个distapcher统一分发该网络事件。

因此设计上就可以吧网络io层独立出来,代码看起来可能是这样

UE MMO服务架构 mmo服务端_服务器

要切换到其他io 做一个适配层就可以了,

asio的适配

UE MMO服务架构 mmo服务端_python_02

 

2.服务器并发模型

多进程单线程 or 多进程多线程 

关于并发基本模型主要有,多进程的单线程模型,多进程的多线程模型,单进程的多线程模型,这里的线程主要是指游戏逻辑执行的线程。多进程单线程模型,类似于kbe的架构,一个cell 或者base 游戏逻辑执行的线程只有一个,这样大大简化了代码开发难度,效率相对也较高,比如吧一个cell做场景服务器,多个cell协同合作,玩家跨场景就在cell之间切换。

数据迁移的速度就很关键了,这也是实现无缝跨地图的重要因素,。kbe的这种bigworld方式的数据迁移主要就用socket 共享内存 redis 等,但是这些速度都没那么快,能用内存就用内存。

根据上述缺陷,还有一种解决方案,就是把cell base 直接装进一个进程里,数据迁移就简单得多,加个锁 然后更改数据指针所有权即可。这样吧cell当做线程来处理,cellMgr 可以当做这个进程的主线程,负责维护处理cell,这样吧进程通信socket 更改为了直接的内存交互,

这样做的一个缺点是把这些cell cellmgr 限制在了一台物理机上,由于都在同一个物理机,从单台物理机限制了并发量,一个cell 宕机之后 如果处理不得当,会导致整个进程宕机,从而影响整个系统,再者局域网通信socket 都可以维持在1ms以内。 这点数据迁移代价节约的并不多,如果客户端也要loading的话,那还不如不做这种优化,PS:反正都要读条

 

TODO