百万用户同时在线游戏服务器架构实现.doc 基于epoll 通信模型
http://wenku.baidu.com/view/02033d0af78a6529647d53fc.html
百萬用戶在線網絡游戲服務器架構實現
?
一、??????????? 前言
事實上100萬游戲服務器,在面對大量用戶訪問、高并發請求方面,基本的解決方案集中在這樣幾個環節:使用高性能的服務器、高效率的編程語言、高性能的數據庫、還有高性能的架構模型。但是除了這幾個方面,還沒法根本解決面臨的高負載和高并發問題。
當然用戶不斷地追求更高的機器性能,而升級單一的服務器系統,往往造成過高的投入和維護成本,性價比大大低于預期。同時全天候的可用性的要求也不能滿足要求,如果服務器出現故障則該項服務肯定會終止。所以單獨追求高性能的服務器不能滿足要求,目前基本的解決方案是使用集群技術做負載均衡,可以把整體性能不高的服務器做成高可擴展性,高可用性,高性能的,滿足目前的要求。
目前解決客戶端和服務器進行底層通訊的交互的雙向I/O模型的服務器的成熟方案。
1.windows下,比較成熟的技術是采用IOCP,完成端口的服務器模型。
2.Linux下,比較成熟的技術是采用Epoll服務器模型, Linux?2.6內核中提供的System?Epoll為我們提供了一套完美的解決方案。
目前如上服務器模型是完全可以達到5K到20K的同時在線量的。但5K這樣的數值離百萬這樣的數值實在相差太大了,所以,百萬人的同時在線是單臺服務器肯定無法實現的。
而且目前幾個比較成熟的開發框架,比如ICE,ACE等。這樣,當采用一種新的通信技術來實現通信底層時,框架本身就不用做任何修改了(或修改很少),而功能很容易實現,性能達到最優。目前采用的ace框架個不錯的選擇方案,可以不受操作系統的影響,移植比較方便。
對于數據庫選擇可有許多成熟的方案,目前大多數選擇的mysql Master/slave模式,以及oracle? RAC方案。基本可以滿足目前的要求,但具體的瓶頸不是在數據庫本身,應該還是硬件磁盤I/O的影響更大些。建議使用盤陣。這有其他成熟的方案,比如采用NAS解決分布數據存儲。
其實最為關鍵的是服務器的架構和實現,數據流量的負載均衡,體系的安全性,關鍵影響度,共享數據的處理等等多個方面對100萬用戶的數據處理有影響,所以都要全面的考慮。
?
二、??????????? 高性能的服務器
?
1.????? 網絡環境
目前采用Client/Server架構來開發網絡游戲,客戶端和服務器一般通過TCP/UDP協議進行通信,關鍵瓶頸很明確--游戲服務器與客戶機之間的鏈路。目前單機環境比較好些的是,2塊1000M網卡,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平臺上很多免費開源的集群軟件,如LVS(Linux 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
這里用了Deadline的I/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 1024為65536
#define NR_FILE 8192為65536
#define NR_RESERVED_FILES 10為128
設置最大打開文件數量(TCP連接數量)
修改/usr/src/linux/include/net/tcp.h
#define TCP_TIMEWAIT_LEN (60*HZ) 為1*HZ
#define TCP_SYNACK_RETRIES? 5為3?
設置在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框架實現,是完全可以達到5K到20K的同時在線量的,而且消耗系統資源小。但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 RAC(Oracle Real Application Clusters)方案,已經基本解決了這些問題。
?
? ?
?
?
6.????? 管理服務器
A.???? 所有應用服務器管理
通過管理服務器,可以對其他的服務器一些數據的查詢,比如目前狀態,處理數據流量,在線用戶數,以及通知各個服務器更新配置,時間同步。
B.???? 時間同步問題
應服務器可以通過一個全局變量來修改應用服務器的時間
多臺服務器會產生時間不同步的問題,為了保障各個服務器時間保持同步。可以通過在管理服務器設置為時間服務器,各個應用服務器跟管理服務器進行同步保障系統時間的同步。而應服務器可以通過一個全局變量來修改應用服務器的時間。
C.????? 其他全局變量的管理
對服務器最大支持的用戶數量,客戶端的時間管理等。
?
總結
以上是生活随笔為你收集整理的百万用户同时在线游戏服务器架构实现.doc 基于epoll 通信模型的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: element-ui vue-quill
- 下一篇: 如何短时间突击 Java面试?附刷题神器