[Aprenda a apreciar Netflix] sessenta, fita tem a capacidade de cliente balanceamento de carga: AbstractLoadBalancerAwareClient

Quando você quiser encontrar um erro em seu código, é difícil, quando você acha que o seu código não é um erro, o que é ainda mais difícil.

-> retorno Lista coluna <-
Download Endereço: https://github.com/f641385712/netflix-learning

prefácio

Fita não é apenas balanceamento de carga, balanceamento de carga é apenas um dos seu núcleo, o mais famoso de apenas o módulo. No bate-papo ribbon-core, quando sabemos que ele tem uma API núcleo é IClientque indica envia uma solicitação para obter uma resposta, não especifica o método de transmissão, protocolo e assim por diante.

Porque a função do núcleo da fita é para carregar o equilíbrio, e, portanto, neste artigo vamos aprender que tem uma capacidade de balanceamento de carga do cliente: AbstractLoadBalancerAwareClient, é na jarra: ribbon-loadbalancer.


texto

AbstractLoadBalancerAwareClient

Porque nós somos menos propensos a usar a fita quando outro, mas apenas como balanceamento de carga, para que possa ser entendido como simples e cru: AbstractLoadBalancerAwareCliento pai de nível superior de toda a implementação do cliente , mas na verdade ele é.

Note-se que não só os implementos classe abstrata de uma interface IClient, e também herdado de LoadBalancerContext, por isso não é apenas possuir um cliente, balanceamento de carga também tem um contexto.

A classe abstrata não tem propriedades de membros, fornece um número de maneiras:


método de inicialização

Ele fornece dois construtores para a inicialização.

public abstract class AbstractLoadBalancerAwareClient<S extends ClientRequest, T extends IResponse> extends LoadBalancerContext implements IClient<S, T>, IClientConfigAware {

    public AbstractLoadBalancerAwareClient(ILoadBalancer lb) {
        super(lb);
    }
    public AbstractLoadBalancerAwareClient(ILoadBalancer lb, IClientConfig clientConfig) {
        super(lb, clientConfig);        
    }

}

Como um balanceamento de carga e cliente relacionado, balanceador de carga ILoadBalanceré essencial para mim.


buildLoadBalancerCommand () para comando de balanceamento de carga de construção

Fita Todas as solicitações são executadas com base em modo de comando a ser executado, e, portanto, requerem empacotado como um LoadBalancerCommandcomando:

AbstractLoadBalancerAwareClient:

	// 抽象方法:提供一个RequestSpecificRetryHandler重试处理器
	// 因为重试方案父类定不了:有些是超时重试,有些是异常重试,因此交给子类去决定为好
	// 但请保证是RequestSpecificRetryHandler的子类:因为它已经帮你实现了写基本逻辑
	// 一般使用包装器模式,给RequestSpecificRetryHandler.fallback赋值了就好
	public abstract RequestSpecificRetryHandler getRequestSpecificRetryHandler(S request, IClientConfig requestConfig);
	// 毕竟LoadBalancerCommand的属性众多,默认只给其设置必要的属性,其它的交给调用者去个性化吧
	// 比如常用的:增加监听器来监听必要的执行过程
	protected void customizeLoadBalancerCommandBuilder(S request, IClientConfig config, LoadBalancerCommand.Builder<T> builder) {
		// 空实现,交给子类去定制
	}

	// request请求对象,提供URI(注意不是URL,因为不一定是网络请求)
    protected LoadBalancerCommand<T> buildLoadBalancerCommand(S request, IClientConfig config) {
    	// 得到重试处理器:因为重试处理器对LoadBalancerCommand的行为特别重要
		RequestSpecificRetryHandler handler = getRequestSpecificRetryHandler(request, config);
		LoadBalancerCommand.Builder<T> builder = LoadBalancerCommand.<T>builder()
				.withLoadBalancerContext(this)
				.withRetryHandler(handler)
				.withLoadBalancerURI(request.getUri());
		customizeLoadBalancerCommandBuilder(request, config, builder);
		return builder.build();
	}

Ele deixa um método abstrato e um método para ligar AbstractLoadBalancerAwareClientpara completar a personalização ~


executeWithLoadBalancer () com a implementação de capacidades de balanceamento de carga

Não é um método de interface: porque o método de interface não tem capacidades de balanceamento de carga. Mas é muito muito mais importante: a embalagem do execute()método de interface, no LoadBalancerCommandinterior de modo que você tem que executar o balanceamento de carga capacidade.

AbstractLoadBalancerAwareClient:

	// 注意:接口方法只有execute,这是在外层套了一个负载均衡器,均由负载均衡的能力
    public T executeWithLoadBalancer(S request) throws ClientException {
        return executeWithLoadBalancer(request, null);
    }

    public T executeWithLoadBalancer(final S request, final IClientConfig requestConfig) throws ClientException {
    	// 构建一个执行命令:command
    	LoadBalancerCommand<T> command = buildLoadBalancerCommand(request, requestConfig);


		// 提交目标操作/目标请求  -> 执行目标方法
    	return command.submit(server -> {
    		// 根据LB选中的Server,构建出一个最终的URI
    		// 因为你的URI可能没有host、port等是不完整的
    		URI finalUri = reconstructURIWithServer(server, request.getUri());
    		// 给request重新制定一个新的URI
    		S requestForServer = (S) request.replaceUri(finalUri);
    		
    		// execute执行目标方法:一般是发送http请求,当然这不是一定的~
    		return Observable.just(AbstractLoadBalancerAwareClient.this.execute(requestForServer, requestConfig));
    	})
    	// 阻塞的,顺序执行 使用RxJava是为了编程方便、优美
		.toBlocking()
		.single();
    }
}

Descrição: De forma a estrutura de código claro, construiu um monte de try ... catch são omitidos

A essência do método é a: utilização LoadBalancerCommandde embalagens executemétodo de destino, de modo que tem uma capacidade de equilíbrio de carga. Portanto, na aplicação prática: Não chamar diretamente o executemétodo, mas usando mais superior, mais poderosos executeWithLoadBalancer()métodos.


Se somente em ribbon-loadbalancerdentro do frasco, ICliento sistema tem um e somente nesta sub-categoria AbstractLoadBalancerAwareClient, e é uma classe abstrata. Desde o balanceador de carga não se limita a esse protocolo específico, como http, TCP, UDP, etc, são o balanceamento de carga pode ser feito neste jar não tem qualquer classe de implementação do cliente especial .

Mas no ambiente Primavera Nuvem, uma próspera:

Aqui Insert Picture Descrição
Aqui Insert Picture Descrição
Ele não vai Primavera Nuvem na sua implementação, mas colocá-lo nas secções relevantes e na integração Primavera Cloud.


ClientFactory

Uma vez que o cliente é tão importante, a fim de forma rápida e facilmente obter uma instância de cliente, fita fornece ClientFactoryesta classe de fábrica. Esta classe é usada para criar rapidamente um IClientcliente ILoadBalancer, IClientConfigcomo fábricas. Ele também mantém o mapa interno e global, obter cache para melhorar a eficiência.

public class ClientFactory {

	// key是ClientName  value是Client实例
	private static Map<String, IClient<?,?>> simpleClientMap = new ConcurrentHashMap<>();
	// key是Lb的名称  value是LB实例
	private static Map<String, ILoadBalancer> namedLBMap = new ConcurrentHashMap<>();
	// key是ClientName  value是该client对应的配置(含默认配置)
	private static ConcurrentHashMap<String, IClientConfig> namedConfig = new ConcurrentHashMap<>();

	// ==========工具方法们=========
	
	// 反射创建一个实例,并且调用其initWithNiwsConfig()方法把config传递给它
	public static Object instantiateInstanceWithClientConfig(String className, IClientConfig clientConfig) {
		...
		IClientConfigAware obj = (IClientConfigAware) clazz.newInstance();
		obj.initWithNiwsConfig(clientConfig);
		return obj;
	}

	// 反射创建一个clientConfigClass类型的配置。IClientConfig接口的自带实现仅有DefaultClientConfigImpl
	// 注意config.loadProperties(name)方法会被调用哦(配置会被加载进来)
	// 最后放进缓存(缓存里就返回缓存里的)
	public static IClientConfig getNamedConfig(String name, Class<? extends IClientConfig> clientConfigClass) {
        IClientConfig config = namedConfig.get(name);
        if (config != null) {
            return config;
        } 
        config = (IClientConfig) clientConfigClass.newInstance();
        config.loadProperties(name);
        ...
        return config;
	}
    public static IClientConfig getNamedConfig(String name) {
        return 	getNamedConfig(name, DefaultClientConfigImpl.class);
    }

	... // 创建`ILoadBalancer`实例的方法几乎一模一样,略

	// 提供名称和客户端配置的实用程序方法来创建客户端和负载均衡器(如果在客户端配置中启用)
	// InitializeNFLoadBalancer默认配置值是true,开启负载均衡器的
	public static synchronized IClient<?, ?> registerClientFromProperties(String restClientName, IClientConfig clientConfig) throws ClientException {
    	IClient<?, ?> client = null;
    	ILoadBalancer loadBalancer = null;
    	// 如果同名的Client已经创建过了,在调用此方法就抛错,而并非把缓存里的返回给你
    	if (simpleClientMap.get(restClientName) != null) {
    		throw new ClientException(ClientException.ErrorType.GENERAL, "A Rest Client with this name is already registered. Please use a different name");
    	}
    	... // 反射创建Client、LB的实例
		simpleClientMap.put(restClientName, client);
		return client;
	}

	// 它木有传入配置:所以全部使用外部化配置
    public static synchronized IClient getNamedClient(String name) {
        return getNamedClient(name, DefaultClientConfigImpl.class);
    }
    public static synchronized IClient getNamedClient(String name, Class<? extends IClientConfig> configClass) {
    	if (simpleClientMap.get(name) != null) {
    	    return simpleClientMap.get(name);
    	}
    	return createNamedClient(name, configClass);
    }
}

Que ClientFactory.instantiateInstanceWithClientConfig()método é o mais versátil: pode ajudá-lo a casos instanciar de qualquer instância, incluindo os cinco componentes principais. A vantagem é que você automaticamente Depois de chamada de inicialização initWithNiwsConfig()método de atribuição de propriedade completa -


resumo

Sobre fita com recursos de balanceamento de carga do cliente: AbstractLoadBalancerAwareClient-lo introduzido pela primeira vez a este, embora mencionados neste artigo são de madeira e exemplos de código classe de implementação concreta são dadas, mas uma vez que você entendê-la (na verdade, o núcleo é LoadBalancerCommand) você pensaria que o outro é um pediatra, este continuará a ser descrito mais tarde, quando explicando integração.

Até agora, cerca de fita, de longe, a parte mais central (core e contém loadbalancer) vai apresentar todo, embora este projecto foi agora parou mais, mas parada com mais non-stop , ainda é o mainstream (ou mesmo a única) balanceamento de carga do cliente dispositivo. Ele pode ser usado não só para aprender no sistema Primavera nuvem com facilidade, tais como a estrutura para carga dubbo compreensão mecanismo de balanceamento são fáceis, o outro, tanto quanto eu entendo a compreensão em profundidade da fita, e as pessoas têm a capacidade de usá-lo para conseguir a implantação multi-zona não é muito, então Se você dominar a sua promoção e aumento salarial não é que o peso dele ~

Claro, isso não é toda a fita série, para trás, mas também sobre a integração do combate na Primavera Cloud. Com forte suporte teórico para fazer, para explicar o rápido muito real.
linha divisória

afirmação

O original não é fácil, não é fácil de palavra de código, muito obrigado pela sua polegares, coleção, atenção. 把本文分享到你的朋友圈是被允许的,但拒绝抄袭. Você também pode código de verificação [para a esquerda / ou adicionar wx: fsx641385712] Eu convido você para participar da Engenharia Java, Architect Series aprendizagem em grupo familiar e comunicação.
passado em destaque

Publicado 362 artigos originais · Louvor obteve 531 · vista 480 000 +

Acho que você gosta

Origin blog.csdn.net/f641385712/article/details/104998870
Recomendado
Clasificación