服务器动态伸缩设计
一臺服務器的承載量是有限的,對于一個區來說,平時可能只需要支持500到1500人左右,這樣一臺服務器可能就可以搞定,但是如果有運營搞活動,打廣告拉流量,可能一個區的承載量需要支持300到6000的量,甚至更多。為了適應這樣的不同情況,在游戲服務器設計的時候,最好能做到服務器可以動態擴展和收縮,可以根據情況,運行不同的服務器配置。
?
玩家進入游戲之前就要確定進入哪個區,這個區在哪個服務器上面是由服務器端分配的。所以需要以下幾張表,來存儲游戲的區信息和服務器信息
1,游戲區信息表
分區ID,分區名字,分區狀態(主要是:新區,熱門,活躍,維護等)
2,游戲區對應的服務器表
分區ID,服務器Id,服務器ip,服務器端口,服務器狀態(正常,不可用等),當前在線人數(在分配服務器做為參考值),權重值
?
第二張表是一個一對多的關系,一個區對應多個服務器地址,當用戶選擇某一個區之后,向服務器請求獲取這個區所在的服務器地址。這時,服務器可能根據當前區所對應的服務器的在線人數或者其它條件,按照一定的算法,給當前玩家分配一個可以連接的服務器地址,返回它的ip和端口。這樣就可以實現服務器的動態擴展了,當一個區需要增加承載量時,只需要給這個區增加服務器數量即可。當流量減少,穩定之后,可以減少服務器數量。
?
分配服務器地址的算法一般有以下幾種:
1,用戶id求余法
???假如當前一區對應著6臺服務器,當用戶選擇一區時,可以根據用戶的id和服務器數量求余,比如serverIdIndex = userId % 6,serverIndex的值是0 到5之間的某個值。這個算法可以讓同一臺用戶使用分配到同一臺服務器上面。
2,加權隨機法
假如當前有一區對應3臺服務器A,B,C,它們有一個權重的屬性,A(1),B(3),C(4),可以這樣計算:
?
package com.wgs.arithmetic;import java.util.ArrayList; import java.util.List; import java.util.Random;//加權隨機 public class WeightedRandom {public WeightObj random(List<WeightObj> objList) {List<WeightObj> sumList = new ArrayList<>();for (WeightObj obj : objList) {if (obj.weight > 1) {int weight = obj.weight;for (int i = 0; i < weight; i++) {sumList.add(obj);}} else {sumList.add(obj);}}int size = sumList.size();if (size == 0) {return null;}if (size == 1) {return sumList.get(0);}int index = randomInt(0, size - 1);return sumList.get(index);}public int randomInt(int min, int max) {if (min == max) {return min;}Random r = new Random();int intValue = max - min;intValue = intValue < 0 ? 1 : intValue + 1;return min + r.nextInt(intValue);}class WeightObj {private int id;private int weight;public int getId() {return id;}public void setId(int id) {this.id = id;}public int getWeight() {return weight;}public void setWeight(int weight) {this.weight = weight;}} }?
3,輪詢法
這個是按照請求順序,比如一個區對應3臺服務器 A,B,C ,第一個用戶請求時分配A,第二個用戶分配B,第三個用戶給C,每四個用戶再給A,如果循環下去。
4,最小在線人數
這個應該是最精確的,不過需要統計每個服務器的在線人數,每次用戶請求分配服務器時,遍歷服務器列表,把最小在線人數的服務器地址分配給這個用戶。
?
?
如果游戲服務器沒有網關,以上方案可以直接使用,如果游戲服務器有一層網關,需要添加網關的信息,分配給用戶的連接地址就是網關的地址,一個區可能對應著一個網關,一個網關對應多個服務器,確定網關之后,再確定網關之后哪個服務器處理業務消息,需要給客戶端再分配一個服務器ID,網關根據服務器的ID轉發客戶端的請求。
?
在實際應用可,可能會有更多的條件加入進來,以確定用戶連接到哪個服務器,比如服務器是否在維護狀態,人數是否過多等等,所以要根據實際情況選擇和設計。
?
?
游戲開發個人公眾號,歡迎交流
?
轉載于:https://www.cnblogs.com/wgslucky/p/7226229.html
總結
- 上一篇: Jmeter之HTTP Request
- 下一篇: 7.24笔记