接口服务器(Interface Server)和消息分发服务器(Dispatcher Server)在分发请求的策略上有所不同.
辅助函数和变量:
public String[] getTargetServerIps();//目标服务器的ip,如193.243.15.45:8080
public int[] getTargetServerIds();//目标服务器ID,与上述服务器ip一一对应,可以自由配置
public boolean isServerWorking(index);//判断目标服务器的状态
int currentTargetServerIndex=0;//当前的目标服务器在targetServerIds中的index
接口服务器(Interface Server)采用轮询算法:
public String getTargetServerIp(){//获取该次请求所要分发的目标服务器
String[] targetServerIps=getTargetServerIps();
int[] targetServerIds=getTargetServerIds();
int index=currentTargetServerIndex;
boolean isWorking=false;
while(!isWorking){
index=targetServerIds.length()%(currentTargetServerIndex+1);
isWorking=isServerWorking(index);
if(!isWorking&&index==currentTargetServerIndex){//无任何目标服务器可用
return "0:0";
}
}
currentTargetServerIndex=index;
return targetServerIps[index];
}
消息分发服务器(Dispatcher Server)分发请求采用的hash算法
// hash algrithm from JDK's String,来自于jdk的hash算法
public int hash(byte[] bs) {
int hash = 0;
for (int i = 0; i < bs.length; i++) {
hash = 31 * hash + bs[i];
}
return hash;
}
public int getTargetServerGroupIndexByHash(String hashParam) throws BtirException {//返回根据hash计算出的目标服务器群组
byte[] hashinfo=hashParam.getBytes("utf-8");
int frameCount=2://由hash值的后两位进行分段的数目 ,即hash结果数,目标服务器群组的数量
int step = 100 / frameCount;
int hash = Math.abs(hash(hashParam) % 100);
for(int i=0, beg=0, end=step; i<frameCount; i++) {
if(beg <= hash && hash < end )
return 2*i;
beg = end;
end += step;
}
return 2*(frameCount-1); //如果设置得好,应该不会走到这里
}
public String getTargetServerIpInGriuo(int groupIndex){//根据轮询算法,计算服务器群组中的最优服务器
String[] targetServerIps=getTargetServerIps();//组内的轮询算法,代码略
int[] targetServerIds=getTargetServerIds();
int index=getTargetServerIndexInGroup(groupIndex);//轮询算法代码略
return targetServerIps[index];
}