百万用户同时在线游戏服务器架构实现.doc 基于epoll 通信模型

http://wenku.baidu.com/view/02033d0af78a6529647d53fc.html

百万用户在线网络游戏服务器架构实现

 

一、            前言

事实上100万游戏服务器,在面对大量用户访问、高并发请求方面,基本的解决方案集中在这样几个环节:使用高性能的服务器高效率的编程语言高性能的数据库还有高性能的架构模型。但是除了这几个方面,还没法根本解决面临的高负载和高并发问题。

当然用户不断地追求更高的机器性能,而升级单一的服务器系统,往往造成过高的投入和维护成本,性价比大大低于预期。同时全天候的可用性的要求也不能满足要求,如果服务器出现故障则该项服务肯定会终止。所以单独追求高性能的服务器不能满足要求,目前基本的解决方案是使用集群技术做负载均衡,可以把整体性能不高的服务器做成高可扩展性,高可用性,高性能的,满足目前的要求。

目前解决客户端和服务器进行底层通讯的交互的双向I/O模型的服务器的成熟方案。

1.windows下,比较成熟的技术是采用IOCP,完成端口的服务器模型。

2.Linux下,比较成熟的技术是采用Epoll服务器模型, Linux 2.6内核中提供的System Epoll为我们提供了一套完美的解决方案。

目前如上服务器模型是完全可以达到5K20K的同时在线量的。但5K这样的数值离百万这样的数值实在相差太大了,所以,百万人的同时在线是单台服务器肯定无法实现的。

而且目前几个比较成熟的开发框架,比如ICE,ACE等。这样,当采用一种新的通信技术来实现通信底层时,框架本身就不用做任何修改了(或修改很少),而功能很容易实现,性能达到最优。目前采用的ace框架个不错的选择方案,可以不受操作系统的影响,移植比较方便。

对于数据库选择可有许多成熟的方案,目前大多数选择的mysql Master/slave模式,以及oracle  RAC方案。基本可以满足目前的要求,但具体的瓶颈不是在数据库本身,应该还是硬件磁盘I/O的影响更大些。建议使用盘阵。这有其他成熟的方案,比如采用NAS解决分布数据存储。

其实最为关键的是服务器的架构和实现,数据流量的负载均衡,体系的安全性,关键影响度,共享数据的处理等等多个方面对100万用户的数据处理有影响,所以都要全面的考虑。

 

二、            高性能的服务器

 

1.      网络环境

目前采用Client/Server架构来开发网络游戏,客户端和服务器一般通过TCP/UDP协议进行通信,关键瓶颈很明确--游戏服务器与客户机之间的链路。目前单机环境比较好些的是,21000M网卡,20K客户端,并发提供每个客户端的带宽是2000/20K=100KB/s,这是理论值,勉强可行。如果这样实现目前肯定有成本和性能问题。特别是用户响应时间已经超过他们的忍受范围。为了避免瓶颈许多游戏厂家一组限制用户上限为100M/5k~10k。即用户100KB/s

而客户的网络情况也要考虑。这就也提出尽可能减少传输数据。

这需要测试评估网络吞吐量和延迟需求,以便对服务器的用户数和带宽做评估。

网络部署中还要考虑网络拓扑情况。内网和外网要分不同的交换机,避免出现网络瓶颈。

还要考虑网络图朴情况的优化。比如每组几台使用一个交换机做流量分配。

 

2.      CPU和内存的参考

目前要求高处理能力,高带宽,低存储容量主要考虑的瓶颈问题应该是I/O问题,一般情况时采用双路CPU或多路,而且服务器专用内存已经很好的解决了I/O瓶颈。实际测试如果几千人同时在线的话,CPU和内存需求都很低,目前一般服务器都可以满足要求。

3.      负载均衡

所以必须要采用多台服务器的架构方式,但出现了均衡负载和分布架构的问题,可以通过下面几种方式解决。

A.     硬件负载均衡设备

常用的F5等负载均衡器,很好的解决了负载均衡的问题。一般这种设备投资比较高,但部署容易,而且支持分布式架构。

B.     集群系统

集群系统增长了系统可用性(availability)和冗余(redundancy),也提供了容错(fault tolerance)。使用集群,可以分布请求以便多个服务器可以共享负载,一些服务器也可能提供确定哪台服务器利用的不充分以便均衡负载的复杂处理。

Linux平台上很多免费开源的集群软件,如LVSLinux Virtual Server)是Linux平台下的一个集群软件工具。通过LVS,你可以快捷方便的组建一个带有第四层负载均衡功能的集群系统。并且,借助第三方的工具包,还可以实现对LVS集群进行可用性支持的功能扩展。他提供了基于心跳线heartbeat的实时灾难应对解决方案,提高系统的鲁棒性,同时可供了灵活的虚拟VIP配置和管理功能,可以同时满足多种应用需求,这对于分布式的系统来说必不可少。而且还有如下几点特点:

  • 解决网络拥塞问题,服务就近提供,实现地理位置无关性。
  • 为用户提供更好的访问质量。
  • 提高服务器响应速度。
  • 提高服务器及其他资源的利用效率。
  • 避免了网络关键部位出现单点失效。

缺点:

  • 配置比较复杂,而且需要修改内核来支持这种结构,提高了实施的和运维的工作量。
  • 一般需要增加两台服务器做主,备也增加了成本。

 

C.      软件自身实现逻辑负载均衡

根据应用服务器的许多需求,负载均衡也有一些不能满足我们的自身的需求的东西,比如均衡的条件,一般集群是按照ip分配,处理包的速度,支持的连接数等。而应用服务器可以根据自己的需求定制自己的负载规则。比如许多游戏服务器采用根据区域做用户限制,这样管理起来比较方便灵活,而且效率高。

4.      操作系统的优化

     建议使用linux 2.6.x内核 64位系统。而且要对部分参数的修改。

A.     文件系统

fstab里加入noatime,如

#cat /etc/fstab

/dev/sda1          /home                  ext3    noatime,defaults        1 2

reboot或者重新mount生效

B.     Tcp优化

/etc/sysctl.conf里加入

net.ipv4.netfilter.ip_conntrack_tcp_timeout_syn_recv = 3

#启用syncookies

net.ipv4.tcp_syncookies = 1

#定义backlog队列容纳的最大半连接数

net.ipv4.tcp_max_syn_backlog = 8192

net.ipv4.tcp_fin_timeout = 30

net.ipv4.tcp_keepalive_time = 1800

net.ipv4.tcp_window_scaling = 0

net.ipv4.tcp_sack = 0

net.ipv4.tcp_timestamps = 0

这些需要内核支持。如果不支持不用修改。

C.      虚拟内存优化

/etc/sysctl.conf

       vm.lower_zone_protection = 100

D.     I/O调度器

grub.conf的相应启动选项里加入elevator=deadline,如:

kernel /vmlinuz-2.6.6 ro root=/dev/sda6 elevator=deadline

这里用了DeadlineI/O调度器,它比系统默认的AnticipatoryI/O调度器更为小巧,在数据吞吐量非常大的数据库系统中表现得更有优势。

E.      网络协议方面优化

Ip route cache 需要修改,否则容易丢包。

echo 1 > /proc/sys/net/ipv4/route/gc_interval

echo 150 >/proc/sys/net/ipv4/route/gc_timeout

echo 2 >/proc/sys/net/ipv4/route/gc_elasticity

 

使用 hugeTLB

echo xxx >/proc/sys/vm/nr_hugepages

 

Tune tcp :

echo "4096 49152 131072" >/proc/sys/net/ipv4/tcp_wmem

echo xxxx >/proc/sys/net/ipv4/tcp_max_syn_backlog

echo xxxx >/proc/sys/net/core/somaxconn

echo 1200000 > /proc/sys/net/ipv4/tcp_max_tw_buckets

echo 7 >/proc/sys/net/ipv4/tcp_retries2

echo "600000 650000 700000" >/proc/sys/net/ipv4/tcp_mem

echo 0 >/proc/sys/net/ipv4/tcp_timestamps

echo 0 >/proc/sys/net/ipv4/tcp_window_scaling

echo 0 >/proc/sys/net/ipv4/tcp_sack

echo 330000 >/proc/sys/net/ipv4/tcp_max_orphans

echo "10000 62000" >/proc/sys/net/ipv4/ip_local_port_range

 

epoll模型需要修改的参数:

echo 1300000 >/proc/sys/fs/file-max

 

F.      内核源代码参数修改

可以根据部署应用服务器的要求,或者需要部署集群的要求需要对内核作部分修改。具体参考文档,下面只是简单的例子。

修改/usr/src/linux/include/linux/posix_types.h

#define __FD_SETSIZE 1024  65536 

设置fd_set支持的最大数量

修改/usr/src/linux/include/linux/fs.h

#define INR_OPEN 102465536

#define NR_FILE 819265536

#define NR_RESERVED_FILES 10128

设置最大打开文件数量(TCP连接数量)

修改/usr/src/linux/include/net/tcp.h

#define TCP_TIMEWAIT_LEN (60*HZ) 1*HZ

#define TCP_SYNACK_RETRIES  5

设置在backlog队列里的半连接的重试次数,每次都会花相应的时间,本质上也是减少重试时间

make menuconfig中,去掉没用的选项,打开以下选项的开关:

High Memory Support (支持4GB以上内存)

Symmetric multi-processing support (支持多CPU)

TCP syncookie support (可以防DOS)

 

设置文件打开数等的其他方法(好处就是可以不重新编译内核)

/etc/init.d/sshd里加入(统一加在. /etc/rc.d/init.d/functions行后面)

ulimit -n 65535 >/dev/null 2>&1

ulimit -u 16384 >/dev/null 2>&1

三、            高效率的编程语言

1.      平台语言选择

不同平台的具体实现差别也很大。例如仅在Windwos平台下就有基于Windwows消息机制的、基于事件机制的、也有基于完成端口I/O模型的实现等等,而linux平台也有Epoll服务器模型,Linux 2.6内核中提供的System Epoll为我们提供了一套完美的解决方案。可以根据不同的平台和效率,目前多采用 C/C++

2.      成熟的开发框架

目前解决客户端和服务器进行底层通讯的交互的双向I/O模型的服务器的成熟方案。

1.windows下,比较成熟的技术是采用IOCP,完成端口的服务器模型。

2.Linux下,比较成熟的技术是采用Epoll服务器模型, Linux 2.6内核中提供的System Epoll为我们提供了一套完美的解决方案。

当然也有利于利用其它一些成熟的开发框架,比如ICE,ACE等。这样,当采用一种新的通信技术来实现通信底层时,框架本身就不用做任何修改了(或修改很少)。

目前采用 ACE框架实现,是完全可以达到5K20K的同时在线量的,而且消耗系统资源小。但5K这样的数值离百万这样的数值实在相差太大了,所以,百万人的同时在线是单台服务器肯定无法实现的。所以只能采用多台服务器负载分摊100万用户的流量数据。

3.      程序架构

通讯机制,通讯协议,线程池,memorycache,数据库

四、            高性能的数据库

1.      采用分布集群

百万用户同时在线对于数据库选择可有许多成熟的方案,目前大多数选择的mysql Master/slave模式,以及oracle  RAC方案。基本可以满足目前的要求,但具体的瓶颈不是在数据库本身,应该还是硬件磁盘I/O的影响更大些。建议使用盘阵。这些市场上有很成熟的方案可以参考。

目前选择oracle,应该根据具体估计出并发玩家数量和同时在线人数,就可以估计每秒事务量。找到了能够满足事务需求的 CPU 和内存配置,如果可以最少只需购买两台这样的服务器,并将它们配置为 active-active 集群就可以了,这样保证两台服务器同时负载,并实时同步数据。但是如果实际100万在线的情况,这样双机很难达到这种满足,则要考虑使用多台的分布式集群方案也可以有很好扩展性。这需要有经验的DBA做一个评估。

2.      部署Oracle优化

最好操作系统做优化,oracle 采用64位的linux版本,大约是8000元钱。数据库数据文件,控制文件和具体系统初始参数的优化。目前可简单参考需要修改的几个参数:(根据具体的硬件设备进行优化。)

SGA 3500M

log_buffer 10M/10485760

larg_pool_size 30M/31457280

java_pool_size 10M/10485760

shared_pool_size 250M/262144000

db_16k_cache_size  2000M/2097152000

db_cache_size 1000M/1048576000

db_keep_cache_size 50M/52428800

sort_area_size 20M/20971520

sga_max_size 3670016000

数据库表空间和回滚文件的设置。

数据库表空间可以设置自动扩展。但也要考虑数据量规划好最优的大小。

回滚段大小由于并发数据量比较大,需要根据具体的数据量考虑其大小。

五、            高性能的游戏服务器架构模型

目前主流游戏服务器架构一般采用RunGate层次化模式,,但如果达到100万用户的服务器还有许多需要优化和考虑的地方。最简单的服务器负载均衡如何处理,共享数据如何处理都在层次化的服务器结构中出现。特别是负载均衡也存在着问题,如果其中一台服务器达到服务上限而瘫痪,则很容易产生连锁反应,出现集群的服务器依次宕掉。所以在设计时候要做冗余和条件限制的考虑。

1.      目前可以参考当前的架构设计

对于100万用户同时在线服务器架构和实现,应该从多方面考虑。比如体系的安全性,数据存储和逻辑,流量的负载均衡分配,逻辑数据关键影响度,共享数据的处理等。

客户端和服务器端一般通过不同的协议来完成不同的数据流的交互。而对于协议处理的模块尽可能的放到内部处理,避免其与客户端直接打交道,保证了安全性。而中间的连接服务器就起到了一个代理的功能,连接服务器只负责在客户端和内部处理服务器之间做包的转发功能。

而登陆(网关)服务器控制着用户的认证和负载均衡的。目前比较常用的千兆硬件防火墙,而且同时在游戏应用服务需要软件防火墙。至于安全方面不作为主要考虑中。

其他模块的考虑是功能划分和应用服务器的性能上。主要是数据和逻辑的处理怎样提高效率上,当然一些内存池的使用也是提高应用服务器常用的手段。

在不修改目前服务器层次,考虑的架构图如下:

 

 

2.      登陆服务器

A.     登陆服务器的功能

登陆服务器主要功能:

一个是对客户的密码做验证。

另一个是网关功能,该客户端如果通过验证则把通过查询选择一个负载低连接服务器的ip和端口信息反馈个给客户端,然后客户端就可以直接跟连接服务器通讯。避免连接服务器直接对外,可以有效保护服务器的安全。核心思想是:尽快地提供用户登陆的速度,尽可能方便地让玩家进入游戏中。

简单登陆服务器处理图:

 

B.     登陆服务器负载均衡

目前考虑的支持大用户量的登陆服务器,也是必须使用多台服务器的群均衡负载。服务器群的部署可以使用硬件负载均衡器(f5等,可以设定很多规则,比如限制避免DOS攻击),软件集群也能能好解决,或者考虑使用动态DNS(许多网站解决双网互通时候采用这种策略也是不错解决方案)。

但他们还是有一些问题的。比如采用dns出现一个节点宕机由于缓存的问题导致一部分客户端很长时间不能访问的情。而负载均衡的由于在本地更新快如果出现宕机马上知道,肯定效率高。

从低成本高效率考虑建议采用软件负载均衡技术,并且对单一的登陆服务器登陆用户数量逻辑上做一个限制(比如5k<>20K,魔兽据说采用逻辑循环队列,应对并发用户情况,但大用户时响应时间太慢不可取)这样可以很好解决并发和冗余的问题,并可以方便扩容。保证大用户量的情况下用户响应时间能满足要求。

C.      部署登陆服务器考虑

考虑到同时并发登陆的用户数量,根据服务器的响应时间和带宽做一下估算,由于登陆服务器用户协议实现发送的数据量很小,根据并发用户同时登陆的情况2~4台(QQ的目前是宣称并发登陆20k,如果这样单台处理5k,按照设计并发处理数量应该满足要求)。目前可以考虑分布式架构构建登陆服务器,如上硬件负载均衡器的考虑基本能满足分布架构。这样对服务器维护和扩展比较容易。

目前登陆服务器后台数据库处理作为一个分布式集群,肯定满足要求。

 

3.      连接服务器

A.     连接服务器功能

连接服务器也是跟客户端直接连接的,主要起了数据包转发的功能。连接服务器根据不同的协议把客户端的请求转发到内部不同的应用服务器去,比如逻辑服务器,使比较复杂的和耗资源的逻辑处理等都放到后面应用服务器处理,提高了效率。而连接服务器也是可以实现负载均衡,根据不同的应用服务器的负载情况,选择连接到资源消耗小的应用服务器上。

连接服务器处理图:

B.     连接服务器部署的考虑

由于考虑到服务器许多逻辑上的要求(比如保证一个客户端和一个连接服务器的一个连续的会话),连接服务器通过登陆服务器的直接负载均衡。对于分布也都满足要求,更灵活。

如果单台处理5k那么100万用户量最少需求是200台服务器才能满足要求。把这200

台部署成一组连接服务器的完成负载均衡功能,可以解决大用户量的问题。

4.      其他应用服务器组

A.     逻辑服务器组

处理客户端一些逻辑处理的请求,并维护在线用户表。

采用分布式结构的好处是可以有效分摊整个系统的压力,但是,不足点就是对于全局信息的索引将会变得比较困难,因为每个单独的底层逻辑服务器上都只是存放了自己这一个服务器上的用户数据,它没有办法查找到其它服务器上的用户数据。解决这个问题,简单一点的作法,就是在集群内部,由一个中介者,提供一个全局的玩家列表。这个全局列表,根据需要,可以直接放在管理服务器上,也可以存放在数据库中。

但是单独管理服务器处理在线用户还是由于应用服务器本身的原因用户数量的限制,这也需要采用群集,并采用哈希算法把用户信息分别保存到不同的服务器以便于索引。而这样效率不高,最后确定直接写数据库的方式更合理。可以单独建立一个库存放大量的在线用户索引,可以提高效率,解决目前大用户量的问题。

         在数据库中只保存在线用户的索引,比如用户ID,用户信息保存到那个逻辑服务器上,其他逻辑服务器可以通过索引直接在对应的逻辑服务器查找到该用户的其他在线信息。能很好解决服务器间的互动数据的交互。

 

 

B.     地图服务器组

负责地图相关的信息的处理。

 

C.      模型服务器组

主要负责处理用户地块上物品的上传,下载,更新。而且关键处理用户自造物品的的上传下载等。根据本游戏的需求这个服务器处理的数据量会很大。

D.     交易服务器

处理所有物品交易的逻辑和交易处理,或者通过第三方的交易平台进行现金流处理。

E.      聊天服务器组

目前采用的是jarbberd的服务器,因为目前jarbberd的最大在线用户数50k的数量,所以也要考虑集群解决大用户量的问题。集群能很好解决了这个问题。

 

5.      数据库集群

主要负责处理游戏需要的数据的存储,查询。保证数据的实时性安全性。集群环境下实现多机共享数据库,以保证应用的高可用性。同时可以自动实现并行处理及均分负载,还能实现数据库在故障时的容错和无断点恢复。

可以共享数据库文件,避免同步的影响。同时可以分布跨区域的部署,增加了灵活的部署方案。

部署方案:

一种是基于数据库引擎的模式,ORACLE RAC是共享磁盘的体系结构,用户只需简单地增加一个服务器节点,RAC就能自动地将这节点加入到它的集群服务中去,RAC会自动地将数据分配到这节点上,并且会将接下来的数据库访问自动分布到合适的物理服务器上,而不用修改应用程序;要求数据库引擎本身具有集群功能(一般只有企业版的数据库才具有这功能)。

而另一种是基于数据库网关的结构,需要手工修改数据分区。ICX是一种基于中间件的数据库集群技术,对客户端和数据库服务器都是透明的。可以用来集群几个数据库集群。但成本高,维护难度大。

    所以目前建议采用第一种,oracel RACOracle Real Application Clusters方案,已经基本解决了这些问题。

 

   

 

 

6.      管理服务器

A.     所有应用服务器管理

通过管理服务器,可以对其他的服务器一些数据的查询,比如目前状态,处理数据流量,在线用户数,以及通知各个服务器更新配置,时间同步。

B.     时间同步问题

应服务器可以通过一个全局变量来修改应用服务器的时间

多台服务器会产生时间不同步的问题,为了保障各个服务器时间保持同步。可以通过在管理服务器设置为时间服务器,各个应用服务器跟管理服务器进行同步保障系统时间的同步。而应服务器可以通过一个全局变量来修改应用服务器的时间。

C.      其他全局变量的管理

对服务器最大支持的用户数量,客户端的时间管理等。

 

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值