Spring Cloud 服务注册之后 如何调用

Spring Cloud 提供了一个接口 DiscoveryClient , 为 Eureka 或者 consul 等注册中心去实现, getInstances 方法获取注册的实例,一个实例对应一个工程

List<ServiceInstance> getInstances(String serviceId);

看下接口 ServiceInstance 下面两个方法 获取 主机名(IP)/ 端口

    String getHost();
    int getPort();

注册了实例之后,使用 阻塞式同步RestTemplate 调用 或者 异步非阻塞 WebClient 调用,RestTemplate 为每个HTTP请求创建一个线程,在响应之前一直是阻塞状态,占用系统内存资源。

多个实例 @LoadBalacedRestTemplate 或者 WebClient 做负载均衡的支持,LoadBalancerInterceptor 实现 ClientHttpRequestInterceptor 接口 (intercept 方法)

    ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
            throws IOException;

通过请求 URL 获取 host 然后使用 LoadBalancerClient 进行调用

public class LoadBalancerInterceptor implements ClientHttpRequestInterceptor {

    private LoadBalancerClient loadBalancer; 

    @Override
    public ClientHttpResponse intercept(final HttpRequest request, final byte[] body,
            final ClientHttpRequestExecution execution) throws IOException {
        final URI originalUri = request.getURI();
        String serviceName = originalUri.getHost();
        Assert.state(serviceName != null,
                "Request URI does not contain a valid hostname: " + originalUri);
        return this.loadBalancer.execute(serviceName,
                this.requestFactory.createRequest(request, body, execution));
    }

看下 execute 方法 默认引用的是 RibbonLoadBalancerClient 通过 serviceId 和 调用的实例 ribbonServer 及 请求request 做服务调用

    public <T> T execute(String serviceId, LoadBalancerRequest<T> request, Object hint)
            throws IOException {
        ILoadBalancer loadBalancer = getLoadBalancer(serviceId);
        Server server = getServer(loadBalancer, hint);
        if (server == null) {
            throw new IllegalStateException("No instances available for " + serviceId);
        }
        RibbonServer ribbonServer = new RibbonServer(serviceId, server,
                isSecure(server, serviceId),
                serverIntrospector(serviceId).getMetadata(server));

        return execute(serviceId, ribbonServer, request);
    }

配置 RestTemplate

@Configuration
public class RestTemplateConfiguration {

    @LoadBalanced
    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
        return builder
                .setConnectTimeout(Duration.ofMillis(100))
                .setReadTimeout(Duration.ofMillis(500))
                .requestFactory(this::requestFactory)
                .build();
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
禁止转载,如需转载请通过简信或评论联系作者。

推荐阅读更多精彩内容