public class MyRule extends AbstractLoadBalancerRule implements IRule {@Override
public void initWithNiwsConfig(IClientConfig iClientConfig) {
}
@Override
public Server choose(Object key) {
HttpServletRequest request = ((ServletRequestAttributes)
RequestContextHolder.getRequestAttributes())
.getRequest();
String uri = request.getServletPath() + "?" + request.getQueryString();
return route(uri.hashCode(), getLoadBalancer().getAllServers());
}
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
public Server route(int hashId, List<Server> addressList) {
if (CollectionUtils.isEmpty(addressList)) {
return null;
}
TreeMap<Long, Server> address = new TreeMap<>();
addressList.stream().forEach(e -> {
// 虚化若干个服务节点,到环上
for (int i = 0; i < 8; i++) {
long hash = hash(e.getId() + i);
address.put(hash, e);
}
});
long hash = hash(String.valueOf(hashId));
SortedMap<Long, Server> last = address.tailMap(hash);
// 当request URL的hash值大于任意一个服务器对应的hashKey,
// 取address中的第一个节点
if (last.isEmpty()) {
address.firstEntry().getValue();
}
return last.get(last.firstKey());
}
public long hash(String key) {
MessageDigest md5;
try {
md5 = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
byte[] keyByte = null;
try {
keyByte = key.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
md5.update(keyByte);
byte[] digest = md5.digest();
long hashCode = ((long) (digest[2] & 0xFF << 16))
| ((long) (digest[1] & 0xFF << 8))
| ((long) (digest[0] & 0xFF));
return hashCode & 0xffffffffL;
}
@Configuration
@RibbonClient(name = "eureka-client", configuration = MyRule.class)
public class RibbonConfiguration {
}
版权声明:本文为Leon_Jinhai_Sun原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。