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;
}
算法:
/// 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;
}
}