feign如何实现负载均衡?

feign集成了ribbon,主要是通过ribbon来实现负载均衡

spring初始化默认加载resource下META-INF下spring.factory配置,其中FeignLoadBalancerAutoConfiguration是feign实现负载均衡的核心
feign配置文件

配置类需要加载的文件
HttpClientFeignLoadBalancerConfiguration:ApacheHttpClient请求配置
OkHttpFeignLoadBalancerConfiguration:OkHttpClient网络请求方式
DefaultFeignLoadBalancerConfiguration:默认HttpURLConnection

实现负载均衡的核心:FeignBlockingLoadBalancerClient中的LoadBalancerClient,LoadBalancerClient是调用的ribbon组件,通过ribbon来获取服务列表信息实现负载均衡

/*
 * Copyright 2013-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.cloud.openfeign.loadbalancer;

import java.io.IOException;
import java.net.URI;
import java.nio.charset.StandardCharsets;

import feign.Client;
import feign.Request;
import feign.Response;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.http.HttpStatus;
import org.springframework.util.Assert;

/**
 * A {@link Client} implementation that uses {@link LoadBalancerClient} to select a
 * {@link ServiceInstance} to use while resolving the request host.
 *
 * @author Olga Maciaszek-Sharma
 * @since 2.2.0
 */
public class FeignBlockingLoadBalancerClient implements Client {

	private static final Log LOG = LogFactory
			.getLog(FeignBlockingLoadBalancerClient.class);

	/**
	 * 网络请求方式
	 */
	private final Client delegate;

	/**
	 * 获取的ribbon服务
	 */
	private final LoadBalancerClient loadBalancerClient;

	public FeignBlockingLoadBalancerClient(Client delegate,
			LoadBalancerClient loadBalancerClient) {
		this.delegate = delegate;
		this.loadBalancerClient = loadBalancerClient;
	}

	/**
	 * 发起网络调用
	 * @param request
	 * @param options
	 * @return
	 * @throws IOException
	 */
	@Override
	public Response execute(Request request, Request.Options options) throws IOException {
		final URI originalUri = URI.create(request.url());
		String serviceId = originalUri.getHost();
		Assert.state(serviceId != null,
				"Request URI does not contain a valid hostname: " + originalUri);
		ServiceInstance instance = loadBalancerClient.choose(serviceId);
		if (instance == null) {
			String message = "Load balancer does not contain an instance for the service "
					+ serviceId;
			if (LOG.isWarnEnabled()) {
				LOG.warn(message);
			}
			return Response.builder().request(request)
					.status(HttpStatus.SERVICE_UNAVAILABLE.value())
					.body(message, StandardCharsets.UTF_8).build();
		}
		String reconstructedUrl = loadBalancerClient.reconstructURI(instance, originalUri)
				.toString();
		Request newRequest = Request.create(request.httpMethod(), reconstructedUrl,
				request.headers(), request.body(), request.charset(),
				request.requestTemplate());
		return delegate.execute(newRequest, options);
	}

	// Visible for Sleuth instrumentation
	public Client getDelegate() {
		return delegate;
	}

}

集群选择出的某一个服务
通过RetryableFeignLoadBalancer类来选择服务如何选择服务

通过调用ribbon选择服务ribbon选择服务
在这里插入图片描述
选择服务选择服务
负载均衡默认是轮询方案默认轮询负载方案
ribbon选择服务的方式
集群选择方案
AvailabilityFilteringRule:在RoundRibbon的基础上,选择满足条件的服务,如果10次了还没得到,则在满足条件的服务列表中,再用RoundRibbon算法选择.
BestAvailableRule:选择最小请求数
ClientConfigEnabledRoundRobinRule:轮询
RandomRule:随机选择一个server
RetryRule:根据轮询的方式重试
RoundRobinRule:轮询选择server
ZoneAvoidanceRule:根据server的zone区域和可用性来轮询选择
WeightedResponseTimeRule:根据响应时间去分配一个weight(权重),权重越低,被选择的可能性越低

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值