zoukankan      html  css  js  c++  java
  • 服务器动态伸缩设计

    一台服务器的承载量是有限的,对于一个区来说,平时可能只需要支持5001500人左右,这样一台服务器可能就可以搞定,但是如果有运营搞活动,打广告拉流量,可能一个区的承载量需要支持3006000的量,甚至更多。为了适应这样的不同情况,在游戏服务器设计的时候,最好能做到服务器可以动态扩展和收缩,可以根据情况,运行不同的服务器配置。

     

    玩家进入游戏之前就要确定进入哪个区,这个区在哪个服务器上面是由服务器端分配的。所以需要以下几张表,来存储游戏的区信息和服务器信息

    1,游戏区信息表

    分区ID,分区名字,分区状态(主要是:新区,热门,活跃,维护等)

    2,游戏区对应的服务器表

    分区ID,服务器Id,服务器ip,服务器端口,服务器状态(正常,不可用等),当前在线人数(在分配服务器做为参考值),权重值

     

    第二张表是一个一对多的关系,一个区对应多个服务器地址,当用户选择某一个区之后,向服务器请求获取这个区所在的服务器地址。这时,服务器可能根据当前区所对应的服务器的在线人数或者其它条件,按照一定的算法,给当前玩家分配一个可以连接的服务器地址,返回它的ip和端口。这样就可以实现服务器的动态扩展了,当一个区需要增加承载量时,只需要给这个区增加服务器数量即可。当流量减少,稳定之后,可以减少服务器数量。

     

    分配服务器地址的算法一般有以下几种:

    1,用户id求余法

       假如当前一区对应着6台服务器,当用户选择一区时,可以根据用户的id和服务器数量求余,比如serverIdIndex = userId % 6serverIndex的值是0 5之间的某个值。这个算法可以让同一台用户使用分配到同一台服务器上面。

    2,加权随机法

    假如当前有一区对应3台服务器A,B,C,它们有一个权重的属性,A1),B(3)C4),可以这样计算:

     

    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台服务器 ABC ,第一个用户请求时分配A,第二个用户分配B,第三个用户给C,每四个用户再给A,如果循环下去。

    4,最小在线人数

    这个应该是最精确的,不过需要统计每个服务器的在线人数,每次用户请求分配服务器时,遍历服务器列表,把最小在线人数的服务器地址分配给这个用户。

     

     

    如果游戏服务器没有网关,以上方案可以直接使用,如果游戏服务器有一层网关,需要添加网关的信息,分配给用户的连接地址就是网关的地址,一个区可能对应着一个网关,一个网关对应多个服务器,确定网关之后,再确定网关之后哪个服务器处理业务消息,需要给客户端再分配一个服务器ID,网关根据服务器的ID转发客户端的请求。

     

    在实际应用可,可能会有更多的条件加入进来,以确定用户连接到哪个服务器,比如服务器是否在维护状态,人数是否过多等等,所以要根据实际情况选择和设计。

     

     

    游戏开发个人公众号,欢迎交流

     

  • 相关阅读:
    win10 UWP button
    内网分享资源
    内网分享资源
    CF724F Uniformly Branched Trees
    win10 UWP FlipView
    win10 UWP FlipView
    win10 UWP FlipView
    搭建阿里云 centos mysql tomcat jdk
    搭建阿里云 centos mysql tomcat jdk
    win10 UWP 申请微软开发者
  • 原文地址:https://www.cnblogs.com/wgslucky/p/7226229.html
Copyright © 2011-2022 走看看