基于多线程的大容量MMORPG主逻辑服务器实现策略
2013-06-12 15:53
267 查看
转载请标明出处:http://blog.csdn.net/herm_lib/article/details/9079309
实际参与的商业项目而且已运营的服务器,逻辑这块都是一个独立的单线程的,网络跑在其他线程中。像接入服务器,由于他自身的特点,可以尽量利用CPU,做到大负载接入。大部分商业服务器,包括网游服务器,瓶颈还是在于逻辑而非网络,所以接入服务器这块也没有必要的优化。
以前总结过接入服务器的优化的策略:游戏网关服务器性能优化的一种方案 http://blog.csdn.net/herm_lib/article/details/7085181
今天想到了大世界服务器,以前出于兴趣,基于多线程实现了一个逻辑服务器,当时印象比较深刻。但随着时间的推移和年纪增长记忆力衰退,发现当时实现策略已经不再清晰。重新翻了一下以前的代码,好好地回忆,赶快把自己的理解记录下来。
今天的话题说得直白点就是,类似WOW这样的游戏,如何能做到支持最大数量的同时在线呢?这类游戏大地图是一个公共的开放空间,而且玩家角色之间是相互可见的,须要控制视野。实现大型战场的话,可以考虑参考本文的方法。
今天的文章基于的前提条件
服务器硬件足够强大,4CPU8核或者8CPU16核之类的。单台机器如果不够强,采用网络分布式的方案,理论上是不满足高即时的逻辑要求的。
要支持最大数量的同时在线,本质上就采用分布式策略。
一种方法是将地图分成多块,分配特定的线程为某块服务器。这个策略基本是不可行的,因为每一块的地图角色数量是不均衡的。除非,从设计角度强制每一块地图的人数有上限,这样就回到那种常见的小地图,跑两步就要传送到另外一个地图块模式中去了。
我这边采用的方法是,将不同的玩家角色分配给不同的线程,比如有角色R1 R2 R3, 线程 T1 T2 T3, T1跑R1逻辑,T2跑R2逻辑。。。。 线程分配方式,可以简单地为R1算个hash值,然后对应到哪个线程上。
这种方式在技术实现上,存在两个稍微麻烦一点的地方:
1. 线程互斥
2. 不同线程中的角色数据交互
第一种就是一种纯技术实现方案,我们要做到的是,多线程,但无须互斥。如果多线程,还要用各种锁,基本上玩家一多,线程一多,再多的CPU最后可能沦落到和一个CPU接近的负载。现在这个问题就归结到如何实现多线程不加锁了,基本上通过下面两点搞定:
[1] 一生产者线程一消费者线程,通过Memroy Barrie可以不用加锁,Memory Barrier,大家搜索吧。
[2] 多生产者多消费者,可以转换成[1]中的情形。
接下来说说第二个问题,角色间的数据交互,交互形式有两种,一种是线程内的,另外一个是线程间的。同一个线程内的两个或者多个角色数据交互,基本上是直接同步调用就行了。 线程间的有讲究,发展成类似服务器间的数据交互,从实现角度讲,可以认为和服务器间的数据交互是一样的,要做成异步的了。
就拿线程T1中的R1要获取T2中的R2的等级等信息,来说事,一般我们是获取角色基本信息,细节步骤如下:
[1] T1写 R1获取R2基本角色信息的请求消息(记为GET_ROLE_BASE_INFO_REQ),到 T2的线程队列;(R1就去做其他事情了啊。。。)
[2] T2取到 GET_ROLE_BASE_INFO_REQ,将 R2的 基本信息的回应消息(GET_ROLE_BASE_INFO_RES),写到T1的线程队列;
[3] T1读到T2的回应消息,通知给R1。
过程没有什么特别,和我们客户端和服务器,或者服务器之间的数据交互完全一样。 为了做到线程内和线程间的统一,线程内的角色间数据交互可以和线程间的方式统一起来。
上面的实现策略,在目前硬件条件下是可行的。有兴趣的兄弟可以实践一下,真正实践起来就有感觉了。
实际参与的商业项目而且已运营的服务器,逻辑这块都是一个独立的单线程的,网络跑在其他线程中。像接入服务器,由于他自身的特点,可以尽量利用CPU,做到大负载接入。大部分商业服务器,包括网游服务器,瓶颈还是在于逻辑而非网络,所以接入服务器这块也没有必要的优化。
以前总结过接入服务器的优化的策略:游戏网关服务器性能优化的一种方案 http://blog.csdn.net/herm_lib/article/details/7085181
今天想到了大世界服务器,以前出于兴趣,基于多线程实现了一个逻辑服务器,当时印象比较深刻。但随着时间的推移和年纪增长记忆力衰退,发现当时实现策略已经不再清晰。重新翻了一下以前的代码,好好地回忆,赶快把自己的理解记录下来。
今天的话题说得直白点就是,类似WOW这样的游戏,如何能做到支持最大数量的同时在线呢?这类游戏大地图是一个公共的开放空间,而且玩家角色之间是相互可见的,须要控制视野。实现大型战场的话,可以考虑参考本文的方法。
今天的文章基于的前提条件
服务器硬件足够强大,4CPU8核或者8CPU16核之类的。单台机器如果不够强,采用网络分布式的方案,理论上是不满足高即时的逻辑要求的。
要支持最大数量的同时在线,本质上就采用分布式策略。
一种方法是将地图分成多块,分配特定的线程为某块服务器。这个策略基本是不可行的,因为每一块的地图角色数量是不均衡的。除非,从设计角度强制每一块地图的人数有上限,这样就回到那种常见的小地图,跑两步就要传送到另外一个地图块模式中去了。
我这边采用的方法是,将不同的玩家角色分配给不同的线程,比如有角色R1 R2 R3, 线程 T1 T2 T3, T1跑R1逻辑,T2跑R2逻辑。。。。 线程分配方式,可以简单地为R1算个hash值,然后对应到哪个线程上。
这种方式在技术实现上,存在两个稍微麻烦一点的地方:
1. 线程互斥
2. 不同线程中的角色数据交互
第一种就是一种纯技术实现方案,我们要做到的是,多线程,但无须互斥。如果多线程,还要用各种锁,基本上玩家一多,线程一多,再多的CPU最后可能沦落到和一个CPU接近的负载。现在这个问题就归结到如何实现多线程不加锁了,基本上通过下面两点搞定:
[1] 一生产者线程一消费者线程,通过Memroy Barrie可以不用加锁,Memory Barrier,大家搜索吧。
[2] 多生产者多消费者,可以转换成[1]中的情形。
接下来说说第二个问题,角色间的数据交互,交互形式有两种,一种是线程内的,另外一个是线程间的。同一个线程内的两个或者多个角色数据交互,基本上是直接同步调用就行了。 线程间的有讲究,发展成类似服务器间的数据交互,从实现角度讲,可以认为和服务器间的数据交互是一样的,要做成异步的了。
就拿线程T1中的R1要获取T2中的R2的等级等信息,来说事,一般我们是获取角色基本信息,细节步骤如下:
[1] T1写 R1获取R2基本角色信息的请求消息(记为GET_ROLE_BASE_INFO_REQ),到 T2的线程队列;(R1就去做其他事情了啊。。。)
[2] T2取到 GET_ROLE_BASE_INFO_REQ,将 R2的 基本信息的回应消息(GET_ROLE_BASE_INFO_RES),写到T1的线程队列;
[3] T1读到T2的回应消息,通知给R1。
过程没有什么特别,和我们客户端和服务器,或者服务器之间的数据交互完全一样。 为了做到线程内和线程间的统一,线程内的角色间数据交互可以和线程间的方式统一起来。
上面的实现策略,在目前硬件条件下是可行的。有兴趣的兄弟可以实践一下,真正实践起来就有感觉了。
相关文章推荐
- 基于多线程的大容量MMORPG主逻辑服务器实现策略
- 基于tesseract的多线程OCR服务器的JAVA实现
- Java基于Socket实现简单的多线程回显服务器功能示例
- 基于TCP协议用多线程实现并发服务器,实现思路、算法和demo
- Java基于多线程的网络通信实现服务器计算正方形面积
- 基于MYSQL的 网络游戏 多线程 数据库 服务器 设计与实现
- 基于非阻塞socket的多线程服务器的实现------一个服务器如何与多个客户端进行通信?
- 基于HTTP模拟实现静态服务器-多任务多线程
- spring boot +security+oauth认证服务器和资源服务器(基于注解实现)
- 通过多线程为基于 .NET 的应用程序实现响应迅速的用户(MSDN)
- python 多线程实现检测服务器在线情况
- 利用tomcat服务器实现多线程下载 2
- java cache过期策略两种实现,一个基于list轮询一个基于timer定时
- 优雅设计封装基于Okhttp3的网络框架(三):多线程下载功能核心实现 及 线程池、队列机制、终止线程解析
- Linux C: 基于C/S的多线程网络编程 (服务器充当一个客户端的两点传输)
- 通过多线程为基于 .NET 的应用程序实现响应迅速的用户
- 配置基于主机名的虚拟主机实现服务器单IP跑多个web应用
- 一种基于Qt的可伸缩的全异步C/S架构服务器实现(五) 单层无中心集群
- 基于Windows Server 2008 系统的DNS服务器搭建与FTP服务器实现-《网络协议分析》实验
- 自己的web服务器项目-实现多线程处理(三)