Erlang 性能优化总结

本人主要从事游戏后端开发,所以本文只从游戏开发角度分析Erlang使用中应注意的问题和优化点。

  1.  单节点还是多节点

Erlang节点之间的通信是透明的,节点内部和外部之间的调用一致。基于这样的特性,很多人会选用多节点,把各子系统(登陆节点,玩家节点,地图节点,全局节点等)分配到不同的节点中,以支持更多的在线玩家。这样做的出发点是好点是好的,但会引起一列表的问题:登陆、转场逻辑复杂,节点间的消息广播频繁,玩家数据同步、一致问题,内存消耗,运维复杂化等。相比之下,单节点就简单多了,不用考虑节点通信,玩家数据保证一致,运维方便,一机多服。在开启SMP的情间下,单节点的性能已经很好。对页游的业务,同时在线达到5000人已经非常少见,即使达到也是首服当天才会出现,单节点完全可以应付这样的情况,所以没必要用多节点,增加系统复杂性。

2. 消息广播

消息广播是游戏中的性能消耗大头,主要包括地图的行走、PK广播,世界聊天广播。世界聊天广播可以通过CD等策划手段限制,行走和PK包的广播实时性高,只能通过技术手段解决。地图中的广播包,只需发给视野内的玩家就可以,不用全地图广播。视野内的玩家可以通过九宫格划分,以 X,Y为主键,映射到对应的玩家数据。以九宫格方式查找玩家非常高效,我第一个游戏,地图中的玩家起初是保存在一个列表中,每次广播时都要遍历列表,找出同屏玩家,消息广播非常低效,特别是在PK时,CPU占用高。用九宫格优化后,一切问题都解决了。还有一个优化广播问题的方法是数据包缓存。

3. 缓存-数据库,网络

缓存是用空间换时间,它是性能优化中常用的方法。数据库缓存,开服时把玩家的必要数据加载到内存中,可以减少玩家的登陆延时,应对玩家并发登陆,刷新也很有效。同时玩家数据没必要实现存库,对于坐标,经验,金钱等变化频繁的值,如果实时存在,会很容易压跨数据库或对存库进程造成消息阻塞。玩家改变的数据可以缓在内存中,定时存库,或下线时再存库。网络中的消息包也可以在应用层给缓存起来,达到一定长度或延时一定时间后再发出去。虽然虚拟机和TCP层会做缓存,最好还是在应用层做一次缓存。

4. 进程-每玩家应该有几个进程

其实每玩家一个进程已经足够,代码简单,方便维护,性能开销小。没必要为每个玩家开启了网络,物品、任务等进程,多个进程不但造成进程间通信开销,还不好维护。

5. 善用进程字典

Erlang中是不建议用进程字典的,但进程字典是数据存取最快的方式,对于游戏这种高性能要求的应用,进程字典是不二的选择。使用进程字典时要切记在对应的进程中操作,最好按功能把put,get操作封装到模块接口中,避免误用。

6. 代码规范

a. 代码应该简单,逻辑清晰,把功能细分到函数中。函数一般不多于30行,每个模块不多于1000行。

b. 写尾递归函数一定要有清淅的退出条件,不要在函数中改变退出条件。一个退出条件不明确的尾递归,是造成消息阻塞,内存耗尽的主要原因之一。

c.  不要相信客户端,上行的数据都需要验证,前端的请求都要做合法性判断,防止出现外挂、刷钱刷物品、刷金币的情况。

d 不要写过多的case ,if嵌套,最好不要大于3个嵌套,通过 try catch 方法写扁平化的代码。

7. 自动化工具

自动化工具可以避免出错,还把开发人员解放出来,提高生产效率。对于重复性,有规律的代码(如数据存取,通信协议),可以分离出来,让工具自动生成。有了生成工具后,修改协议,新加字段等操作,简单方便,不用为增加数据表中一个字段,而改十多个函数接口的修改;也不用担心前后端协议不一致的问题。

8. 监控系统

通过erlang:system_monitor/2,监控系统long_gc,large_heap等情况。

9. 性能分析工具

准备好top memory,top message_queue等查看系统属性的工具,出问题时可以随时查看。

Erlang技术分享内容均为原创,转载请标明本文地址
本文链接:http://www.kongqingquan.com/archives/221

此条目发表在Erlang分类目录,贴了, , 标签。将固定链接加入收藏夹。

Erlang 性能优化总结》有 2 条评论

  1. wudaijun说:

    很不错,很多实用的建议。多谢分享!

  2. wudaijun说:

    顺便问问,博主如何看待Erlang的拷贝效率?

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">