负载均衡
# 负载均衡接口
public interface IGatewayLoadBalanceRule {
/*通过上下文参数获取服务实例*/
ServiceInstance choose(GatewayContext ctx);
ServiceInstance choose(String serviceId,boolean gray);
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 随机
根据serviceId获取到所有服务实例,随机数根据索引获取实例;
@Slf4j
public class RandomLoadBalanceRule implements IGatewayLoadBalanceRule{
private final String serviceId;
private Set<ServiceInstance> serviceInstanceSet;
/*k:serivceId*/
private static ConcurrentHashMap<String,RandomLoadBalanceRule> serviceMap = new ConcurrentHashMap<>();
public RandomLoadBalanceRule(String serviceId) {
this.serviceId = serviceId;
}
public static RandomLoadBalanceRule getInstance(String serviceId){
RandomLoadBalanceRule loadBalanceRule = serviceMap.get(serviceId);
if(loadBalanceRule == null){
loadBalanceRule = new RandomLoadBalanceRule(serviceId);
serviceMap.put(serviceId, loadBalanceRule);
}
return loadBalanceRule;
}
@Override
public ServiceInstance choose(GatewayContext ctx) {
String serviceId = ctx.getUniqueId();
return choose(serviceId, ctx.isGray());
}
@Override
public ServiceInstance choose(String serviceId,boolean gray) {
Set<ServiceInstance> serviceInstanceSet = DynamicConfigManager.getInstance().getServiceInstanceByUniqueId(serviceId,gray);
if(serviceInstanceSet.isEmpty()){
log.warn("No instance available for:{}",serviceId);
throw new NotFoundException(SERVICE_INSTANCE_NOT_FOUND);
}
List<ServiceInstance> instances = new ArrayList<>(serviceInstanceSet);
int index = ThreadLocalRandom.current().nextInt(instances.size());
ServiceInstance instance = (ServiceInstance)instances.get(index);
return instance;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# 轮询
@Slf4j
public class RoundRobinLoadBalanceRule implements IGatewayLoadBalanceRule{
private AtomicInteger position = new AtomicInteger(1);
private final String serviceId;
private static ConcurrentHashMap<String,RoundRobinLoadBalanceRule> serviceMap = new ConcurrentHashMap<>();
public RoundRobinLoadBalanceRule(String serviceId) {
this.serviceId = serviceId;
}
public static RoundRobinLoadBalanceRule getInstance(String serviceId){
RoundRobinLoadBalanceRule loadBalanceRule = serviceMap.get(serviceId);
if(loadBalanceRule == null){
loadBalanceRule = new RoundRobinLoadBalanceRule(serviceId);
serviceMap.put(serviceId,loadBalanceRule);
}
return loadBalanceRule;
}
@Override
public ServiceInstance choose(GatewayContext ctx) {
return choose(ctx.getUniqueId(), ctx.isGray());
}
@Override
public ServiceInstance choose(String serviceId,boolean gray) {
Set<ServiceInstance> serviceInstanceSet = DynamicConfigManager.getInstance().getServiceInstanceByUniqueId(serviceId,gray);
if(serviceInstanceSet.isEmpty()){
log.warn("No instance available for:{}",serviceId);
throw new NotFoundException(SERVICE_INSTANCE_NOT_FOUND);
}
List<ServiceInstance> instances = new ArrayList<ServiceInstance>(serviceInstanceSet);
if(instances.isEmpty()){
log.warn("No instance available for service:{}",serviceId);
return null;
}else{
int pos = Math.abs(this.position.incrementAndGet());
return instances.get(pos%instances.size());
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# 负载均衡过滤器
@Slf4j
@FilterAspect(id=LOAD_BALANCE_FILTER_ID,
name = LOAD_BALANCE_FILTER_NAME,
order = LOAD_BALANCE_FILTER_ORDER)
public class LoadBalanceFilter implements Filter {
@Override
public void doFilter(GatewayContext ctx) throws Exception {
String serviceId = ctx.getUniqueId();
IGatewayLoadBalanceRule loadBalanceRule = getLoadBalanceRule(ctx);
ServiceInstance serviceInstance = loadBalanceRule.choose(serviceId,ctx.isGray());
System.out.println("IP为"+serviceInstance.getIp()+",端口号:"+serviceInstance.getPort());
GatewayRequest request = ctx.getRequest();
if(serviceInstance != null && request != null){
String host = serviceInstance.getIp()+":"+serviceInstance.getPort();
request.setModifyHost(host);
}else{
log.warn("No instance available for :{}",serviceId);
throw new NotFoundException(SERVICE_INSTANCE_NOT_FOUND);
}
}
private IGatewayLoadBalanceRule getLoadBalanceRule(GatewayContext ctx) {
IGatewayLoadBalanceRule loadBalanceRule = null;
Rule configRule = ctx.getRule();
if(configRule!=null){
Set<Rule.FilterConfig> filterConfigs = configRule.getFilterConfigs();
Iterator<Rule.FilterConfig> iterator = filterConfigs.iterator();
Rule.FilterConfig filterConfig;
while(iterator.hasNext()) {
filterConfig = (Rule.FilterConfig) iterator.next();
if (filterConfig == null) {
continue;
}
String filterId = filterConfig.getId();
if (filterId.equals(LOAD_BALANCE_FILTER_ID)) {
String config = filterConfig.getConfig();
String strategy = LOAD_BALANCE_STRATEGY_RANDOM;
if(StringUtils.isNotEmpty(config)){
Map<String,String> map = JSON.parseObject(config, Map.class);/*何时存入?*/
strategy = map.getOrDefault(LOAD_BALANCE_KEY, strategy);
}
switch(strategy){
case LOAD_BALANCE_STRATEGY_RANDOM:
loadBalanceRule = RandomLoadBalanceRule.getInstance(configRule.getServiceId());
break;
case LOAD_BALANCE_STRATEGY_ROUND_ROBIN:
loadBalanceRule = RoundRobinLoadBalanceRule.getInstance(configRule.getServiceId());
break;
default:
log.warn("No loadBalance strategy for service:{}", strategy);
loadBalanceRule = RandomLoadBalanceRule.getInstance(configRule.getServiceId());
break;
}
}
}
}
return loadBalanceRule;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61