freepeople性欧美熟妇, 色戒完整版无删减158分钟hd, 无码精品国产vα在线观看DVD, 丰满少妇伦精品无码专区在线观看,艾栗栗与纹身男宾馆3p50分钟,国产AV片在线观看,黑人与美女高潮,18岁女RAPPERDISSSUBS,国产手机在机看影片

正文內(nèi)容

游戲服務器架構(gòu)-預覽頁

2024-10-13 20:02 上一頁面

下一頁面
 

【正文】 那你可以自豪地告訴你的策劃,多設(shè)計些大量消耗服務器資源的玩法吧,比如大型國戰(zhàn)、公會戰(zhàn)爭等。我知道,有人一定會說,才帶2000人,那是你水平不行,我隨便寫個TCP服務器都可帶個五六千連接。再回過頭來看看我們想要實現(xiàn)的結(jié)構(gòu),我們既想要有一個唯一的入口,使得客戶端不用頻繁改變連接,又希望這個唯一入口的負載不會太大,以致于接受不了多少連接。事實上,在大多數(shù)游戲的大部分時間里,這個數(shù)字也是很讓人眼紅的。一般來說,我們把這臺負責連接管理的服務器稱為網(wǎng)關(guān)服務器,因為內(nèi)部的數(shù)據(jù)都要通過這個網(wǎng)關(guān)才能出去,不過從這臺服務器提供的功能來看,稱其為反向代理服務器可能更合適。最后的結(jié)構(gòu)看起來大概是這樣的:Zone Server Zone ServerMaster Server Master ServerGateway Server Center ServerClient服務器結(jié)構(gòu)探討最終的結(jié)構(gòu)如果我們就此打住,可能馬上就會有人要嗤之以鼻了,就這點古董級的技術(shù)也敢出來現(xiàn)。新增加了網(wǎng)關(guān)服后需要在大區(qū)服上做相應的支持,或者再簡單點,有一臺主要的網(wǎng)關(guān)服,當其負載較高時,主動將新到達的連接重定向到其他網(wǎng)關(guān)服上。既然說到了優(yōu)化,我們也稍稍考慮一下現(xiàn)在結(jié)構(gòu)下可能采用的優(yōu)化方案。還有聊天處理邏輯,這部分與游戲邏輯沒有任何關(guān)聯(lián),我們也完全可以將其獨立出來,放到一臺單獨的聊天服務器上去實現(xiàn)。好比我們?nèi)タ匆粓鐾頃枧_上演員們按著預定的節(jié)目單有序地上演著,但這就是整場晚會的全部嗎?顯然不止,在幕后還有太多太多的人在忙碌著,甚至在晚會前和晚會后都有。GM可以采用跟普通玩家一樣的拉入方式來進入游戲,當然權(quán)限會比普通玩家高一些,也可以提供一臺GM服務器專門用來處理GM命令,這樣可以有更高的安全性,GM服一般接在中心服務器上。至于搜集玩家機器資料所涉及到的法律問題不是我們該考慮的。突然發(fā)現(xiàn)自己一旦羅嗦起來還真是沒完沒了。決定了OS也就基本上確定了網(wǎng)絡(luò)IO模型,windows上的IOCP和linux下的epool,或者直接使用現(xiàn)有的網(wǎng)絡(luò)框架,如ACE和asio等,其他還有些商業(yè)的網(wǎng)絡(luò)庫在國內(nèi)的使用好像沒有見到,不符合中國國情嘛。還有消息包格式的定義,這個曾在云風的blog上展開過激烈的爭論。而且,以特殊字符做分隔的消息包定義還加大了一點點網(wǎng)絡(luò)數(shù)據(jù)量。在服務器上port是監(jiān)聽用的,想象這樣一種情況,web server在80端口上監(jiān)聽,當一個連接到來時,系統(tǒng)會為這個連接分配一個socket句柄,同時與其在80端口上進行通訊;當另一個連接到來時,服務器仍然在80端口與之通信,只是分配的socket句柄不一樣。第三篇:百萬用戶級游戲服務器架構(gòu)設(shè)計百萬用戶級游戲服務器架構(gòu)設(shè)計服務器結(jié)構(gòu)探討最簡單的結(jié)構(gòu)所謂服務器結(jié)構(gòu),也就是如何將服務器各部分合理地安排,以實現(xiàn)最初的功能需求。對于一個最簡單的游戲服務器來說,它只需要能夠接受來自客戶端的連接請求,然后處理客戶端在游戲世界中的移動及交互,也即游戲邏輯處理即可。但不管是采用何種方式進入,照目前看來我們的服務器起碼得提供一個帳號驗證的功能。這樣,我們可為每組服務器單獨配備一臺登錄服。該結(jié)構(gòu)存在一個服務器資源配置的問題。所以,我們能否更合理地配置登錄服資源,使得整個大區(qū)內(nèi)的登錄服可以共享就成了下一步改進的目標。正如我們之前所描述過的那樣,登錄服在大多數(shù)情況下都是比較空閑的,也許我們的一個擁有20個游戲世界的大區(qū)僅僅使用10臺或更少的登錄服即可滿足需求。還是拿開新區(qū)的情況來說,即使新增加登錄服滿足了玩家登錄的請求,游戲世界服的承載能力依然有限,玩家一樣只能在排隊系統(tǒng)中等待,或者是進入到游戲世界中導致大家都卡。我們需要持久化的數(shù)據(jù)有玩家的帳號及密碼,玩家創(chuàng)建的角色相關(guān)信息,另外還有一些游戲世界全局共有數(shù)據(jù)也需要持久化。最新的DNS服務已實現(xiàn)了根據(jù)服務器系統(tǒng)狀態(tài)來實現(xiàn)的動態(tài)負載均衡,也就是實現(xiàn)了真正意義上的負載均衡,這樣也就有效地解決了當某臺登錄服當機后,DNS服務器不能立即做出反應的問題。從數(shù)據(jù)庫服務器的部署上來說,可以將帳號和角色數(shù)據(jù)都放在一個中心數(shù)據(jù)庫中,也可分為兩個不同的庫分別來處理,基到從物理上分到兩臺不同的服務器上去也行。最后,我們的服務器結(jié)構(gòu)就像這樣:大區(qū)服務器/|/|登錄服1登錄服2世界服1世界服2||||||帳號數(shù)據(jù)庫DBSDBS這里既然討論到了大區(qū)及帳號數(shù)據(jù)庫,所以順帶也說一下關(guān)于激活大區(qū)的概念。這個激活的過程也就是從中心庫上把我們的帳號數(shù)據(jù)拷貝到所要到的大區(qū)帳號數(shù)據(jù)庫中。在所有這些基礎(chǔ)邏輯中,與我們要討論的服務器結(jié)構(gòu)關(guān)系最緊密的當屬地圖管理方式??梢赃@樣認為,一塊地圖就是一個獨立的數(shù)據(jù)處理單元。正如俗語所說的那樣,三個和尚可能會碰到?jīng)]水喝的情況。先稱它為游戲世界的中心服務器吧,畢竟是管理者嘛,大家都以它為中心。我們來看看結(jié)構(gòu)圖是怎樣的:中心服務器/ / 登錄服 地圖1 地圖2 地圖n | / / | / /客戶端很簡單,不是嗎。客戶端只需要連接到中心服上,所有到地圖服務器的數(shù)據(jù)都由中心服來轉(zhuǎn)發(fā)。我們將地圖服務器分開來原來也是想將負載分開,以多帶些客戶端,現(xiàn)在要所有的連接都從中心服上轉(zhuǎn)發(fā),那連接數(shù)又遇到單臺服務器的可最大承載量的瓶頸了。如果一個演示socket API用的echo服務器就能滿足MMOG服務器的需求,那寫服務器該是件多么愜意的事啊。既然如此,那五六千個連接也還有滿足我們的要求。你知道大陸現(xiàn)在有多少游戲在運營嗎?或許你又該說,我們不該在一開始就把自己的目標定的太低!好吧,我們還是先不談這個。網(wǎng)關(guān)之后的結(jié)構(gòu)我們依然可以采用之前描述的方案,只是,似乎并沒有必要為每一個地圖都開一個獨立的監(jiān)聽端口了。一般來說,當某一部分能力達不到我們的要求時,最簡單的解決方法就是在此多投入一點資源。每個代表客戶端玩家的對象內(nèi)部都保留一個代表其連接的對象,消息廣播時要求每個玩家對象使用自己的連接對象發(fā)送數(shù)據(jù)即可,至于連接是在什么地方,那是完全透明的。這其中最消耗系統(tǒng)資源的當屬生物的AI處理了,尤其是那些復雜的尋路算法,所以我們可以考慮把這部分AI邏輯獨立出來,由一臺單獨的AI服務器來承擔。緩存的數(shù)據(jù)會定時的寫入到后臺數(shù)據(jù)庫中。在之前描述的部分就如同舞臺上的演員,是我們能直接看到的,幕后的工作人員我們也來認識一下。任何為用戶提供服務的地方都會有日志記錄,游戲服務器當然也不例外。服務器結(jié)構(gòu)探討一點雜談再強調(diào)一下,服務器結(jié)構(gòu)本無所謂好壞,只有是否適合自己。首先是服務器操作系統(tǒng),linux與windows之爭隨處可見,其實在大多數(shù)情況下這不是我們所能決定的,似乎各大公司也基本都有了自己的傳統(tǒng),如網(wǎng)易的freebsd,騰訊的linux等。早期選擇UDP的主要原因還是帶寬限制,現(xiàn)在寬帶普通的情況下TCP比UDP多出來的一點點開銷與開發(fā)的便利性相比已經(jīng)不算什么了。另外早期有些游戲的包格式定義是以特殊字符作分隔的,這樣一個好處是其中某個包出現(xiàn)錯誤后我們的游戲還能繼續(xù)。開始學習網(wǎng)絡(luò)編程的時候我犯過這樣的錯誤,以為port的定義為unsigned short,所以想當然的認為服務器的最大連接數(shù)為65535,這會是一個硬性的限制。按windows網(wǎng)絡(luò)編程第二版上的說法,這個上限值配置影響。想象一下帳號驗證的實現(xiàn)方法,最容易的那就是把用戶輸入的明文用帳號和密碼直接發(fā)給登錄服,服務器根據(jù)帳號從數(shù)據(jù)庫中取出密碼,與用戶輸入的密碼相比較。哦,如果我們只是希望密碼不可能被還原出來,那還不容易嗎,使用一個不可逆的散列算法就行了。慢著,外掛偷密碼的目的是什么?是為了能用我們的帳號進游戲!如果我們總是用一種固定的算法來對密碼做散列,那外掛只需要記住這個散列后的字串就行了,用這個做密碼就可以成功登錄。這其中之一是一個叫做SRP的算法,全稱叫做Secure Remote Password,即安全遠程密碼。登錄服除了帳號驗證外還得提供另一項功能,就是在玩家的帳號驗證成功后返回給他一個服務器列表讓他去選擇。好了,登錄服要實現(xiàn)的功能就這些,很簡單,是吧。那我們就先來看看,游戲服務器代碼實現(xiàn)中,main函數(shù)都做了些什么。登錄服中唯一的這一個線程,也就是主循環(huán)線程對監(jiān)聽的socket做select操作,為每個連接進來的客戶端讀取其上的數(shù)據(jù)并立即進行處理,直到服務器收到SIGABRT或SIGBREAK信號時結(jié)束。只是,在對性能要求比較高的服務器上,select一般不會是最好的選擇。數(shù)據(jù)庫的處理也類似,會使用異步的方式,也是避免耗時的查詢過程將游戲服務器主循環(huán)阻塞住。當然,也有把這些分享到單獨的進程中去做的。主邏輯循環(huán)的結(jié)構(gòu)還是很簡單的,復雜的部分都在如何處理這些消息包的邏輯上。很簡單,讓那些獨立的IO線程在接收完數(shù)據(jù)后自己送過來就是了。}網(wǎng)絡(luò)IO,數(shù)據(jù)庫IO線程把整理好的消息包都加入到主邏輯循環(huán)線程的這個消息隊列中便返回。實現(xiàn)雖然簡單,但功能是絕對滿足需求的,只是性能上可能稍稍有些不盡如人意。網(wǎng)絡(luò)IO線程要給邏輯線程投遞消息時,會從隊列容器中取一個空隊列來使用,直到將該隊列填滿后再放回容器中換另一個空隊列。那這樣有時也會出現(xiàn)IO線程未寫滿一個隊列,而邏輯線程又沒有數(shù)據(jù)可處理的情況,特別是當數(shù)據(jù)量很少時可能會很容易出現(xiàn)。所以,這種方案下加鎖的次數(shù)會比較多一些,IO線程每次寫隊列時都要加鎖,邏輯線程在調(diào)換隊列時也需要加鎖,但邏輯線程在讀隊列時是不需要加鎖的。Ghost Cheng的方案因為提供了多個隊列,可以使得多個IO線程可以總工程師的,互不干擾的使用自己的隊列,只是還有一個遺留問題我們還不了解其解決方法。也許我們可以使用內(nèi)存池,比如SGI STL中附帶的小內(nèi)存分配器。那要是追的人跑的太慢,跑的人轉(zhuǎn)了一圈過來反追上追的人了呢?那您也先歇會兒吧。至于為什么,不需要多做解釋了吧??梢俏覀兪褂昧饲懊娼榻B的優(yōu)化方案后,可能這里便不再需要環(huán)形緩沖區(qū)了,至少我們并不再需要他們是環(huán)形的了。一般來說最直接的方法就是邏輯線程什么時候想發(fā)數(shù)據(jù)了就直接調(diào)用相關(guān)的socket API發(fā)送,這要求服務器的玩家對象中保存其連接的socket句柄。如果使用全局緩沖區(qū)的話,那我們可以再進一步,使用一個獨立的線程來處理數(shù)據(jù)發(fā)送,類似于邏輯線程對數(shù)據(jù)的處理方式,這個獨立發(fā)送線程也維護一個消息隊列,邏輯線程要發(fā)數(shù)據(jù)時也只是把數(shù)據(jù)加入到這個隊列中,發(fā)送線程循環(huán)取包來執(zhí)行send調(diào)用,這時的阻塞也就不會對邏輯線程有任何影響了。服務器公共組件實現(xiàn)狀態(tài)機有關(guān)State模式的設(shè)計意圖及實現(xiàn)就不從設(shè)計模式中摘抄了,我們只來看看游戲服務器編程中如何使用State設(shè)計模式。}。我們再來看看設(shè)計模式中對State模式的說明,其中關(guān)于State模式適用情況里有一條,當操作中含有龐大的多分支的條件語句,且這些分支依賴于該對象的狀態(tài),這個狀態(tài)通常用一個或多個枚舉變量表示。然后,按照State模式的描述,我們還需要一個Context類,也就是狀態(tài)機管理類,用以管理當前的狀態(tài)類。}。我們的邏輯處理類會從MachineBase派生,當取出數(shù)據(jù)包后交給當前狀態(tài)處理,前面描述的兩個狀態(tài)類從StateBase派生,每個狀態(tài)類只處理該狀態(tài)標識下需要處理的消息。使用狀態(tài)機雖然避免了復雜的判斷語句,但也引入了新的麻煩。放到我們今天討論的State模式中,就拿登錄服所處理的兩個狀態(tài)來說,也許用mangos所采用的遍歷處理函數(shù)的方法可能更簡單,但當系統(tǒng)中的狀態(tài)數(shù)量增多,狀態(tài)標識也變多的時候,State模式就顯得尤其重要了。有些類似于QT中的event與signal,我將一些動作請求消息定義為事件,而將狀態(tài)改變消息定義為信號。仔細來看,事件與信號其實并無多大差別,從我們對其需求上來說,都只要能注冊事件或信號響應函數(shù),在事件或信號產(chǎn)生時能夠被通知到即可。這一功能需求在游戲服務器上是到處存在的。在QT中,事件因為都是與窗口相關(guān)的,所以事件回調(diào)時都是從當前窗口開始,一級一級向上派發(fā),直到有一個窗口返回true,截斷了事件的處理為止。在QT中,事件使用了一個事件隊列來維護,如果事件的處理中又產(chǎn)生了新的事件,那么新的事件會加入到隊列尾,直到當前事件處理完畢后,QApplication再去隊列頭取下一個事件來處理。關(guān)于事件機制的考慮其實還很多,但都是一些不成熟的想法。關(guān)于登錄服、大區(qū)服及游戲世界服的結(jié)構(gòu)之前已做過探討,這里再把各自的職責和關(guān)系列一下。GateWay/WorldServer為各個獨立的世界服或者通過網(wǎng)關(guān)連接到后面的世界服。但是當下一次服務器再維護后,所有的世界服都不存在了,全部重新開始添加。WorldServerMgr內(nèi)部的實現(xiàn)很簡單,監(jiān)聽一個固定的端口,接受來自WorldServer的主動連接,并檢測其狀態(tài)。這個或許就可以用前面描述過的事件方式,或者就是觀察者模式了。三個狀態(tài)的轉(zhuǎn)換流程大致為:LogonState驗證成功版本檢查版本低于最新值轉(zhuǎn)到UpdateState |版本等于最新值轉(zhuǎn)到WorldState這個版本檢查的和決定下一個狀態(tài)的過程是在LogonState中進行的,下一個狀態(tài)的選擇是由當前狀態(tài)來決定。世界選擇狀態(tài)則提供了一個列表給客戶端,其中包括了所有游戲世界網(wǎng)關(guān)服務器的IP、PORT和當前負載情況。與此同時,與登錄服的連接還沒有斷開,直到客戶端確實連接上了選定的世界服并且走完了排隊過程為止。這時,乘務員會客氣地告訴你要先換登機牌,那登機牌又從哪來?檢票口換的,人家會先驗明你的身份,確認后才會發(fā)給你登機牌??墒?,那么多的LoginServer,要一個個問下來,這效率也太低了,后面排的長隊一定會開始叫喚了。而不管在哪里,這個查詢的壓力都是有點大的,想想,全區(qū)所有玩家呢。讓我們來詳細描述一下這個過程,客戶端在LoginServer上驗證通過時,LoginServer為其生成了本次會話的session key,但只是保存在當前的LoginServer上,不會存數(shù)據(jù)庫,也不會發(fā)送給WorldServerMgr。同時,所有服務器上的session key在連接關(guān)閉后一定會被刪除,保證一個session key真正只為一次連接會話服務。因此作為個人沒時間也不可能對每一區(qū)域都了
點擊復制文檔內(nèi)容
環(huán)評公示相關(guān)推薦
文庫吧 www.dybbs8.com
備案圖鄂ICP備17016276號-1