<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>中文 &#187; xiaohyy</title>
	<atom:link href="http://software.intel.com/zh-cn/blogs/author/xiaohyy/feed/" rel="self" type="application/rss+xml" />
	<link>http://software.intel.com/zh-cn/blogs</link>
	<description></description>
	<lastBuildDate>Mon, 28 May 2012 14:23:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>游戏服务器的架构设计</title>
		<link>http://software.intel.com/zh-cn/blogs/2010/01/05/400003040/</link>
		<comments>http://software.intel.com/zh-cn/blogs/2010/01/05/400003040/#comments</comments>
		<pubDate>Tue, 05 Jan 2010 10:19:40 +0000</pubDate>
		<dc:creator>xiaohyy</dc:creator>
				<category><![CDATA[博客征文专栏]]></category>
		<category><![CDATA[游戏]]></category>
		<category><![CDATA[多核]]></category>

		<guid isPermaLink="false">http://software.intel.com/zh-cn/blogs/2010/01/05/400003040/</guid>
		<description><![CDATA[游戏服务器的设计是一项颇有挑战性的工作，游戏服务器的发展也由以前的单服结构转变为多服机构，甚至出现了bigworld引擎的分布式解决方案，最近了解到Unreal的服务器解决方案atlas也是基于集群的方式。 负载均衡是一个很复杂的课题，这里暂不谈bigworld和atlas的这类服务器的设计，更多的是基于功能和场景划分服务器结构。 首先说一下思路，服务器划分基于以下原则： 1：分离游戏中占用系统资源（cpu，内存，IO等）较多的功能，独立成服务器 2：在同一服务器架构下的不同游戏，应尽可能的复用某些服务器（进程级别的复用） 3：以多线程并发的编程方式适应多核处理器。 4：宁可在服务器之间多复制数据，也要保持清晰的数据流向 5：主要按照场景划分进程，若需按功能划分，必须保持整个逻辑足够的简单，并满足以上1，2点 服务器结构图： 各个服务器的简要说明： Gateway：应用网关，主要用于保持和client的连接，该服务器需要2种IO，对client采用高并发连接，低吞吐量的网络模型，如IOCP等，对服务器采用高吞吐量连接，如阻塞或异步IO。 网关主要有以下用途： 1：分担了网络IO资源 2：同时，也分担了网络消息包的加解密，压缩解压等cpu密集的操作。 3：隔离了client和内部服务器组，对client来说，它只需要知道网关的相关信息即可（ip和port）。 4：client由于一直和网关保持常连接，所以切换场景服务器等操作对client来说是透明的。 5：维护玩家登录状态 World Server 是一个控制中心，它负责把各种计算资源分布到各个服务器 它具有以下职责： 1：管理和维护多个Scene Server 2：管理和维护多个功能服务器，主要是同步数据到功能服务器 3：复杂转发其他服务器和Gateway之间的数据 4：实现其他需要跨场景的功能，如组队，聊天，帮派等 Phys Server 主要用于玩家移动，碰撞等检测 所有玩家的移动类操作都在该服务器上做检查，所以该服务器本身具备所有地图的地形等相关信息。具体检查过程是这样的：首先，Worldserver收到一个移动信息，WorldServer收到后向Phys Server请求检查，Phys Server检查成功后再返回给world Server，然后world server传递给相应的Scene Server. Scene Server 场景服务器，按场景划分，每个服务器负责的场景应该是可以配置的。理想情况下是可以动态调节的。 ItemMgr Server 物品管理服务器，负责所有物品的生产过程。在该服务器上存储一个物品掉落数据库，服务器初始化的时候载入到内存。任何需要产生物品的服务器均与该服务器直接通信 AIServer 又一个功能服务器，负责管理所有NPC的AI。AI服务器通常有2个输入，一个是Scene Server发送过来的玩家相关操作信息，另一个时钟Timer驱动，在这个设计中，对其他服务器来说，AIServer就是一个拥有很多个NPC的客户端。AIserver需要同步所有与AI相关的数据，包括很多玩家数据。由于AIServer的Timer驱动特性，可在很大程度上使用TBB程序库来发挥多核的性能。]]></description>
			<content:encoded><![CDATA[<p>游戏服务器的设计是一项颇有挑战性的工作，游戏服务器的发展也由以前的单服结构转变为多服机构，甚至出现了bigworld引擎的分布式解决方案，最近了解到Unreal的服务器解决方案atlas也是基于集群的方式。</p>
<p>负载均衡是一个很复杂的课题，这里暂不谈bigworld和atlas的这类服务器的设计，更多的是基于功能和场景划分服务器结构。</p>
<p>首先说一下思路，服务器划分基于以下原则：<br />
1：分离游戏中占用系统资源（cpu，内存，IO等）较多的功能，独立成服务器<br />
2：在同一服务器架构下的不同游戏，应尽可能的复用某些服务器（进程级别的复用）<br />
3：以多线程并发的编程方式适应多核处理器。<br />
4：宁可在服务器之间多复制数据，也要保持清晰的数据流向<br />
5：主要按照场景划分进程，若需按功能划分，必须保持整个逻辑足够的简单，并满足以上1，2点</p>
<p>服务器结构图：</p>
<p><img src="http://p.blog.csdn.net/images/p_blog_csdn_net/xiaohyy/EntryImages/20091010/Servers_1.gif" alt="" /></p>
<p>各个服务器的简要说明：</p>
<p>Gateway：应用网关，主要用于保持和client的连接，该服务器需要2种IO，对client采用高并发连接，低吞吐量的网络模型，如IOCP等，对服务器采用高吞吐量连接，如阻塞或异步IO。</p>
<p>网关主要有以下用途：<br />
1：分担了网络IO资源<br />
2：同时，也分担了网络消息包的加解密，压缩解压等cpu密集的操作。<br />
3：隔离了client和内部服务器组，对client来说，它只需要知道网关的相关信息即可（ip和port）。<br />
4：client由于一直和网关保持常连接，所以切换场景服务器等操作对client来说是透明的。<br />
5：维护玩家登录状态</p>
<p>World Server 是一个控制中心，它负责把各种计算资源分布到各个服务器<br />
它具有以下职责：<br />
1：管理和维护多个Scene Server<br />
2：管理和维护多个功能服务器，主要是同步数据到功能服务器<br />
3：复杂转发其他服务器和Gateway之间的数据<br />
4：实现其他需要跨场景的功能，如组队，聊天，帮派等</p>
<p>Phys Server 主要用于玩家移动，碰撞等检测<br />
所有玩家的移动类操作都在该服务器上做检查，所以该服务器本身具备所有地图的地形等相关信息。具体检查过程是这样的：首先，Worldserver收到一个移动信息，WorldServer收到后向Phys Server请求检查，Phys Server检查成功后再返回给world Server，然后world server传递给相应的Scene Server.</p>
<p>Scene Server 场景服务器，按场景划分，每个服务器负责的场景应该是可以配置的。理想情况下是可以动态调节的。</p>
<p>ItemMgr Server 物品管理服务器，负责所有物品的生产过程。在该服务器上存储一个物品掉落数据库，服务器初始化的时候载入到内存。任何需要产生物品的服务器均与该服务器直接通信</p>
<p>AIServer 又一个功能服务器，负责管理所有NPC的AI。AI服务器通常有2个输入，一个是Scene Server发送过来的玩家相关操作信息，另一个时钟Timer驱动，在这个设计中，对其他服务器来说，AIServer就是一个拥有很多个NPC的客户端。AIserver需要同步所有与AI相关的数据，包括很多玩家数据。由于AIServer的Timer驱动特性，可在很大程度上使用TBB程序库来发挥多核的性能。</p>
]]></content:encoded>
			<wfw:commentRss>http://software.intel.com/zh-cn/blogs/2010/01/05/400003040/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>关于多核的发展对网络游戏设计影响的一些思考</title>
		<link>http://software.intel.com/zh-cn/blogs/2009/12/15/400002914/</link>
		<comments>http://software.intel.com/zh-cn/blogs/2009/12/15/400002914/#comments</comments>
		<pubDate>Tue, 15 Dec 2009 10:04:11 +0000</pubDate>
		<dc:creator>xiaohyy</dc:creator>
				<category><![CDATA[博客征文专栏]]></category>

		<guid isPermaLink="false">http://software.intel.com/zh-cn/blogs/2009/12/15/400002914/</guid>
		<description><![CDATA[早在几年前，Herb sutter就发表了《免费午餐已经结束，软件历史性的向并发靠拢》一文，引起了业内很大的反应，现在双核早已普及，09年应该是国内普及4核的一年。 Erlang这种老古董也因为多核的发展而逐渐热起来，网上关于普通程序员是否需要掌握多核编程技术也有很多争论，不论大家观点是否正确，至少多核相关技术引起了开发人员的注意。 我是做游戏服务器开发的，公司的老游戏的服务器机器配置一般是带超线程的双至强cpu，逻辑上是4个cpu（关于超线程的性能提升姑且不谈），照理说，游戏服务器早就应该是多线程的设计，但是据我了解，国内大部分的游戏服务器游戏逻辑部分都是单线程的，即存在所谓主线程的说法，单线程的设计是基于以下几个因素（以3000个玩家同时在线为列）： 1：大概有20-30%的cpu被网络IO占用，网络层很容易用多线程实现 2：可通过架构上的设计剥离数据访问，IO等容易采用多线程实现的部分，剩下的占用cpu密集的操作就是所谓的主线程 3：多线程的设计会导致开发周期延长，设计变得更加复杂，可维护性降低。 3：最关键的一点：多线程带来的复杂性和bug数量，频繁的宕机回档是任何游戏都不能忍受的。 4：再来分析一下以前的双cpu服务器采用单线程的方式带来的性能损失（超线程带来的性能极为有限，暂不做讨论），粗略的来看，网络IO部分可由2个 cpu平均分摊，再抛开一些锁和缓存同步带来的开销及一些其他软件（如监控，统计），损失大概30%-40%的性能，损失的性能和稳定性及开发周期等之间权衡，当然选择单线程的设计。 再来看如果现在启动一个新项目，对性能的考虑又该如何。首先做2个假设，1：项目周期为2年，即2年后游戏公测，或大规模内测。2：2年后服务器主流配置为16核，低端配置8核。如果仍采用单线程的服务器设计，以16核的cpu计算，损失的性能最少会达到800%，这个时候可能有人会说，我把所有的服务器放到一台机器上，甚至数据库也放过来，这样就能充分的利用到所有的cpu资源。不错，我承认这样基本上完全能利用cpu资源，但这不是游戏的核心内容，以前只能支持3000个玩家，10000个激活npc的服务器，现在仍然如此。硬件在发展，玩家的体验需求也在发展，就像网络的带宽提升了100倍，我们仍然只能看到断断续续的视频一样无法接受。说了这么多，也无非是得出一个结论：多核的发展在游戏开发当中必须引起重视。 那么，又如何利用多核资源呢？我总结了一下，大概有以下几种做法： 1：多进程设计，这是云风走的路线 2：挑战逻辑复杂性，设计良好的线程模型和数据结构 3：采用intel openmp 和 tbb 等技术 下面就以上几种设计谈谈个人看法： 多进程的设计很符合unix哲学，很kiss，难点在于进程的管理，通信，协调。优点是易于维护，调试，结构清晰。缺点是进程的管理麻烦，有一些效率损失，最重要的一点是，多进程设计可能仍然无法有效的在多核cpu上提高效率，根据80-20法则，可能80%的cpu消耗在20%的进程内，如果根据功能模块划分进程，即使设计良好的数据流水线，在20%的进程内也是需要做并行计算的。 第2中做法风险太大，需要多年的游戏设计经验和很好很强大的设计能力。 第3中做法比较折中，分析出占用80%cpu的那20%的代码，并行化。当然说起来比做起来容易，这种方式仍需要良好的数据结构的设计。举个例子，同时对1000个怪物做寻路操作，这种只读的操作是无需加锁很容易并行化。 结合以上几种设计，我认为最合适的做法是采用较粗粒度的进程，结合tbb等库在cpu密集操作的进程内部做并行化 是一种相对较好的设计 写的比较乱，有些地方不够严谨，以上的想法只是提供一种思路，还并未在实践中运用 ：） ps：tbb中有pipeline框架，可在进程内部方便的提供流水线机制]]></description>
			<content:encoded><![CDATA[<p>早在几年前，Herb sutter就发表了《免费午餐已经结束，软件历史性的向并发靠拢》一文，引起了业内很大的反应，现在双核早已普及，09年应该是国内普及4核的一年。 Erlang这种老古董也因为多核的发展而逐渐热起来，网上关于普通程序员是否需要掌握多核编程技术也有很多争论，不论大家观点是否正确，至少多核相关技术引起了开发人员的注意。<br />
我是做游戏服务器开发的，公司的老游戏的服务器机器配置一般是带超线程的双至强cpu，逻辑上是4个cpu（关于超线程的性能提升姑且不谈），照理说，游戏服务器早就应该是多线程的设计，但是据我了解，国内大部分的游戏服务器游戏逻辑部分都是单线程的，即存在所谓主线程的说法，单线程的设计是基于以下几个因素（以3000个玩家同时在线为列）：<br />
1：大概有20-30%的cpu被网络IO占用，网络层很容易用多线程实现<br />
2：可通过架构上的设计剥离数据访问，IO等容易采用多线程实现的部分，剩下的占用cpu密集的操作就是所谓的主线程<br />
3：多线程的设计会导致开发周期延长，设计变得更加复杂，可维护性降低。<br />
3：最关键的一点：多线程带来的复杂性和bug数量，频繁的宕机回档是任何游戏都不能忍受的。<br />
4：再来分析一下以前的双cpu服务器采用单线程的方式带来的性能损失（超线程带来的性能极为有限，暂不做讨论），粗略的来看，网络IO部分可由2个 cpu平均分摊，再抛开一些锁和缓存同步带来的开销及一些其他软件（如监控，统计），损失大概30%-40%的性能，损失的性能和稳定性及开发周期等之间权衡，当然选择单线程的设计。</p>
<p>再来看如果现在启动一个新项目，对性能的考虑又该如何。首先做2个假设，1：项目周期为2年，即2年后游戏公测，或大规模内测。2：2年后服务器主流配置为16核，低端配置8核。如果仍采用单线程的服务器设计，以16核的cpu计算，损失的性能最少会达到800%，这个时候可能有人会说，我把所有的服务器放到一台机器上，甚至数据库也放过来，这样就能充分的利用到所有的cpu资源。不错，我承认这样基本上完全能利用cpu资源，但这不是游戏的核心内容，以前只能支持3000个玩家，10000个激活npc的服务器，现在仍然如此。硬件在发展，玩家的体验需求也在发展，就像网络的带宽提升了100倍，我们仍然只能看到断断续续的视频一样无法接受。说了这么多，也无非是得出一个结论：多核的发展在游戏开发当中必须引起重视。<br />
那么，又如何利用多核资源呢？我总结了一下，大概有以下几种做法：<br />
1：多进程设计，这是云风走的路线<br />
2：挑战逻辑复杂性，设计良好的线程模型和数据结构<br />
3：采用intel openmp 和 tbb 等技术</p>
<p>下面就以上几种设计谈谈个人看法：<br />
多进程的设计很符合unix哲学，很kiss，难点在于进程的管理，通信，协调。优点是易于维护，调试，结构清晰。缺点是进程的管理麻烦，有一些效率损失，最重要的一点是，多进程设计可能仍然无法有效的在多核cpu上提高效率，根据80-20法则，可能80%的cpu消耗在20%的进程内，如果根据功能模块划分进程，即使设计良好的数据流水线，在20%的进程内也是需要做并行计算的。<br />
第2中做法风险太大，需要多年的游戏设计经验和很好很强大的设计能力。<br />
第3中做法比较折中，分析出占用80%cpu的那20%的代码，并行化。当然说起来比做起来容易，这种方式仍需要良好的数据结构的设计。举个例子，同时对1000个怪物做寻路操作，这种只读的操作是无需加锁很容易并行化。</p>
<p>结合以上几种设计，我认为最合适的做法是采用较粗粒度的进程，结合tbb等库在cpu密集操作的进程内部做并行化 是一种相对较好的设计</p>
<p>写的比较乱，有些地方不够严谨，以上的想法只是提供一种思路，还并未在实践中运用 ：）</p>
<p>ps：tbb中有pipeline框架，可在进程内部方便的提供流水线机制</p>
]]></content:encoded>
			<wfw:commentRss>http://software.intel.com/zh-cn/blogs/2009/12/15/400002914/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

