【造轮子】自定义IRule

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 addressList) {
	if (CollectionUtils.isEmpty(addressList)) {
		return null;
	}

	TreeMap 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 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 {

}

 

你可能感兴趣的