WEB與遊戲開發的一些區別

余月七發表於2021-07-10

WEB與遊戲開發的一些區別

前言

​ 最近由於在準備期末考,以及準備實習。其實都沒好好寫過部落格,但今天由於個人身邊的一些事,所以對做web和做遊戲開發的區別做個記錄,以下都是從網上搜尋到的資料文章,感覺可以解決一些疑惑,有的文章無法貼原作者的連結,因為實在找不到原作者,如有侵權,聯絡刪!!!


  • 需要事先了解的點(複習點)

    • HTTP協議的特點

      簡單快速

      ​ 客戶向伺服器請求服務時,只需傳送請求方法和路徑請求方法常用的有GET,HEAD,POST每種方法規定了客戶與伺服器聯絡的型別不同由於HTTP協議簡單,使得HTTP伺服器的程式規模小,因而通訊速度很快。

      靈活

      ​ HTTP允許傳輸任意型別的資料物件正在傳輸的型別由內容型別加以標記。

      無連線

      ​ 無連線的含義是限制每次連線只處理一個請求伺服器處理完客戶的請求,並收到客戶的應答後,即斷開連線採用這種方式可以節省傳輸時間。

      無狀態

      ​ HTTP協議是無狀態協議無狀態是指協議對於事務處理沒有記憶能力缺少狀態意味著如果後續處理需要前面的資訊,則它必須重傳,這樣可能導致每次連線傳送的資料量增大。另一方面,在伺服器不需要先前資訊時它的應答就較快支援B / S及C / S模式

      以下是 HTTP 請求/響應的步驟

      1、客戶端連線到Web伺服器

      一個HTTP客戶端,通常是瀏覽器,與Web伺服器的HTTP埠(預設為80)建立一個TCP套接字連線。例如,http://www.oakcms.cn。

      2、傳送HTTP請求

      通過TCP套接字,客戶端向Web伺服器傳送一個文字的請求報文,一個請求報文由請求行、請求頭部、空行和請求資料4部分組成。

      3、伺服器接受請求並返回HTTP響應

      Web伺服器解析請求,定位請求資源。伺服器將資源複本寫到TCP套接字,由客戶端讀取。一個響應由狀態行、響應頭部、空行和響應資料4部分組成。

      **4、釋放連線TCP連線**

      若connection 模式為close,則伺服器主動關閉TCP連線,客戶端被動關閉連線,釋放TCP連線;若connection 模式為keepalive,則該連線會保持一段時間,在該時間內可以繼續接收請求;

      5、客戶端瀏覽器解析HTML內容

      客戶端瀏覽器首先解析狀態行,檢視錶明請求是否成功的狀態程式碼。然後解析每一個響應頭,響應頭告知以下為若干位元組的HTML文件和文件的字符集。客戶端瀏覽器讀取響應資料HTML,根據HTML的語法對其進行格式化,並在瀏覽器視窗中顯示。

      原文:https://www.cnblogs.com/ranyonsue/p/5984001.html

    • Socket通訊伺服器

      ​ Socket伺服器主要用於提供高效、穩定的資料處理、訊息轉發等服務,它直接決定了前臺應用程式的效能。

      ​ 我們先從整體上認識一下Socket伺服器,Socket伺服器從架構上一般分為:網路層、業務邏輯層、會話層、資料訪問層

      (一) 網路層

      網路層主要用於偵聽socket連線、建立socket、接受訊息、傳送訊息、關閉連線。作為socket通訊伺服器,網路層的效能相當重要,所以我們在設計網路層時,要著重在以下幾方面獲得突破:最大連線數、最大併發數、秒處理訊息數。如何突破呢?下面我為大家介紹幾種網路層常用到的一些技術和技巧(具體實現,我將在博文中逐一具體闡述):

      1)Buffer管理

      ​ 每一個SocketAsyncEventArgs物件(以下簡稱SAEA)在記憶體中都有其對應的快取空間,如果不對這些快取空間進行同一管理,當SAEA物件逐漸增多時,這些SAEA物件的快取空間會越來越大,它們在系統記憶體中不是連續的,造成很多記憶體碎片,而且這些快取不能重複利用,當建立、銷燬SAEA物件時,造成CPU很多額外消耗,影響伺服器效能。面對這問題如何解決呢?用Buffer池管理!

      2)雙工通訊

      ​ Socket伺服器提高通訊效率是一個永恆的話題,提高通訊效率有很多種方法,雙工通訊就是其中之一。一個SAEA物件在同一時刻只能用來接收資料或傳送資料,有人想,如果一個SAEA物件在同一時刻既能傳送資料又能接受資料,那肯定會提高socket通訊效率。恩,很有想法!可是你能讓你的頭在同一時刻既往左轉又往右轉嗎?答案是不行的,那如何實現雙工通訊呢?既然一個SAEA物件在同一時刻只能做一件事,那我自定義DuplexSAEA物件,在該物件中封裝兩個SAEA,一個用於接受,一個用於傳送,問題不就解決了嗎。

      3)poolOfAcceptEventArgs

      ​ poolOfAcceptEventArgs是個什麼東西?它不是個東西,是一個容器,一個容納AcceptSAEA物件的容器。給你兩個socket伺服器,你能很快判別兩個伺服器效能的優異嗎?很簡單,你瞬間向一臺伺服器打入5、6萬的連線,看看會不會都連上,如果都連上,說明這臺socket伺服器的併發處理連線的能力還是不錯的。那如何提高socket伺服器的併發連線能力呢?答案:poolOfAcceptEventArgs!

      4)訊息佇列排程器

      ​ 訊息佇列排程器主要分為兩種:接受訊息佇列、傳送訊息佇列。為什麼要用訊息佇列呢?主要是提高socket伺服器的吞吐量。首先我們定義一個佇列Queue,然後編寫N個排程器,不斷從佇列中排程訊息,接受佇列排程器用於將訊息拋至業務邏輯層處理,傳送佇列排程器用於呼叫網路層傳送訊息介面,向指定埠傳送資料。

      5)心跳掃描

      ​ 有一個困惑:客戶端連線socket伺服器,連線沒有斷開,但客戶端掛了,這樣這條連線在socket伺服器中就成了釘子戶,落地生根不走了!一個釘子戶還可以忍受,千千萬萬個呢?那就崩潰了!怎樣解決這個問題呢?定時掃描每條連線,如果該條連線在超時時間內沒有IO響應,則關閉它。

      6)粘包

      ​ 伺服器在接受訊息包時,如果兩個資料包同時被你伺服器收了怎麼辦?你會把他當成一個資料包嗎?如果一個資料包斷了,分成兩次被你伺服器收了,你會把他們拼接起來嗎?這些就是粘包了,怎麼解決?正規表示式掃描!

      7)多執行緒程式設計

      ​ Socket伺服器的程式設計就是多執行緒程式設計,面對多執行緒,執行緒間怎樣同步、怎樣避免死鎖?多執行緒訪問公共資源如何處理,在下面的博文中,我將會為大傢俱體闡述。

      (二) 業務邏輯層

        網路層將解包後的訊息包拋至業務邏輯層,業務邏輯層收到訊息包後,解析訊息型別,然後轉入相應的處理流程處理。

        網路層應提供傳送訊息的介面供業務邏輯層呼叫,因為網路層不會主動傳送訊息,傳送訊息的操作是由業務邏輯層來控制的,所以業務邏輯層應根據具體的業務應用,封裝不同功能的傳送訊息的方法。

      (三) 會話層

        會話層主要用於記錄線上使用者資訊,該層隸屬於業務邏輯層。既然隸屬於業務邏輯層,那為什麼還要獨立出來呢?這主要為以後分散式開發擴充用,試想,一臺伺服器最大能支援多少人同時線上?中國有多少人?如果1億人同時線上,你一臺伺服器能支援得了嗎?答案肯定是否定的,所以要分散式開發。分散式開發涉及到使用者資訊同步的問題,所以會話層就要獨立出來了。

      (四) 資料訪問層

        資料庫執行效率是整個socket伺服器的瓶頸?為什麼呢?舉個例子:假設我們的socket伺服器的秒處理訊息的條數為3000,每處理一條訊息都會儲存歷史記錄,那麼,如果資料訪問層不想拖網路層的後腿,那麼他的執行sql語句的效率也必須達到每秒3000!如果socket伺服器和資料庫伺服器部署在同一網段上,這個速度是沒有問題的,但如果資料庫伺服器部署在外網呢?你的sql語句的執行效率能達到那麼高嗎?很困難!

        再思考一個問題:如果網路層執行執行緒和資料庫執行執行緒是同一個執行緒,那麼網路層的處理必須等待資料庫執行完畢後,才能進行!如果資料庫執行效率比較慢,那對整個socket伺服器將是一個毀滅性的打擊。

        那麼怎樣將資料訪問層與網路層分離,讓他們互不影響?如何提高資料庫執行效率,讓網路層的處理速度和資料訪問層的處理速度達到一個平衡?答案:連線池+sql排程器+主從資料庫

      原文:https://www.cnblogs.com/tianzhiliang/archive/2010/10/28/1863684.html


解釋一:

​ 原文未找到!!!

在一間遊戲公司的兩個部門待過, 前一個部門以做web開發為主,後一個部門做遊戲開發,我在兩邊都是做後端的。在遊戲部門待的時間不長, 不敢說已經深入瞭解遊戲開發技術細節,我僅把我已經接觸到的內容與之前擅長的web技術做對比,一來作為工作日誌記錄, 二來希望能給想從web轉游戲的同學提供一個預先學習的方向,少走一些彎路。

​ 這一系列內容我會連載釋出,而不是一次性講清楚所有內容, 畢竟當前還不敢狂妄的表示已經瞭解遊戲開發的種種細節。

通用性

​ 即使不同型別的軟體開發也是具有一定相似性的,這種相似性隨軟體型別的不同而不同。 如web前端開發與web後端開發差異就挺大, 前端程式執行在瀏覽器中,後端程式執行在伺服器上;前端程式操縱的目標是網頁元素,後端程式操縱的目標是儲存在伺服器上的資料。前端和後端相似的地方估計也就程式語言使用的一些基礎概念了,所以前後端程式設計師崗位轉變存在一定難度,比如讓一個沒有任何後端經驗的前端程式設計師立馬上手寫後端程式,幾乎不可能。

​ 然而web伺服器和遊戲伺服器的差異就沒這麼大了,它們用的是相同的程式語言, 比如說java;它們用的是相同的資料庫軟體,比如mysql和redis;它們都執行在伺服器端,比如linux server和windows server,且對穩定性要求及其嚴格。擁有這幾處相同點兩種程式在巨集觀上是完全相似的,對應程式設計師工作的轉換也不存在硬性的技術障礙, 如果程式設計師技術基礎紮實,完全可以平滑過渡。

差異性

​ 因為業務的不同,web伺服器和遊戲伺服器勢必存在不同之處,然而這種不同並非技術上的不同,而是套路上的不同。

伺服器型別的不同

​ web程式使用http服務,瀏覽器和伺服器之間是http協議通訊。遊戲伺服器通常是一個socket伺服器,與遊戲客戶端之間保持長連線,如果是網頁H5遊戲,那麼使用的也是全雙工的websocket協議。通常,使用http協議的web伺服器不用程式設計師費事去管理網路連線,程式設計師只要專注業務邏輯即可。而使用socket或者web socket等協議進行長連線通訊卻需要程式設計師手動程式設計管理,比如說斷線重連遊戲狀態恢復機制,就需要手動處理網路連線。這表示socket程式設計難度大於http程式設計,從而導致遊戲伺服器程式設計大於web伺服器程式設計。可這並不能表示遊戲伺服器程式設計不同於web程式設計, 如果一個web程式設計師不瞭解socket程式設計原理,那也不能算一個優秀的web程式設計師,畢竟http是以socket為基礎的。

傳輸資料格式的不同

​ 在web前後端傳輸資料除了使用http標準的鍵值對格式以外使用最多的是json,json被使用的一個最重要的原因是與JS無縫相容,高效方便。然而,這種優勢在遊戲客戶端中不存在,人家遊戲客戶端又不使用JavaScript程式設計,所以遊戲客戶端和伺服器之間有更合適的資料傳輸時格式存在。我接觸到的是穀人希家的protocol buffer協議, 它相對於json的優點是體積小。經我測試,同樣的資料內容,使用protocol buffer格式儲存大小隻有使用json儲存的三分之一甚至更低,即使在某些特殊情況下也不會超過json的一半。
嚴格驗證資料格式,有xml xsd的功效。而json資料格式驗證相對寬鬆,只要符合json語法就行,因此容易出錯。反之,protocol buffer則更加穩定。至於缺點最嚴重的是使用麻煩, 需要藉助穀人希的第三方工具才行。protocol buffer的使用細節,這裡不作講解。

分散式處理業務

​ 我接觸到的遊戲伺服器是微服務的一種形態, 整個遊戲伺服器的邏輯被分割成很多服務模組,分別執行在不同的伺服器上。然而,我無法理解的是每個模組之間的通訊居然使用socket,而不是更流行的http。遊戲客戶端與伺服器之間使用socket連線可以理解, 然而,伺服器各模組之間也使用socket卻有些使我莫名其妙,雖然這會使伺服器之間通訊效能有所提升,卻會帶來編寫程式碼任務過於複雜,穩定性下降等問題,為了些許效能提升而喪失專案的維護性,有點得不償失。 不過也有可能我還沒有理解其中奧祕,判斷過於片面。

極端的效能敏感

​ 遊戲中實時對戰模組必須使用c/c++實現,原因是JVM執行垃圾收集時會造成虛擬機器停頓,也就是stop the world。在虛擬機器技術發展日新月異的今天, gc停頓依舊會對遊戲體驗造成影響,因而必須使用老掉牙的c++, 這使我感到震驚。另外, 遊戲中大多數資料被放在redis中而非mysql也使我意外,資料持久化儲存顯然不是redis的優勢,拿效能換穩定和安全,這種做法略顯激進。

以上內容是我當前對於web開發與遊戲伺服器開發不同之處的見解,如有謬誤請指出。 此外,在之後的學習和實踐中的心得體會,會在之後的文章中繼續釋出。


解釋二:

遊戲伺服器和Web伺服器的區別

有些對遊戲伺服器的介紹可能會說,遊戲伺服器是一個需要長期執行的程式,然後怎麼怎麼樣。我個人認為Web伺服器一樣的需要長期執行,也需要響應不定點不定時來自使用者的請求。兩者從巨集觀上來看其實沒有本質的區別。同時Web伺服器也會對於穩定性和效能有要求,遊戲服一般分為大小服,我們這裡都按照小服舉例子。

3.1 狀態

首先要提到的就是狀態。可能你會聽說過一個概念,遊戲伺服器是有狀態的,而Web伺服器是無狀態的。什麼意思呢?Web伺服器的資料流大多直接會到資料庫中。而遊戲伺服器的資料流首先會到記憶體中,然後定期的寫入資料庫(落地)。

換句話說,遊戲伺服器本身的資料與資料庫中的資料在執行期間會存在一個資料不一致的視窗。如果此時遊戲伺服器當機了,那麼就會造成資料首先到的記憶體資料與資料庫存的資料不一致。

而Web伺服器則不會有這樣的問題,Web所有的資料狀態都會落地,而且可以針對操作加上事務,不用擔心因為操作失敗而引入髒資料。正因為有了狀態的約束,遊戲伺服器就會很慎重的使用記憶體、CPU。以求在資源有限的情況下,最大化的提高的承載量,並且降低服務延遲。當然,Web伺服器會為了降低某個介面的響應時間而去做對應的優化。

3.2 擴容

在Web伺服器中,如果你不能評估一個服務所面臨的壓力,又不想因為瞬時的熱點訪問導致服務直接不可用的話,完全可以設定成自動擴容,因為每個服務只是單純的接收請求,然後處理請求、返回結果,不會將資料儲存在伺服器的記憶體中。要有資料存到記憶體,那也是在Redis中。而Redis資料丟失對資料的一致性基本沒有影響。

但是在遊戲伺服器這邊很難做到像Web那樣靈活。首先,資料的流向不是資料庫,而是記憶體。

舉個很簡單的例子,玩家的主城被攻打著火了,如果有了自動擴容,很有可能在落地的視窗內,玩家再請求一次,請求到了另一個例項。主城又沒有著火了。因為資料都會先存在記憶體中。

再舉一個例子,玩家氪金買了一個禮包。然後退出遊戲,落地視窗內再次上線沒了。這就不是單純的資料問題了,玩家這是花了真金白銀買的道具,突然就沒了,一兩個還好處理,如果多個玩家都出現這樣的問題,那這就屬於嚴重的線上事故了。修復資料的工作量十分的大。

所以,對於一個遊戲伺服器,所能使用的記憶體和CPU的資源是非常有限的,不像Web伺服器可以不用花很大的代價做到橫向擴充套件。這也就是為什麼遊戲伺服器會十分十分的注重程式碼的效能以及穩定性。

3.3 穩定

就像上面說的例子,如果遊戲伺服器執行中出了BUG,導致服務直接不可用,或者說通過這個BUG刷到了大量的道具,將是一個非常嚴重的線上事故。

而對於Web伺服器來說,如果是管理系統之類的,有可能會有髒資料值得一提的是,髒資料對於Web來說,排查起來也是一件很頭疼的事情。如果沒有髒資料,只是服務暫且不可用,而且如果用的是微服務架構,重啟服務的代價是相對來說比較小的,只有正在重啟的服務的業務是不可用的,其餘的部分則可以正常的訪問。

而對於遊戲伺服器來說,伺服器重啟影響的是全服的玩家。玩家在停服期間,甚至連遊戲都進不了,特別的影響玩家體驗。而且,如果停服之前伺服器的資料落地出現了問題,服務重啟之後會將資料從資料庫load到記憶體中,此時同樣會造成資料不一致的問題。

3.4 效能

從我的經驗來看,在做Web伺服器的時候,沒有為了減少GC的壓力,為了少佔用記憶體去做過多的優化。當然這是因為專案本身的體量不大,如果QPS很高的話,Web伺服器同樣很需要注重效能,只不過遊戲伺服器需要一直特別注意這個方面。

不過在Web,如果訪問量很大的話導致單個服務不能扛住壓力,大部分人首先想到的解決方案應該就是搞多個例項,畢竟可以做到很輕鬆的橫向擴充套件。

在遊戲伺服器裡,會把伺服器的資源看的相當的寶貴。例如,能不落地的欄位就絕對不要落地,某個欄位的值可以通過已知的條件算出來的,就儘量不要定義在程式碼裡。不過這也要看具體情況權衡運算量和呼叫的頻率。因為上線之後,如果遇到了資料不一致,維護的資料越少,修復資料的難度就越小。

3.5 嚴謹

這一點上來說,我認為是兩者都很關注的一個重點。只不過,在遊戲伺服器的某些情況中,如果伺服器丟擲異常或者panic。其造成的後果會被遊戲特殊的環境放大。

例如,召回你的在外部隊失敗了,那麼部隊就會一直在外面且不可用。這跟在瀏覽器中點一個按鈕沒有反應比起來,影響相對較小。而且使用微服務架構,在修復問題之後可以以很低的成本來重啟對應的服務,而遊戲伺服器中還要修復一次資料。

再舉一個很極端的例子,點選商店,玩家要準備氪金了。但是卻發現進不了商店,也可能不能獲取商品列表。這些會直接影響到遊戲的體驗,甚至收入。

而對於Web來說,伺服器的穩定性同樣很重要。不然根據業務的不同,造成後果的嚴重性也有可能不同。影響了使用者體驗,就會直接影響到產品的口碑。

3.6 資料傳輸格式

熟悉Web的都知道,資料傳輸格式是JSON。而在遊戲伺服器中是Protobuf,是由Google開發的資料傳輸格式,與JSON類似。Protobuf是二進位制的,二進位制資料量會比JSON更小一點。而且,如果傳輸的欄位是空值,就不會被傳輸。而JSON如果是空值,一樣的也會被傳輸。

無論是在什麼樣的環境中,舉個例子,Node.js和Java中,Protobuf的效能表現都比JSON好。在Java中,Protobuf甚至要比JSON快了接近80%。如果Java的服務之間通訊有了效能瓶頸, 可以考慮服務之間使用RPC來通訊。

但是凡事都具有兩面性。Protobuf的缺點仍然存在:

  • 文件較少
  • 社群與JSON的對比起來
  • 可讀性沒有JSON好

原文:https://zhuanlan.zhihu.com/p/86748689


問題

​ 對這塊僅僅做了個簡單的瞭解,也並不知道大佬們眼中的區別是怎樣的,以及那種多人聯網棋牌類遊戲用Java可以開發嗎?如果可以,可以用什麼方式呢?個人沒有一個準確的認識,希望有大佬可以給我指正以及講述一下這裡面的一些原理。

相關文章