常见负载均衡算法实现

1.轮询负载均衡算法

/// <summary>
/// 轮询负载均衡算法
/// </summary>
public static class RoundRobin
{
    private static object obj = new object();

    static Dictionary<string, int> dic = new Dictionary<string, int>
    {
        { "192.168.1.12", 1},
        {"192.168.1.13", 1 },
        { "192.168.1.14", 3},
        { "192.168.1.15", 1},
        {"192.168.1.16", 1},
        {"192.168.1.17", 1 },
        { "192.168.1.18", 1},
        { "192.168.1.19", 1}
    };

    static int pos = 0;
    public static string roundRobin()
    {
        var keyList = dic.Keys.ToList();


        string server = null;

        lock (obj)
        {
            if (pos >= keyList.Count)
            {
                pos = 0;
            }
            server = keyList[pos];
            pos++;
        }
        return server;
    }
}

优点:请求分配平均

缺点:不能根据机器配置的好坏进行分配

2.加权轮询负载均衡算法

/// <summary>
/// 加权轮询算法
/// </summary>
public static class WeightRoundRobin
{
    private static object obj = new object();
    private static int pos = 0;

    static Dictionary<string, int> dic = new Dictionary<string, int>
    {
        { "192.168.1.12", 1},
        {"192.168.1.13", 1 },
        { "192.168.1.14", 3},
        { "192.168.1.15", 1},
        {"192.168.1.16", 1},
        {"192.168.1.17", 1 },
        { "192.168.1.18", 1},
        { "192.168.1.19", 1}
    };

    public static string roundRobin()
    {
        //獲取ip列表list
        List<string> it = dic.Keys.ToList();

        List<String> serverList = new List<string>();

        foreach (var item in it)
        {
            int weight = 0;
            dic.TryGetValue(item, out weight);

            for (int i = 0; i < weight; i++)
            {
                serverList.Add(item);
            }
        }

        string server = null;

        lock (obj)
        {
            if (pos >= serverList.Count)
            {
                pos = 0;
            }
            server = serverList[pos];
            pos++;
        }
        return server;
    }

}

3.加权随机负载均衡算法

/// <summary>
/// 加权随机负载均衡算法
/// </summary>
public static class WeightRandom
{

    static Dictionary<string, int> dic = new Dictionary<string, int>
    {
        { "192.168.1.12", 1},
        {"192.168.1.13", 1 },
        { "192.168.1.14", 3},
        { "192.168.1.15", 1},
        {"192.168.1.16", 1},
        {"192.168.1.17", 1 },
        { "192.168.1.18", 1},
        { "192.168.1.19", 1}
    };

    public static string weightRandom()
    {
        //獲取ip列表list
        List<string> it = dic.Keys.ToList();

        List<String> serverList = new List<string>();

        foreach (var item in it)
        {
            int weight = 0;
            dic.TryGetValue(item, out weight);

            for (int i = 0; i < weight; i++)
            {
                serverList.Add(item);
            }
        }
        Random random = new Random();
        int randomPos = random.Next(serverList.Count);
        string server = serverList[randomPos];
        return server;
    }
}

4.IP Hash负载均衡算法

/// <summary>
/// IP Hash负载均衡算法
/// </summary>
public static class IpHash
{
    static Dictionary<string, int> dic = new Dictionary<string, int>
    {
        { "192.168.1.12", 1},
        {"192.168.1.13", 1 },
        { "192.168.1.14", 3},
        { "192.168.1.15", 1},
        {"192.168.1.16", 1},
        {"192.168.1.17", 1 },
        { "192.168.1.18", 1},
        { "192.168.1.19", 1}
    };

    public static string ipHash(string remoteIp)
    {
        List<string> keys = dic.Keys.ToList();

        int hashCode = Math.Abs(remoteIp.GetHashCode());
        int serverListSize = keys.Count;
        int serverPos = hashCode % serverListSize;

        return keys[serverPos];
    }

}

5.Twitter全局唯一ID生成算法

测试:private static void TestIdWorker()
    {
        HashSet<long> set = new HashSet<long>();
        IdWorker idWorker1 = new IdWorker(0, 0);
        IdWorker idWorker2 = new IdWorker(1, 0);
        //762884413578018816
        //762884520121729024
        Stopwatch sw = new Stopwatch();
        sw.Start();
        for (int i = 0; i < 1; i++)
        {
            long id = idWorker1.nextId();
            set.Add(id);
            //if (!set.Add(id))
            //{
            //Console.WriteLine("duplicate:" + id);
            //}
        }
        sw.Stop();
        foreach (var item in set)
        {
            Console.WriteLine("结果:" + item);
        }
        Console.WriteLine("时间:" + sw.ElapsedTicks);
        return;
}


算法:
/// <summary>
/// From: https://github.com/twitter/snowflake
/// An object that generates IDs.
/// This is broken into a separate class in case
/// we ever want to support multiple worker threads
/// per process
/// </summary>
public class IdWorker
{
    private long workerId;
    private long datacenterId;
    private long sequence = 0L;

    private static long twepoch = 1288834974657L;

    private static long workerIdBits = 5L;
    private static long datacenterIdBits = 5L;
    private static long maxWorkerId = -1L ^ (-1L << (int)workerIdBits);
    private static long maxDatacenterId = -1L ^ (-1L << (int)datacenterIdBits);
    private static long sequenceBits = 12L;

    private long workerIdShift = sequenceBits;
    private long datacenterIdShift = sequenceBits + workerIdBits;
    private long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
    private long sequenceMask = -1L ^ (-1L << (int)sequenceBits);

    private long lastTimestamp = -1L;
    private static object syncRoot = new object();

    public IdWorker(long workerId, long datacenterId)
    {

        // sanity check for workerId
        if (workerId > maxWorkerId || workerId < 0)
        {
            throw new ArgumentException(string.Format("worker Id can't be greater than %d or less than 0", maxWorkerId));
        }
        if (datacenterId > maxDatacenterId || datacenterId < 0)
        {
            throw new ArgumentException(string.Format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
        }
        this.workerId = workerId;
        this.datacenterId = datacenterId;
    }

    public long nextId()
    {
        lock (syncRoot)
        {
            long timestamp = timeGen();

            if (timestamp < lastTimestamp)
            {
                throw new ApplicationException(string.Format("Clock moved backwards.  Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
            }

            if (lastTimestamp == timestamp)
            {
                sequence = (sequence + 1) & sequenceMask;
                if (sequence == 0)
                {
                    timestamp = tilNextMillis(lastTimestamp);
                }
            }
            else
            {
                sequence = 0L;
            }

            lastTimestamp = timestamp;

            return ((timestamp - twepoch) << (int)timestampLeftShift) | (datacenterId << (int)datacenterIdShift) | (workerId << (int)workerIdShift) | sequence;
        }
    }

    protected long tilNextMillis(long lastTimestamp)
    {
        long timestamp = timeGen();
        while (timestamp <= lastTimestamp)
        {
            timestamp = timeGen();
        }
        return timestamp;
    }

    protected long timeGen()
    {
        return (long)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds;
    }
}

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦