文档章节

聊聊spring cloud的CachingSpringLoadBalancerFactory

go4it
 go4it
发布于 07/21 23:26
字数 477
阅读 30
收藏 1

本文主要研究一下spring cloud的CachingSpringLoadBalancerFactory

CachingSpringLoadBalancerFactory

spring-cloud-openfeign-core-2.2.0.M1-sources.jar!/org/springframework/cloud/openfeign/ribbon/CachingSpringLoadBalancerFactory.java

public class CachingSpringLoadBalancerFactory {

	protected final SpringClientFactory factory;

	protected LoadBalancedRetryFactory loadBalancedRetryFactory = null;

	private volatile Map<String, FeignLoadBalancer> cache = new ConcurrentReferenceHashMap<>();

	public CachingSpringLoadBalancerFactory(SpringClientFactory factory) {
		this.factory = factory;
	}

	public CachingSpringLoadBalancerFactory(SpringClientFactory factory,
			LoadBalancedRetryFactory loadBalancedRetryPolicyFactory) {
		this.factory = factory;
		this.loadBalancedRetryFactory = loadBalancedRetryPolicyFactory;
	}

	public FeignLoadBalancer create(String clientName) {
		FeignLoadBalancer client = this.cache.get(clientName);
		if (client != null) {
			return client;
		}
		IClientConfig config = this.factory.getClientConfig(clientName);
		ILoadBalancer lb = this.factory.getLoadBalancer(clientName);
		ServerIntrospector serverIntrospector = this.factory.getInstance(clientName,
				ServerIntrospector.class);
		client = this.loadBalancedRetryFactory != null
				? new RetryableFeignLoadBalancer(lb, config, serverIntrospector,
						this.loadBalancedRetryFactory)
				: new FeignLoadBalancer(lb, config, serverIntrospector);
		this.cache.put(clientName, client);
		return client;
	}

}
  • CachingSpringLoadBalancerFactory的构造器接收SpringClientFactory、LoadBalancedRetryFactory;它提供了create方法用于创建FeignLoadBalancer;其create方法使用ConcurrentReferenceHashMap来缓存每个client对应的FeignLoadBalancer

LoadBalancerFeignClient

spring-cloud-openfeign-core-2.2.0.M1-sources.jar!/org/springframework/cloud/openfeign/ribbon/LoadBalancerFeignClient.java

public class LoadBalancerFeignClient implements Client {

	static final Request.Options DEFAULT_OPTIONS = new Request.Options();

	private final Client delegate;

	private CachingSpringLoadBalancerFactory lbClientFactory;

	private SpringClientFactory clientFactory;

	public LoadBalancerFeignClient(Client delegate,
			CachingSpringLoadBalancerFactory lbClientFactory,
			SpringClientFactory clientFactory) {
		this.delegate = delegate;
		this.lbClientFactory = lbClientFactory;
		this.clientFactory = clientFactory;
	}

	static URI cleanUrl(String originalUrl, String host) {
		String newUrl = originalUrl;
		if (originalUrl.startsWith("https://")) {
			newUrl = originalUrl.substring(0, 8)
					+ originalUrl.substring(8 + host.length());
		}
		else if (originalUrl.startsWith("http")) {
			newUrl = originalUrl.substring(0, 7)
					+ originalUrl.substring(7 + host.length());
		}
		StringBuffer buffer = new StringBuffer(newUrl);
		if ((newUrl.startsWith("https://") && newUrl.length() == 8)
				|| (newUrl.startsWith("http://") && newUrl.length() == 7)) {
			buffer.append("/");
		}
		return URI.create(buffer.toString());
	}

	@Override
	public Response execute(Request request, Request.Options options) throws IOException {
		try {
			URI asUri = URI.create(request.url());
			String clientName = asUri.getHost();
			URI uriWithoutHost = cleanUrl(request.url(), clientName);
			FeignLoadBalancer.RibbonRequest ribbonRequest = new FeignLoadBalancer.RibbonRequest(
					this.delegate, request, uriWithoutHost);

			IClientConfig requestConfig = getClientConfig(options, clientName);
			return lbClient(clientName)
					.executeWithLoadBalancer(ribbonRequest, requestConfig).toResponse();
		}
		catch (ClientException e) {
			IOException io = findIOException(e);
			if (io != null) {
				throw io;
			}
			throw new RuntimeException(e);
		}
	}

	IClientConfig getClientConfig(Request.Options options, String clientName) {
		IClientConfig requestConfig;
		if (options == DEFAULT_OPTIONS) {
			requestConfig = this.clientFactory.getClientConfig(clientName);
		}
		else {
			requestConfig = new FeignOptionsClientConfig(options);
		}
		return requestConfig;
	}

	protected IOException findIOException(Throwable t) {
		if (t == null) {
			return null;
		}
		if (t instanceof IOException) {
			return (IOException) t;
		}
		return findIOException(t.getCause());
	}

	public Client getDelegate() {
		return this.delegate;
	}

	private FeignLoadBalancer lbClient(String clientName) {
		return this.lbClientFactory.create(clientName);
	}

	static class FeignOptionsClientConfig extends DefaultClientConfigImpl {

		FeignOptionsClientConfig(Request.Options options) {
			setProperty(CommonClientConfigKey.ConnectTimeout,
					options.connectTimeoutMillis());
			setProperty(CommonClientConfigKey.ReadTimeout, options.readTimeoutMillis());
		}

		@Override
		public void loadProperties(String clientName) {

		}

		@Override
		public void loadDefaultValues() {

		}

	}

}
  • LoadBalancerFeignClient的lbClient方法使用CachingSpringLoadBalancerFactory的create方法来创建FeignLoadBalancer;而execute方法则调用了lbClient方法来获取FeignLoadBalancer

小结

CachingSpringLoadBalancerFactory的构造器接收SpringClientFactory、LoadBalancedRetryFactory;它提供了create方法用于创建FeignLoadBalancer;其create方法使用ConcurrentReferenceHashMap来缓存每个client对应的FeignLoadBalancer

doc

© 著作权归作者所有

go4it
粉丝 87
博文 1066
码字总数 1011844
作品 0
深圳
私信 提问
Spring Cloud Alibaba与Spring Boot、Spring Cloud之间不得不说的版本关系

这篇博文是临时增加出来的内容,主要是由于最近连载《Spring Cloud Alibaba基础教程》系列的时候,碰到读者咨询的大量问题中存在一个比较普遍的问题:版本的选择。其实这类问题,在之前写Spr...

程序猿DD
03/03
394
0
聊聊spring cloud gateway的GatewayFilter

序 本文主要研究一下spring cloud gateway的GatewayFilter GatewayFilter spring-cloud-gateway-core-2.0.0.RC2-sources.jar!/org/springframework/cloud/gateway/filter/GatewayFilter.jav......

go4it
2018/06/09
747
0
Spring Cloud 入门教程:聊聊Spring Cloud

一、 Spring Cloud 是什么? Spring Cloud 是将分布式系统中一系列基础框架/工具进行整合的框架。其中包含:服务注册与发现、服务网关、熔断器、配置中心、消息中心、服务链路追踪等等。 Sp...

吴伟祥
2018/12/03
456
0
聊聊spring.cloud.gateway.default-filters

序 本文主要研究下spring.cloud.gateway.default-filters 配置 default-filters,配置的是FilterDefinition对象 FilterDefinition spring-cloud-gateway-core-2.0.0.RC1-sources.jar!/org/sp......

go4it
2018/06/01
494
0
聊聊eureka client的shutdown

序 本文主要研究一下eureka client的shutdown EurekaRegistration spring-cloud-netflix-eureka-client-2.0.0.RC1-sources.jar!/org/springframework/cloud/netflix/eureka/EurekaClientAuto......

go4it
2018/05/04
262
0

没有更多内容

加载失败,请刷新页面

加载更多

spring cloud

一、从面试题入手 1.1、什么事微服务 1.2、微服务之间如何独立通讯的 1.3、springCloud和Dubbo有哪些区别 1.通信机制:DUbbo基于RPC远程过程调用;微服务cloud基于http restFUL API 1.4、spr...

榴莲黑芝麻糊
31分钟前
2
0
Executor线程池原理与源码解读

线程池为线程生命周期的开销和资源不足问题提供了解决方 案。通过对多个任务重用线程,线程创建的开销被分摊到了多个任务上。 线程实现方式 Thread、Runnable、Callable //实现Runnable接口的...

小强的进阶之路
昨天
6
0
maven 环境隔离

解决问题 即 在 resource 文件夹下面 ,新增对应的资源配置文件夹,对应 开发,测试,生产的不同的配置内容 <resources> <resource> <directory>src/main/resources.${deplo......

之渊
昨天
8
0
详解箭头函数和普通函数的区别以及箭头函数的注意事项、不适用场景

箭头函数是ES6的API,相信很多人都知道,因为其语法上相对于普通函数更简洁,深受大家的喜爱。就是这种我们日常开发中一直在使用的API,大部分同学却对它的了解程度还是不够深... 普通函数和...

OBKoro1
昨天
7
0
轻量级 HTTP(s) 代理 TinyProxy

CentOS 下安装 TinyProxy yum install -y tinyproxy 启动、停止、重启 # 启动service tinyproxy start# 停止service tinyproxy stop# 重启service tinyproxy restart 相关配置 默认...

Anoyi
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部