重写feign使用serviceId调用

重写feign使用serviceId调用

有时候需要在feign接口请求前.在url上拼接一些固定字符串.但是又不想在每个方法上都加一段.重写下面方法可以做到在feign构建httpclient后动态修改请求路径,相当于feign请求前URL处理拦截器

重写httpclient工厂类

package com.wmang.ext.client.feign;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.ILoadBalancer;
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory;
import org.springframework.cloud.netflix.ribbon.ServerIntrospector;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.util.ConcurrentReferenceHashMap;

import java.util.Map;

/**
 * Factory for SpringLoadBalancer instances that caches the entries created.
 *
 * @author Spencer Gibb
 * @author Dave Syer
 * @author Ryan Baxter
 * @author Gang Li
 * @author wmang
 */
public class ExampleCachingSpringLoadBalancerFactory {

    protected final SpringClientFactory factory;
    protected final ExampleLoadBalancerExtend loadBalancerExtend;
    protected LoadBalancedRetryFactory loadBalancedRetryFactory = null;

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

    public ExampleCachingSpringLoadBalancerFactory(SpringClientFactory factory, ExampleLoadBalancerExtend loadBalancerExtend) {
        this.factory = factory;
        this.loadBalancerExtend = loadBalancerExtend;
    }

    public ExampleCachingSpringLoadBalancerFactory(SpringClientFactory factory, LoadBalancedRetryFactory loadBalancedRetryPolicyFactory, ExampleLoadBalancerExtend loadBalancerExtend) {
        this.factory = factory;
        this.loadBalancerExtend = loadBalancerExtend;
        this.loadBalancedRetryFactory = loadBalancedRetryPolicyFactory;
    }

    public ExampleFeignLoadBalancer create(String clientName) {
        ExampleFeignLoadBalancer 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 = loadBalancedRetryFactory != null ? new ExampleRetryableFeignLoadBalancer(lb, config, serverIntrospector,
                loadBalancedRetryFactory, loadBalancerExtend) : new ExampleFeignLoadBalancer(lb, config, serverIntrospector, loadBalancerExtend);
        this.cache.put(clientName, client);
        return client;
    }

}

重写FeignLoadBalancedConfiguration

package com.wmang.ext.client.feign;

import feign.Client;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

/**
 * @author wmang
 */
@Configuration
public class ExampleFeignLoadBalancedConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public ExampleLoadBalancerExtend getExampleLoadBalancerExtend() {
        return new ExampleLoadBalancerExtend(null);
    }

    @Bean
    @Primary
    @ConditionalOnMissingBean
    @ConditionalOnMissingClass("org.springframework.retry.support.RetryTemplate")
    public ExampleCachingSpringLoadBalancerFactory ExampleCachingLBClientFactory(
            SpringClientFactory factory,ExampleLoadBalancerExtend loadBalancerExtend) {
        return new ExampleCachingSpringLoadBalancerFactory(factory,loadBalancerExtend);
    }

    @Bean
    @Primary
    @ConditionalOnMissingBean
    @ConditionalOnClass(name = "org.springframework.retry.support.RetryTemplate")
    public ExampleCachingSpringLoadBalancerFactory ExampleRetryabeCachingLBClientFactory(
            SpringClientFactory factory,
            LoadBalancedRetryFactory retryFactory,
            ExampleLoadBalancerExtend loadBalancerExtend) {
        return new ExampleCachingSpringLoadBalancerFactory(factory, retryFactory,loadBalancerExtend);
    }


    @Bean
    @Primary
    @ConditionalOnMissingBean
    public Client feignClient(ExampleCachingSpringLoadBalancerFactory cachingFactory,
                              SpringClientFactory clientFactory) {
        return new ExampleLoadBalancerFeignClient(new Client.Default(null, null),
                cachingFactory, clientFactory);
    }
}

重写loadBalance实现

package com.wmang.ext.client.feign;

import com.netflix.client.*;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import feign.Client;
import feign.Request;
import feign.Response;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.netflix.ribbon.RibbonProperties;
import org.springframework.cloud.netflix.ribbon.ServerIntrospector;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpRequest;

import java.io.IOException;
import java.net.URI;
import java.util.*;

import static org.springframework.cloud.netflix.ribbon.RibbonUtils.updateToSecureConnectionIfNeeded;

/**
 * @author wmang
 */
@Slf4j
public class ExampleFeignLoadBalancer extends
		AbstractLoadBalancerAwareClient<ExampleFeignLoadBalancer.RibbonRequest, ExampleFeignLoadBalancer.RibbonResponse> {

	private final RibbonProperties ribbon;
	protected int connectTimeout;
	protected int readTimeout;
	protected IClientConfig clientConfig;
	protected ServerIntrospector serverIntrospector;

	private ExampleLoadBalancerExtend loadBalancerExtend;

	public ExampleFeignLoadBalancer(ILoadBalancer lb, IClientConfig clientConfig,
							 ServerIntrospector serverIntrospector,ExampleLoadBalancerExtend loadBalancerExtend) {
		super(lb, clientConfig);
		this.setRetryHandler(RetryHandler.DEFAULT);
		this.clientConfig = clientConfig;
		this.ribbon = RibbonProperties.from(clientConfig);
		RibbonProperties ribbon = this.ribbon;
		this.connectTimeout = ribbon.getConnectTimeout();
		this.readTimeout = ribbon.getReadTimeout();
		this.serverIntrospector = serverIntrospector;
		this.loadBalancerExtend = loadBalancerExtend;
	}

	public ExampleFeignLoadBalancer(ILoadBalancer lb, RibbonProperties ribbon) {
		super(lb);
		this.ribbon = ribbon;
	}

	@Override
	public RibbonResponse execute(RibbonRequest request, IClientConfig configOverride)
			throws IOException {
		Request.Options options;
		if (configOverride != null) {
			RibbonProperties override = RibbonProperties.from(configOverride);
			options = new Request.Options(
					override.connectTimeout(this.connectTimeout),
					override.readTimeout(this.readTimeout));
		}
		else {
			options = new Request.Options(this.connectTimeout, this.readTimeout);
		}
		Response response = request.client().execute(request.toRequest(), options);
		return new RibbonResponse(request.getUri(), response);
	}

	@Override
	public RequestSpecificRetryHandler getRequestSpecificRetryHandler(
			RibbonRequest request, IClientConfig requestConfig) {
		if (this.ribbon.isOkToRetryOnAllOperations()) {
			return new RequestSpecificRetryHandler(true, true, this.getRetryHandler(),
					requestConfig);
		}
		if (!request.toRequest().httpMethod().name().equals("GET")) {
			return new RequestSpecificRetryHandler(true, false, this.getRetryHandler(),
					requestConfig);
		}
		else {
			return new RequestSpecificRetryHandler(true, true, this.getRetryHandler(),
					requestConfig);
		}
	}

	@Override
	public URI reconstructURIWithServer(Server server, URI original) {
		URI uri = updateToSecureConnectionIfNeeded(original, this.clientConfig, this.serverIntrospector, server);
		return loadBalancerExtend.reconstructURIWithServer(server, uri);
	}

	protected static class RibbonRequest extends ClientRequest implements Cloneable {

		private final Request request;
		private final Client client;

		protected RibbonRequest(Client client, Request request, URI uri) {
			this.client = client;
			setUri(uri);
			this.request = toRequest(request);
		}

		private Request toRequest(Request request) {
			Map<String, Collection<String>> headers = new LinkedHashMap<>(
					request.headers());
			return Request.create(request.httpMethod(), getUri().toASCIIString(), headers,
					request.requestBody());
		}

		Request toRequest() {
			return toRequest(this.request);
		}

		Client client() {
			return this.client;
		}

		HttpRequest toHttpRequest() {
			return new HttpRequest() {
				@Override
				public HttpMethod getMethod() {
					return HttpMethod
							.resolve(RibbonRequest.this.toRequest().httpMethod().name());
				}

				@Override
				public String getMethodValue() {
					return getMethod().name();
				}

				@Override
				public URI getURI() {
					return RibbonRequest.this.getUri();
				}

				@Override
				public HttpHeaders getHeaders() {
					Map<String, List<String>> headers = new HashMap<>();
					Map<String, Collection<String>> feignHeaders = RibbonRequest.this.toRequest().headers();
					for (Iterator<String> iterator = feignHeaders.keySet().iterator(); iterator.hasNext(); ) {
						String key = iterator.next();
						headers.put(key, new ArrayList<>(feignHeaders.get(key)));
					}
					HttpHeaders httpHeaders = new HttpHeaders();
					httpHeaders.putAll(headers);
					return httpHeaders;

				}
			};
		}

		public Request getRequest() {
			return request;
		}

		public Client getClient() {
			return client;
		}

		@Override
		public Object clone() {
			return new RibbonRequest(this.client, this.request, getUri());
		}
	}

	protected static class RibbonResponse implements IResponse {

		private final URI uri;
		private final Response response;

		protected RibbonResponse(URI uri, Response response) {
			this.uri = uri;
			this.response = response;
		}

		@Override
		public Object getPayload() throws ClientException {
			return this.response.body();
		}

		@Override
		public boolean hasPayload() {
			return this.response.body() != null;
		}

		@Override
		public boolean isSuccess() {
			return this.response.status() == 200;
		}

		@Override
		public URI getRequestedURI() {
			return this.uri;
		}

		@Override
		public Map<String, Collection<String>> getHeaders() {
			return this.response.headers();
		}

		Response toResponse() {
			return this.response;
		}

		@Override
		public void close() throws IOException {
			if (this.response != null && this.response.body() != null) {
				this.response.body().close();
			}
		}

	}

}

重写LoadBalancerURI重组方法

package com.wmang.ext.client.feign;

import com.google.common.base.Strings;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.LoadBalancerContext;
import com.netflix.loadbalancer.Server;
import com.netflix.niws.loadbalancer.DiscoveryEnabledServer;
import com.netflix.util.Pair;
import lombok.extern.slf4j.Slf4j;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.Map;

/**
 * @author: wmang
 * @date: 2020/3/27 13:35
 * @description:
 */
@Slf4j
public class ExampleLoadBalancerExtend extends LoadBalancerContext {
    public static final String METADATA_PUBLISH_VERSION = "pub-version";
    public static final String METADATA_PUBLISH_CODE = "pub-code";
    public static final String METADATA_PUBLISH_MICROSERVICE_NAME = "pub-service_name";
    public static final String URL_SPLIT_GANG = "/";

    public ExampleLoadBalancerExtend(ILoadBalancer lb) {
        super(lb);
    }

    @Override
    public URI reconstructURIWithServer(Server server, URI original) {
        log.info("自定义feignUrl解析开始处理【feignUrl】...");
        String host = server.getHost();
        int port = server.getPort();
        String scheme = server.getScheme();

        if (host.equals(original.getHost())
                && port == original.getPort()
                && scheme.equals(original.getScheme())) {
            return original;
        }
        if (scheme == null) {
            scheme = original.getScheme();
        }
        if (scheme == null) {
            scheme = deriveSchemeAndPortFromPartialUri(original).first();
        }

        try {
            StringBuilder sb = new StringBuilder();
            sb.append(scheme).append("://");
            if (!Strings.isNullOrEmpty(original.getRawUserInfo())) {
                sb.append(original.getRawUserInfo()).append("@");
            }
            sb.append(host);
            if (port >= 0) {
                sb.append(":").append(port);
            }
            if (isIssueService(server)) {
                sb.append(URL_SPLIT_GANG)
                        .append(getProviderCode(server))
                        .append(URL_SPLIT_GANG)
                        .append(getServiceName(server))
                        .append(URL_SPLIT_GANG)
                        .append(getServiceVersion(server));
            }
            sb.append(original.getRawPath());
            if (!Strings.isNullOrEmpty(original.getRawQuery())) {
                sb.append("?").append(original.getRawQuery());
            }
            if (!Strings.isNullOrEmpty(original.getRawFragment())) {
                sb.append("#").append(original.getRawFragment());
            }
            URI newURI = new URI(sb.toString());
            return newURI;
        } catch (URISyntaxException e) {
            log.error("feign url append error:{}", e.getMessage());
            throw new RuntimeException("feign url append error:"+e.getMessage());
        }
    }

    private String getServiceVersion(Server server) {
        DiscoveryEnabledServer discoveryEnabledServer = getDiscoveryServer(server);
        Map<String, String> metadata = discoveryEnabledServer.getInstanceInfo().getMetadata();
        return metadata.get(METADATA_PUBLISH_VERSION);
    }

    private String getServiceName(Server server) {
        DiscoveryEnabledServer discoveryEnabledServer = getDiscoveryServer(server);
        Map<String, String> metadata = discoveryEnabledServer.getInstanceInfo().getMetadata();
        return metadata.get(METADATA_PUBLISH_MICROSERVICE_NAME);
    }

    private String getProviderCode(Server server) {
        DiscoveryEnabledServer discoveryEnabledServer = getDiscoveryServer(server);
        Map<String, String> metadata = discoveryEnabledServer.getInstanceInfo().getMetadata();
        return metadata.get(METADATA_PUBLISH_CODE);
    }

    private boolean isIssueService(Server server) {
        if (server instanceof DiscoveryEnabledServer) {
            DiscoveryEnabledServer discoveryEnabledServer = getDiscoveryServer(server);
            Map<String, String> metadata = discoveryEnabledServer.getInstanceInfo().getMetadata();
            if (!metadata.containsKey(METADATA_PUBLISH_CODE)) {
                return false;
            }
            if (!metadata.containsKey(METADATA_PUBLISH_VERSION)) {
                return false;
            }
            if (!metadata.containsKey(METADATA_PUBLISH_MICROSERVICE_NAME)) {
                return false;
            }
            return true;
        }
        return false;
    }

    private DiscoveryEnabledServer getDiscoveryServer(Server server) {
        return (DiscoveryEnabledServer) server;
    }

    /**
     * Derive scheme and port from a partial URI. For example, for HTTP based client, the URI with
     * only path "/" should return "http" and 80, whereas the URI constructed with scheme "https" and
     * path "/" should return "https" and 443.
     * This method is called by {@link #getServerFromLoadBalancer(URI, Object)} and
     * {@link #reconstructURIWithServer(Server, URI)} methods to get the complete executable URI.
     */
    @Override
    protected Pair<String, Integer> deriveSchemeAndPortFromPartialUri(URI uri) {
        boolean isSecure = false;
        String scheme = uri.getScheme();
        if (scheme != null) {
            isSecure = scheme.equalsIgnoreCase("https");
        }
        int port = uri.getPort();
        if (port < 0 && !isSecure) {
            port = 80;
        } else if (port < 0 && isSecure) {
            port = 443;
        }
        if (isSecure) {
            scheme = "https";
        } else {
            scheme = "http";
        }
        return new Pair<String, Integer>(scheme, port);
    }
}

重写feign默认的httpClient对象(照搬,基本没改动)

package com.wmang.ext.client.feign;

import com.netflix.client.ClientException;
import com.netflix.client.config.CommonClientConfigKey;
import com.netflix.client.config.DefaultClientConfigImpl;
import com.netflix.client.config.IClientConfig;
import feign.Client;
import feign.Request;
import feign.Response;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;

import java.io.IOException;
import java.net.URI;

/**
 * @author wmang
 */
public class ExampleLoadBalancerFeignClient implements Client {

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

    private final Client delegate;
    private ExampleCachingSpringLoadBalancerFactory lbClientFactory;
    private SpringClientFactory clientFactory;

    public ExampleLoadBalancerFeignClient(Client delegate,
                                          ExampleCachingSpringLoadBalancerFactory lbClientFactory,
                                          SpringClientFactory clientFactory) {
        this.delegate = delegate;
        this.lbClientFactory = lbClientFactory;
        this.clientFactory = clientFactory;
    }

    @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);
            ExampleFeignLoadBalancer.RibbonRequest ribbonRequest = new ExampleFeignLoadBalancer.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;
    }

    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());
    }

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

    static class FeignOptionsClientConfig extends DefaultClientConfigImpl {

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

        @Override
        public void loadProperties(String clientName) {

        }

        @Override
        public void loadDefaultValues() {

        }

    }
}

重写feign原生的自动重试机制(照搬,基本没改动)

/*
 *
 *  * Copyright 2013-2016 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
 *  *
 *  *      http://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 com.wmang.ext.client.feign;

import com.netflix.client.DefaultLoadBalancerRetryHandler;
import com.netflix.client.RequestSpecificRetryHandler;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import feign.Request;
import feign.Response;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.*;
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient;
import org.springframework.cloud.netflix.ribbon.RibbonProperties;
import org.springframework.cloud.netflix.ribbon.ServerIntrospector;
import org.springframework.cloud.openfeign.ribbon.FeignRetryPolicy;
import org.springframework.cloud.openfeign.ribbon.RibbonResponseStatusCodeException;
import org.springframework.retry.RetryCallback;
import org.springframework.retry.RetryContext;
import org.springframework.retry.RetryListener;
import org.springframework.retry.backoff.BackOffPolicy;
import org.springframework.retry.backoff.NoBackOffPolicy;
import org.springframework.retry.policy.NeverRetryPolicy;
import org.springframework.retry.support.RetryTemplate;
import org.springframework.util.StreamUtils;

import java.io.IOException;
import java.net.URI;

/**
 * A {@link ExampleFeignLoadBalancer} that leverages Spring Retry to retry failed requests.
 *
 * @author Ryan Baxter
 * @author Gang Li
 * @author wmang
 */
public class ExampleRetryableFeignLoadBalancer extends ExampleFeignLoadBalancer implements ServiceInstanceChooser {

    private final LoadBalancedRetryFactory loadBalancedRetryFactory;

    public ExampleRetryableFeignLoadBalancer(ILoadBalancer lb, IClientConfig clientConfig, ServerIntrospector serverIntrospector,
                                             LoadBalancedRetryFactory loadBalancedRetryFactory,ExampleLoadBalancerExtend loadBalancerExtend) {
        super(lb, clientConfig, serverIntrospector,loadBalancerExtend);
        this.loadBalancedRetryFactory = loadBalancedRetryFactory;
        this.setRetryHandler(new DefaultLoadBalancerRetryHandler(clientConfig));
    }

    @Override
    public RibbonResponse execute(final RibbonRequest request, IClientConfig configOverride)
            throws IOException {
        final Request.Options options;
        if (configOverride != null) {
            RibbonProperties ribbon = RibbonProperties.from(configOverride);
            options = new Request.Options(
                    ribbon.connectTimeout(this.connectTimeout),
                    ribbon.readTimeout(this.readTimeout));
        } else {
            options = new Request.Options(this.connectTimeout, this.readTimeout);
        }
        final LoadBalancedRetryPolicy retryPolicy = loadBalancedRetryFactory.createRetryPolicy(this.getClientName(), this);
        RetryTemplate retryTemplate = new RetryTemplate();
        BackOffPolicy backOffPolicy = loadBalancedRetryFactory.createBackOffPolicy(this.getClientName());
        retryTemplate.setBackOffPolicy(backOffPolicy == null ? new NoBackOffPolicy() : backOffPolicy);
        RetryListener[] retryListeners = this.loadBalancedRetryFactory.createRetryListeners(this.getClientName());
        if (retryListeners != null && retryListeners.length != 0) {
            retryTemplate.setListeners(retryListeners);
        }
        retryTemplate.setRetryPolicy(retryPolicy == null ? new NeverRetryPolicy()
                : new FeignRetryPolicy(request.toHttpRequest(), retryPolicy, this, this.getClientName()));
        return retryTemplate.execute(new RetryCallback<RibbonResponse, IOException>() {
            @Override
            public RibbonResponse doWithRetry(RetryContext retryContext) throws IOException {
                Request feignRequest = null;
                //on retries the policy will choose the server and set it in the context
                //extract the server and update the request being made
                if (retryContext instanceof LoadBalancedRetryContext) {
                    ServiceInstance service = ((LoadBalancedRetryContext) retryContext).getServiceInstance();
                    if (service != null) {
                        feignRequest = ((RibbonRequest) request.replaceUri(reconstructURIWithServer(new Server(service.getHost(), service.getPort()), request.getUri()))).toRequest();
                    }
                }
                if (feignRequest == null) {
                    feignRequest = request.toRequest();
                }
                Response response = request.client().execute(feignRequest, options);
                if (retryPolicy != null && retryPolicy.retryableStatusCode(response.status())) {
                    byte[] byteArray = response.body() == null ? new byte[]{} : StreamUtils.copyToByteArray(response.body().asInputStream());
                    response.close();
                    throw new RibbonResponseStatusCodeException(ExampleRetryableFeignLoadBalancer.this.clientName, response,
                            byteArray, request.getUri());
                }
                return new RibbonResponse(request.getUri(), response);
            }
        }, new LoadBalancedRecoveryCallback<RibbonResponse, Response>() {
            @Override
            protected RibbonResponse createResponse(Response response, URI uri) {
                return new RibbonResponse(uri, response);
            }
        });
    }

    @Override
    public RequestSpecificRetryHandler getRequestSpecificRetryHandler(
            ExampleFeignLoadBalancer.RibbonRequest request, IClientConfig requestConfig) {
        return new RequestSpecificRetryHandler(false, false, this.getRetryHandler(), requestConfig);
    }

    @Override
    public ServiceInstance choose(String serviceId) {
        return new RibbonLoadBalancerClient.RibbonServer(serviceId,
                this.getLoadBalancer().chooseServer(serviceId));
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值