基于Consul的ConsulBlockingLoadBalan
2021-02-01 本文已影响0人
EasyNetCN
在把项目升级到Spring Cloud 2020.0.1是,遇到了使用openfeign会抛出异常,根据异常信息,实现了一个基于Consul的BlockingLoadBalancerClient
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
import org.springframework.cloud.client.DefaultServiceInstance;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties;
import org.springframework.cloud.client.loadbalancer.Request;
import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties;
import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import com.ecwid.consul.v1.ConsulClient;
import com.ecwid.consul.v1.QueryParams;
import com.ecwid.consul.v1.health.HealthServicesRequest;
public class ConsulBlockingLoadBalancerClient extends BlockingLoadBalancerClient {
private final ConsulClient consulClient;
private final ConsulDiscoveryProperties consulDiscoveryProperties;
public ConsulBlockingLoadBalancerClient(LoadBalancerClientFactory loadBalancerClientFactory,
LoadBalancerProperties properties, ConsulClient consulClient,
ConsulDiscoveryProperties consulDiscoveryProperties) {
super(loadBalancerClientFactory, properties);
this.consulClient = consulClient;
this.consulDiscoveryProperties = consulDiscoveryProperties;
}
@Override
public <T> ServiceInstance choose(String serviceId, Request<T> request) {
var consulRequest = HealthServicesRequest.newBuilder().setTag(consulDiscoveryProperties.getDefaultQueryTag())
.setPassing(consulDiscoveryProperties.isQueryPassing()).setQueryParams(QueryParams.DEFAULT)
.setToken(consulDiscoveryProperties.getAclToken()).build();
var consulResponse = consulClient.getHealthServices(serviceId, consulRequest);
var servers = consulResponse.getValue().stream()
.map(m -> new DefaultServiceInstance(m.getService().getId(), m.getService().getService(),
m.getService().getAddress(), m.getService().getPort(), false, m.getService().getMeta()))
.collect(Collectors.toList());
return servers.get(ThreadLocalRandom.current().nextInt(servers.size()) % servers.size());
}