背景: 我需要在網關實現一種功能,某個用戶的請求永遠打在后台指定的服務,也就是根據ip地址進行負載均衡
原理: 在ribbon的配置類下:

那我們自己創建一個IRule的實現類,模仿ZoneAvoidanceRule,該類的繼承體系:

所以我們只要繼成AbstractLoadBalancerRule
package com.yang.xiao.hui.filter;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
@Component //這里注入容器,將會對所有的服務都生效
public class MyRule extends AbstractLoadBalancerRule {
@Override
public void initWithNiwsConfig(IClientConfig clientConfig) {
}
@Override
public Server choose(Object key) {
ILoadBalancer loadBalancer = getLoadBalancer();
List<Server> allServers = loadBalancer.getAllServers();
if(allServers.size()==1){
return allServers.get(0);
}
int size = allServers.size();
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String remoteAddr = request.getRemoteAddr();
int hashCode = Math.abs(remoteAddr.hashCode()); //據說hashcode會有負數導致索引越界
int index=hashCode%size;
return allServers.get(index);
}
}
上面的配置是對所有服務生效,如果我想指定某個服務生效:
回到源碼:

繼續跟進:


我們看看classNameProperty有哪些值:

現在我要指定自定義規則只對Product服務生效:
1.先將MyRule的Component注解去掉,不然對全部服務生效

2. 在yml中配置:

同理,配置單個服務的其他屬性也是一樣,如NFLoadBalancerClassName,NIWSServerListClassName 等
