雲遊戲的架構設計和技術實現

雲遊戲的架構設計和技術實現

首先簡單做個自我介紹。我本人主要是從事遊戲行業的,經歷比較複雜,早年做 PC 端網遊,然後又做了幾年虛擬現實,接着又做頁遊和手遊, 現在主要是做 HTML5 遊戲。這跟雲計算可能有點遠,但是我個人對雲計算技術很感興趣,所以業餘也會關心這項技術的發展。所以就有了這樣一個遊戲和雲計算相結合的項目,這是我去年跟上海勱馳數字技術有限公司合作的項目,我作爲技術顧問參與了這個項目的架構設計和一些核心技術的研發。



什麼是雲遊戲?

雲遊戲這個概念非常簡單,就是我把遊戲放到服務器上去運行,把遊戲渲染出來的的音視頻畫面,通過流的形式傳送到終端,終端上不再需要安裝遊戲,各種終端比如說電視、手機、PC、平板都可以運行。這樣我們就不需要關心遊戲怎麼去適配不同的軟硬件平臺、終端性能夠不夠等等這些問題。這個概念本身是非常好的,在2009年的時候,這個技術就已經出現了,美國有家叫Onlive 的公司第一個推出雲遊戲服務,但是他最終在商業上還是失敗了,技術最後被索尼公司收購,並運用在PS Now上。雲遊戲的概念雖然非常好,但裏面技術挑戰性非常高,有非常多的技術問題需要解決,那個時代可能還比較早,軟硬件都還不太成熟,所以最後沒有能夠成功的商業化。到了現在這個時間點上,雲遊戲技術開始慢慢成熟起來,已經具備了商業化的基礎。



下面是對我們產品的介紹。對雲遊戲來說,用戶主要會關心延遲問題,玩一個對抗性很強的遊戲,如果中間卡個幾百毫秒那肯定受不了,遊戲體驗就會非常差。所以我們最核心的關注點就是要把延遲降低到最小、並且把畫質保持在一個相對可以接受的程度。目前我們產品的整體延遲(從用戶按下操作按鈕到看到畫面變化)可以控制到50毫秒以下,在這樣的延遲水平下玩格鬥遊戲賽車遊戲感覺都是非常流暢的,畫面可以支持到720P/1080P,網絡帶寬只要4兆以上就可以了。我們單臺服務器可以支持 20-50 路的併發遊戲數量,也就是單臺服務器可以同時爲 50 個玩家提供服務,單個併發用戶的整體服務器硬件成本在500元左右,可以說是一個非常有競爭力的成本。當年 OnLive 失敗的主要原因是因爲他的硬件成本非常高,他的一臺服務器僅能服務一個用戶,單個併發用戶的成本可能就要上萬,在這樣的成本水平上要實現商業上的成功是非常困難的。目前這個項目已經在小範圍的內測,他們主要是 toB 的業務,爲寬帶運營商提供增值遊戲服務。



雲遊戲的技術挑戰

第一個是實時性

遊戲的整體延遲包括了遊戲邏輯運算時間、音畫渲染的時間,加上編碼的延時、網路傳輸的延時、客戶端解碼的延時、客戶端向服務端發送控制信息的延時,雲遊戲的實時性要達到一個可令玩家接受的程度,這個技術挑戰是非常高的,當然也要依靠硬件和網絡本身的性能,如果沒有足夠的帶寬也不可能做到。

第二是虛擬化技術

虛擬化在服務端已經非常成熟,我們有虛擬機技術以及各種容器技術,但是在桌面上就不是那麼成熟,普通的虛擬桌面不支持 GPU 的虛擬化,而遊戲非常依賴 GPU 渲染,若沒有 GPU 的虛擬化就沒辦法實現雲遊戲了,所以虛擬化是一個很大的技術瓶頸。

第三是經濟性

每個併發用戶的服務器硬件成本關係到這個模式能否成功商業化,如果成本超出了用戶可接受的範圍,那就沒有辦法實現盈利。

最後是運維管理

雲遊戲的運維管理跟傳統的服務器運維管理不一樣,因爲用到的服務器硬件不一樣,同時硬件負載又很高,這對運維管理提出了新的挑戰,所以在技術上就要解決這些問題。



平臺選擇

遊戲的運行平臺非常多,各種各樣,但是比較適合的只有windows平臺。Linux 平臺雖然開放,但是它沒有什麼遊戲支持,其他的主機遊戲平臺基本都屬於封閉技術,微軟和索尼自己都在研發主機上的雲遊戲,那我們是沒有辦法去做的。

android平臺也是非常適合做雲遊戲。服務器跑個android遊戲再傳到android設備上這個概念看上去比較怪異,但實際上IPTV運營商非常喜歡這個概念,因爲機頂盒不允許安裝第三方的應用,監控比較嚴,那我們通過雲端化來繞過這種限制,這對機頂盒這種產品非常有幫助,所以android平臺也是我們要考慮的。但今天主要是介紹 windows 平臺遊戲的虛擬化,android上是用硬件方案跑的,所以就不介紹了。

windows遊戲的虛擬化技術主要是兩條路線。一個是虛擬機方案,但主要問題是 GPU 虛擬化技術不成熟,可能需要一些專業級的顯卡支持,成本非常高、性能損耗非常大,每一個遊戲都跑一個 Guest OS 非常浪費內存,所以這條方案就被我們否掉了。同時windows 上也缺少可用的容器級技術,我們只能採取 API Hook 方式手工實現虛擬化,我們稱之爲 Sandbox 方案。

Sandbox方案就是把遊戲所用到的系統 API 全部hook接管,讓遊戲認爲自己運行在一個正常的 OS 上面,但實際上是我們接管的一個 OS。這樣做的好處是性能損耗很小,基本上沒有額外的損耗,但是比較痛苦的要針對每個 API 做適配,需要對每個遊戲進行適配,而且遊戲通常不開源,遊戲開發商通常也不會配合你去修改代碼,需要一些 hack 技術來針對每個遊戲做適配。



技術實現細節

圖像和聲音的採集

圖形API有 DirectX 9,10,11,12還有OpenGL,接管這些API後我們就可以把畫面重定向到視頻編碼器,不不在屏幕上輸出了。音頻比較簡單,只要接管Windows Audio Session API就可以了。

輸入操作的虛擬化

手柄比較麻煩,因爲手柄支持的API接口比較多樣化,比如 DirectInput, XInput, RawInput,還有些遊戲直接讀 USB 設備,實現這些API的接管工作是比較瑣碎的。

存儲的虛擬化分

一是遊戲的資源部分,比如執行程序、圖片、聲音等等。這些資源文件都是隻讀的,需要一個共享存儲來放這些文件,因爲這些文件體積比較大,通常一個遊戲需要幾十個G的容量,如果全部都放在本地節點上的話,對節點的存儲容量要求很大,而且以後更新維護起來也比較困難。所以我們用 NAS 來共享這些文件,這麼做的網絡 I/O 開銷會非常大,後面我會介紹如何來優化這一塊。第二是用戶配置和存檔數據等等可變數據,這些數據需要集中化存儲,同時可能存在跨機房的訪問需求。用戶離機房越近延遲越小,所以需要多地、異地部署服務器,讓玩家在全球漫遊訪問你的服務,這需要有跨機房文件共享的能力。

其他需要適配的內容

比如遊戲一般都是單實例,我們需要繞過遊戲的防多啓動機制。還有些遊戲無法後臺窗口運行,我們需要通過 API Hook 的方式,讓遊戲認爲它處於一個正常的狀態。最理想的適配方式是通過 SDK,讓 CP 來適配你的雲遊戲平臺,但目前來說還不實際,因爲雲遊戲的商業化還沒有完全的落地,需要技術去慢慢的推進。



音視頻編碼技術

視頻流採用的是 H.264 編碼,主要是 720P/1080P@30fps,1080P@60fps 對網絡和硬件的要求過高,暫時還做不到。音頻編碼使用AAC。因爲標準的封裝格式不含控制流,不能傳輸用戶的操作數據,所以我們自己定義了一種封裝格式,簡單的把 H.264 和 AAC 的裸流封裝起來傳送給客戶端。

目前用軟件編碼器基本不可行,一路視頻編碼就要消耗掉一個CPU核的資源,跑個三四路就把 CPU 資源吃光了,遊戲就沒辦法運行了。幸運的是三大硬件廠商 Intel、AMD 和 NVIDIA 都推出了自己的硬件編碼器,Intel的CPU自帶硬件編碼器,支持20+路的720P實時編碼沒有問題。NVIDIA 的硬件編碼性能更高,可以直接對GPU的 FrameBuffer 做編碼並傳到 CPU 上,節省了很多內存的拷貝,性能是最好的。

視頻編碼的參數調優

首先避免使用 B 幀以減小延遲;較大的 GOP 設置來減少 I 幀的比例,保證每一幀消耗的碼率都在一個最大可控的範圍內;0 延遲設置,保證每輸入一幀數據編碼器都立刻輸出這幀的編碼數據,避免編碼器緩衝幀數據;bitrate控制,使用固定比特率的算法是不適合的,因爲遊戲中經常會存在一段時間的靜止畫面,此時比特率很低,對接下來的變化幀編碼器就會分配大量的比特來編碼,這就會造成這一幀數據特別巨大,從而帶來了額外的網絡數據傳輸延遲。所以我們採用了自適應算法,在保證比特率總體在最大範圍內的同時,保證每一幀消耗的碼率都在一個最大可控的範圍內,確保每幀的數據傳輸延遲可控。

終端的視頻解碼優化

H264 的解碼是比較頭疼的,因爲android平臺適配起來比較痛苦,尤其是它的硬件解碼坑非常多。如果直接使用mediacodec封裝的硬件解碼器,那個延遲非常高,基本沒有辦法用。有一些芯片廠商會提供一個後門,讓你把緩衝關掉直接輸出畫面,但是這需要對接具體的芯片廠商,無法做到通用,只適合一些機頂盒類的產品。所以還是需要用軟件解碼的方式來支持 0 延遲的輸出。android設備的性能參差不齊,早期的低端芯片性能不滿足實時解碼 ,需要利用 GPU 做一些加速。

網絡傳輸的優化

用UDP傳輸的話,因爲H264 本身不支持容錯,一旦丟包就會出現花屏,在下一個I幀到來前都無法恢復,通常要持續好幾秒,嚴重影響用戶體驗,無法接受;而TCP 丟包的話只是出現幾百毫秒的卡頓,實測還是可以接受的,所以我們放棄了 UDP 協議傳輸,利用TCP在網絡層做一些調優使延遲降低。實測下來,現在的寬帶網絡延遲基本沒有問題,主要問題反而是在用戶側的 WiFi 上,一旦出現無線信號干擾,網絡抖動會比較厲害。

服務器和客戶端的同步算法

我們的雲遊戲把所有環節的緩衝都關掉了,全部是零延遲自出,原來緩衝設計的目的就是爲了抵抗顛簸,比如網絡的顛簸、或某一個編解碼環節出現了抖動,通過緩衝把這個抖動抹平,現在把緩衝都關掉後對同步會造成很大的影響。有很多因素會造成顛簸,比如服務器發送數據過快,客戶端來不及消費,造成的結果就是延遲非常大。所以我們自己設計了一套算法來解決這個同步的問題。具體的做法就是讓客戶端在完成一幀畫面的顯示後向服務器反饋一個消息,服務端根據客戶端反饋的消息就知道客戶端消費到了第幾幀,跟服務器現在編碼的幀數做比較,在一定的閾值內就繼續傳輸下一幀,否則等待客戶端的確認消息,直到客戶端趕上來。這樣做的結果就是當顛簸發生時服務器能及時感知並停止發送數據,等顛簸消除後再繼續發送最新的遊戲畫面,實測下來獲得了比較理想的同步效果。

存儲的優化。只讀資源數據是放在 NAS 上的,幾百個遊戲共享一個 NAS,加載遊戲時的網絡 I/O 開銷非常大,所以我們做了一個優化來本地緩存這些共享文件,利用dokan實現了一個虛擬磁盤來訪問資源文件,再把虛擬磁盤重定向到NAS上,同時利用節點的本地 SSD 硬盤來緩存熱點文件,從而降低了網絡 I/O 的開銷。

更多的雲遊戲玩法

旁觀模式,一個玩家玩的時候其他玩家可以接入這個視頻流,看他怎麼玩;對戰模式,其他玩家可以切到這個遊戲流裏面兩個人在一起對戰;還有直播模式,把視頻流封裝爲 HLS,推送到 CDN 上進行直播,這是非常流行的主播模式,雲遊戲都可以支持。



雲遊戲運維方面的挑戰

雲遊戲需要維護大量的服務器節點,而且跟普通的服務器管理不一樣,需要自己造一些輪子。由於所有的硬件資源都是高負荷運行,我們要最大化的增加硬件利用率,一般的服務器 CPU 佔 10% 就很不錯了,而云遊戲的 CPU 都是在接近 100% 的情況下運行,另外還需要GPU的參與,這導致了硬件的可靠性相對比較低。

軟件因爲沒有隔離性,可靠性也會降低,一旦出現問題怎麼維護、怎麼恢復,成了比較麻煩的問題,因爲沒有現成的方案,就我們需要自己設計服務器集羣來解決這些問題。另外還有跨機房部署的問題。

硬件方案的選型,我們主要有三套方案,一套是 GRID 顯卡方案,這是 NVIDIA 爲雲遊戲專門設計的專業顯卡,上面帶有編碼器可以將遊戲畫面直接編碼輸出,但它的缺點是價格比較昂貴,一臺服務器的硬件成本大約在 5 萬元左右。

還有就是消費級獨顯方案,去掉了昂貴的專業顯卡的同時還能獲得更好的GPU性能,所以這套方案的性價比要高很多,每路併發的硬件成本可以降低到 500 元以下。

最後一個方案是 Intel 核顯方案。完全不需要用獨立顯卡,但 Intel 核心顯卡的性能偏弱,運行大型的 3D 遊戲會比較吃力,運行一些休閒遊戲沒有問題。這個方案的優點是不需要顯卡,1U 的尺寸下可以裝入多個節點,集成度提高,而且易於維護,也是一個值得考慮的方案。

下面來解釋一下雲遊戲一下集羣的概念。Node(節點)對應一臺物理計算機,一個節點可以同時運行多個遊戲實例爲用戶提供服務。多個節點組成一個 Group(節點組),一個Group內包含了若干節點和NAS,對應於一個機櫃, 多個機櫃用萬兆交換機串連起來,部署在一個機房,稱之爲 Cluster(集羣),再上面一層是雲遊戲平臺,包括用戶的入口管理、登錄計費等,可以跨越多個機房。

下圖是系統架構圖:






User Profile Storage  用來存放用戶的存檔數據,Log Storage 用來存儲日誌數據,還有數庫等等。

Group 內的各 Node 組成對等網絡,可以任意添加或者刪除 Node,各個 Node 通過競爭算法選舉出來一個 Master,由 Master 與 Manager 建立連接,對整個 Group 進行管理,如果Master出現故障則由剩餘的節點重新選舉出一個新的Master進行接管,從而保證了任何節點的故障不會影響到其他節點的正常服務。在Node 上僅需要安裝好操作系統和 Daemon 服務,無須配置,即插即用。Node daemon對服務器進行管理和監控;遊戲文件存放於 NAS 上,由各 Node 共享;內網/外網流量隔離,防止互相影響。

Manager 用於對集羣內的所有 Node 進行管理, 配置/更新/上線/負載均衡/監控,遊戲數據管理更新,用戶數據管理等等。提供 web 後臺給運維操作,實現運維的自動化和可視化操作。Manager使用雙機熱備模式實現高可用,避免單點故障造成整體系統癱瘓。

日誌和監控。我們需要有完整的日誌來記錄和追蹤系統行爲,保障整個系統的可維護性。同時系統會實時監控每個遊戲實例以及 Node 的狀態,包括 cpu、gpu、網絡io 的使用率,遊戲幀率、延遲等等數據,所有數據保存下來,後面可以通過一些數據分析的手段來找到性能的瓶頸,然後再針對性的進行優化,進一步優化我們的系統。

   

提問:對家用的wifi做一些支持,能詳細說說嗎?

喬捷:首先,要提示用戶wifi信號不好會造成延遲,終端檢測到網絡信號不好時及時的提示用戶。其次,對於網絡延遲的抖動,我們的同步控制算法能夠補償一部分抖動。最後,可以在服務器上調優一下TCP參數,比如說減小數據重傳的超時時間,加快數據包的重傳,可以有效緩解抖動。



提問:對用戶體驗有影響嗎?

喬捷:目前肯定有,我們是標清的 720P 的畫面質量,因爲要考慮硬件成本和網絡傳輸成本。但隨着成本的逐步降低,未來要支持1080P甚至4K畫質也是沒有問題的。



提問:對於 CP 的開發模式有哪些影響?

喬捷:目前沒有影響,我們只是買一個授權,然後由我們進行對接,不需要CP方去改動代碼。當然如果 CP 方願意來對接我們的SDK話那是最好的,可以加入對戰、排名、內購等各種功能,利用雲遊戲的特點爲遊戲增加更多的玩法。



提問:我們這麼多年下來的計算,最早開始所有的計算都是在中心,隨着終端計算能力的增強,計算很多功能都到終端上面去,現在你的方案是把所有的終端都放在中心,這對服務器成本要求很高?如果能夠容納一些用戶同時運行大型遊戲,服務器成本是否會非常高?

喬捷:對。爲什麼我們要中心化?因爲終端的種類太多了,手機、平板、電視、PC,這麼多平臺,你一個遊戲要去移植這麼多平臺,本身的工作量就非常大,而且用戶要去下載安裝,推廣的成本非常高,網絡遊戲單個用戶的獲客成本已經到了幾十到上百塊錢。所以,服務器成本表面上看是有點高,但是算上開發成本分發成本推廣成本,這點服務器成本已經完全可以接受。

這就和視頻一樣,最早我們看視頻是買光盤的,後來有了網絡以後是從網絡上下載,而現在寬帶普及了之後已經沒有人下載了,都是直接視頻點播,因爲它方便,門檻越低越容易被用戶接受,現在還會有人買光盤嗎?基本上已經沒有了吧。電視電腦都不是我們的工具了,大家現在用的比較多就是手機。計算資源越來越中心化集中,管理成本不斷降低。現在買遊戲機、ps3、ps4,每隔 5 年換一個遊戲機,以後不需要遊戲機更新換代了,更新換代對於廠商來說是一個比較痛苦的過程,有一個漫長的遷移過程。將來根本不用關心什麼硬件,比如今年的“吃雞”遊戲非常流行,但是很多玩家的顯卡性能不足,跑不起來。將來遊戲都是放在服務器上跑,用戶根本不用擔心跑不跑得動,接上就可以玩。一旦這個服務模式成立,硬件廠商都會向這個方向投入資源,最早2011年的時候我們就預研過雲遊戲的技術,當時做了以後就放棄,後來看到這個機會以後推出來了grid顯卡,一下子拉很高,看這一塊商業模式什麼時候落地,現在還是在探索的過程當中,將來是大趨勢。



提問:除了服務上面成本,要求終端的網絡非常好嗎?對解碼要求高麼?

喬捷:對,因爲網絡非常普及的情況下,寬帶已經無處不在了,所以這個問題基本已經被解決了。現在的主流中低端芯片可以實時軟件解碼720P的視頻流。



提問:我知道遊戲有很多種類,目前雲遊戲技術支持的範圍怎麼樣?雲遊戲的交互目前爲止是否還很有限?

喬捷:主要是主機遊戲,用手柄玩的遊戲。看類型,使用鍵盤鼠標的遊戲比如FPS在電腦上比較好操作,在電視上就不太方便了,目前主要還是適配手柄操作的遊戲。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章