一、背景
现有一个远端服务器列表,可以选中一个远端服务器,为我们的请求提供服务。远端服务器完成我们的请求有一个响应时间,由于网络波动或者远端服务器的系统负载等因素,该响应时间不断变化,甚至有时候某个远端服务器直接宕机,不再提供服务。
需要一个算法,能够获取处于良好工作状态的远端服务器,从而较快较好地完成我们的请求。
二、朴素的均衡策略
总体思想:响应时间越小越容易被选中,连续N次不能正常提供服务则被冻结一段时间(这是一个惩罚机制,因为在该种情形下,远端服务器很有可能已经宕机。"N"可以自定义配置,"不能正常提供服务"可以是"响应时间超过一定阈值")。
具体策略:
1、一共有3种状态:正常态,冻结态,测试态
2、状态之间的转移关系如下:
在正常态的情况下,如果连续N次不正常提供服务,那么进入冻结态;
在冻结态的情况下,如果已经冻结相应的冻结时间,那么进入测试态,处于测试态的远端服务器直接被选中;
在测试态的情况下,如果再次不能正常提供服务,那么再次进入冻结态,且延长冻结时间;
在测试态的情况下,如果能够正常提供服务,那么进入正常态
3、在选取合适的远端服务器的过程中:
不考虑测试态的远端服务器;
达到冻结时间的处于冻结态的远端服务器直接被选中,并被设为测试态;
在所有处于正常态的远端服务器中以最大概率选取平均响应时间最小的远端服务器
4、一次正常提供服务,使得相应的连续不正常提供服务计数清零
5、在测试态转为正常态的过程中,相应的连续不正常提供服务计数清零,将其平均响应时间设为较大的一个值,使得在接下来的“选取合适的远端服务器”的过程中,该刚被解冻的远端服务器被选中的概率较小
三、如何实现较大概率选取平均响应时间最小的远端服务器
假如有M台远端服务器,各自的平均响应时间为:t1,t2,...,tm。那么以较大概率选取平均响应时间最小的远端服务器的伪代码如下:
double sum=0;
choosed;
for(tn:n=1,2,...,m)
{
sum+=1/tn;
//p为0-1之间的一个随机数
p=Math.random();
if(p<1/tn/sum)
choosed=n;
}
return choosed;