-
Notifications
You must be signed in to change notification settings - Fork 36
App Server
引擎是可以按多进程部署的。每个进程处理一些比较独立的逻辑,称为一个App Server。进程之间保持TCP长连接,通过协议(Protobuf、Flatbuffers...)或Rpc进行交互。这样有助于提高整个服务器的负载,同时也是游戏中跨服等玩法所必须的。
启动一个进程时,最原始的指令是这样的:
master [name] [index] [srvid]master是编译出来的主程序。name即App Server的名字,对应lua_script下的一个目录,并且这个目录必须有一个app.lua作为入口文件。进程启动时,会把对应的参数传到这个入口文件。index是设计服务时给该app分配一个唯一的索引即可。srvid是服务器id,这个通常和游戏运营相关,表示开了多少个服务器了。
master gateway 1 1
master gateway 2 1上面表示启动了两个gateway进程(index分别设置为1和2),服务器id都为1。
每个应用服务器负责一个比较独立的逻辑,两个服务器之间保持一条TCP连接,通信通过该连接以flatbuffers或者RPC进行。相比于其他分布式系统,如一些Web系统,游戏服务器要求更高的实时性和更复杂的交互性。这使得比较独立这个定义比较难实现,如果逻辑划分不好,则会大量的服务器内部通信会导致系统性能下降。例如,在ARPG游戏中,我们可以划分为:
- gateway - 网关,负责网络连接及协议转发
- world - 世界服,负责玩家数据及基本操作
- area - 区域场景服,负现玩家场景处理,一个或多个
假如玩家在arna服务器中战斗并杀死了一个怪,需要给玩家添加经验。而玩家的数据是在world服务器,那么我们尝试一下RPC:
- 处理方法一:area服计算出经验后,调用world服的
add_exp修改玩家数据 - 处理方法二:area服直接调用world服的
monster_die,由world服计算出经验并修改玩家数据
然而事情并没有这么简单。因为计算经验并不是这么简单的一件事。它受很多因素影响:
- 怪物基础经验值
- 组队加成
- 场景加成
- 世界等级加成
- 经验药丹加成
这么复杂的计算,需要world和area两个服务器中不同的数据混合计算,显示不能直接调用add_exp这么简单通用的接口完事。通常是把当前进程里所需要参数打包,传到另一个进程,合并所有参数计算得出结果。然后把这个过程封装成一个通用的加经验的接口。
上面的例子表明,虽然大多数情况下希望通过多进程来提高系统承载,但如果逻辑分离得不是很好,则大量进程的内部通信可能导致性能大幅下降。最理想的情况当然是一个进程能满足所有逻辑,这样数据交互代价最小。多进程是1 + 1 < 2,整个系统的性能提高达不到一个服务器的2倍,开发的工作量也会增加。但随着游戏跨服等玩家的加入,多进程是必须的。RPC的出现是尽量让开发的工作量降低一些。使用RPC的同时要合理设计两个服务器之间的逻辑流程,降低带来的性能损耗。