创建自定义负载均衡拦截器
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
47public class GrayscaleLoadBalancerClientFilter extends LoadBalancerClientFilter {
private static final String VERSION = "version";
private final DiscoveryClient discoveryClient;
private final AtomicInteger nextServerCyclicCounter;
public GrayscaleLoadBalancerClientFilter(LoadBalancerClient loadBalancer, DiscoveryClient discoveryClient) {
super(loadBalancer);
this.discoveryClient = discoveryClient;
this.nextServerCyclicCounter = new AtomicInteger(0);
}
protected ServiceInstance choose(ServerWebExchange exchange) {
URI uri = (URI) exchange.getAttributes().get(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR);
List<ServiceInstance> list = discoveryClient.getInstances(uri.getHost());
if (CollectionUtils.isEmpty(list)) {
return null;
}
List<String> listHeaders = exchange.getRequest().getHeaders().get(VERSION);
String version = CollectionUtils.isEmpty(listHeaders)
? null : (StringUtils.isBlank(listHeaders.get(0)) ? null : listHeaders.get(0));
if (Objects.nonNull(version)) {
list = list.stream().
filter(serviceInstance -> version.equals(serviceInstance.getMetadata().get(VERSION)))
.collect(Collectors.toList());
if (!CollectionUtils.isEmpty(list)) {
return list.get(this.incrementAndGetModulo(list.size()));
}
}
list = list.stream().
filter(serviceInstance -> !serviceInstance.getMetadata().containsKey(VERSION))
.collect(Collectors.toList());
return list.isEmpty() ? null : list.get(this.incrementAndGetModulo(list.size()));
}
private int incrementAndGetModulo(int modulo) {
int current;
int next;
do {
current = this.nextServerCyclicCounter.get();
next = (current + 1) % modulo;
} while(!this.nextServerCyclicCounter.compareAndSet(current, next));
return next;
}
}注入自定义负载均衡拦截器
1
2
3
4
5
6
public LoadBalancerClientFilter loadBalancerClientFilter(LoadBalancerClient client,
DiscoveryClient discoveryClient) {
return new GrayscaleLoadBalancerClientFilter(client, discoveryClient);
}配置服务元数据
可以在
bootstrap.yml
中配置,或者在注册中心中设置1
2
3
4
5
6spring:
cloud:
nacos:
discovery:
metadata:
version: 1