Настройка планировщика прокси-маршрутов в Spring-Cloud-Feign

Настройте планировщик прокси-маршрутов на Feign

Мне нужно знать, как делать запросы за прокси-сервером с помощью клиента REST весенней загрузки. Я могу сделать эту конфигурацию, используя общие ресурсы apache для запросов REST, например:

Метод, выполняющий POST:

Map <String, Object> map = new TreeMap <String, Object> ();

DynamicProxyRoutePlanner routePlanner = getProxy (param);

CloseableHttpClient closeableHttpClient = HttpClients.custom (). SetRoutePlanner (routePlanner) .build ();

Метод GetProxy:

private DynamicProxyRoutePlanner getProxy (Map <Integer, Object> param) {
        HttpHost proxy = new HttpHost ((String) param.get (PROXY), (Integer) param.get (PROXY_PORT));

        DynamicProxyRoutePlanner routePlanner = new DynamicProxyRoutePlanner (proxy);
        return routePlanner;
}

Класс DynamicProxyRoutePlanner:

public class DynamicProxyRoutePlanner implements HttpRoutePlanner {

    private DefaultProxyRoutePlanner defaultProxyRoutePlanner = null;

    public DynamicProxyRoutePlanner (HttpHost host) {
        defaultProxyRoutePlanner = new DefaultProxyRoutePlanner (host);
    }

    public void setProxy (HttpHost host) {
        defaultProxyRoutePlanner = new DefaultProxyRoutePlanner (host);
    }

    public HttpRoute determineRoute (HttpHost target, HttpRequest request, HttpContext context) throws HttpException {
        return defaultProxyRoutePlanner.determineRoute (target, request, context);
    }
}

Подводя итог...

  • Мне нужно создать такую ​​же конфигурацию ProxyRoutePlanner на Feign.

ОТРЕДАКТИРОВАНО --

я создал класс

@Configuration
public class FeignConfiguration {

с методами

@Bean
    @ConditionalOnMissingBean (CloseableHttpClient.class)
    public CloseableHttpClient httpClient () {
        DynamicProxyRoutePlanner routePlanner = getProxy ();
        CredentialsProvider credentialsProvider = getCredentials ();

        return HttpClients.custom ()
                .setDefaultCredentialsProvider (credentialsProvider)
                .setRoutePlanner (routePlanner) .build ();
    }

    private DynamicProxyRoutePlanner getProxy () {
        HttpHost proxy = new HttpHost (HOST_PROXY, PORT_PROXY);
        return new DynamicProxyRoutePlanner (proxy);
    }


    public CredentialsProvider getCredentials () {
        AuthCache authCache = new BasicAuthCache ();
        CredentialsProvider credsProvider = new BasicCredentialsProvider ();
        credsProvider.setCredentials (new AuthScope (HOST_PROXY, PORT_PROXY, AuthScope.ANY_HOST, "ntlm"),
                new NTCredentials (USER, PASS, "", DOMAIN));
        HttpClientContext context = HttpClientContext.create ();
        context.setCredentialsProvider (credsProvider);
        context.setAuthCache (authCache);
        return credsProvider;
    }

Я перенастроил тесты подключения, но хотя Feign, похоже, не пытается использовать настройки прокси, см. ошибку ниже:

2018-04-25 09: 59: 10.494 ERROR 25309 --- [nio-9063-exec-2] oaccC [. [. [.] [DispatcherServlet]: Servlet.service () for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is feign.RetryableException: Connection refused (Connection refused) executing POST http://sinaflor-api.des.basis.com.br/api/empreendimentos] with root cause

java.net.ConnectException: Connection refused (Connection refused)
at java.net.PlainSocketImpl.socketConnect (Native Method) ~ [na: 1.8.0_171]
at java.net.AbstractPlainSocketImpl.doConnect (AbstractPlainSocketImpl.java:350) ~ [na: 1.8.0_171]
at java.net.AbstractPlainSocketImpl.connectToAddress (AbstractPlainSocketImpl.java:206) ~ [na: 1.8.0_171]
at java.net.AbstractPlainSocketImpl.connect (AbstractPlainSocketImpl.java:188) ~ [na: 1.8.0_171]
at java.net.SocksSocketImpl.connect (SocksSocketImpl.java:392) ~ [na: 1.8.0_171]
at java.net.Socket.connect (Socket.java:589) ~ [na: 1.8.0_171]
at sun.net.NetworkClient.doConnect (NetworkClient.java:175) ~ [na: 1.8.0_171]
at sun.net.www.http.HttpClient.openServer (HttpClient.java:463) ~ [na: 1.8.0_171]
at sun.net.www.http.HttpClient.openServer (HttpClient.java:558) ~ [na: 1.8.0_171]
at sun.net.www.http.HttpClient. <init> (HttpClient.java:242) ~ [na: 1.8.0_171]
at sun.net.www.http.HttpClient.New (HttpClient.java:339) ~ [na: 1.8.0_171]
at sun.net.www.http.HttpClient.New (HttpClient.java:357) ~ [na: 1.8.0_171]
at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient (HttpURLConnection.java:1220) ~ [na: 1.8.0_171]
at sun.net.www.protocol.http.HttpURLConnection.plainConnect0 (HttpURLConnection.java:1156) ~ [na: 1.8.0_171]
at sun.net.www.protocol.http.HttpURLConnection.plainConnect (HttpURLConnection.java:1050) ~ [na: 1.8.0_171]
at sun.net.www.protocol.http.HttpURLConnection.connect (HttpURLConnection.java:984) ~ [na: 1.8.0_171]
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0 (HttpURLConnection.java:1334) ~ [na: 1.8.0_171]
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream (HttpURLConnection.java:1309) ~ [na: 1.8.0_171]
at feign.Client $ Default.convertAndSend (Client.java:133) ~ [feign-core-9.3.1.jar: na]
at feign.Client $ Default.execute (Client.java:73) ~ [feign-core-9.3.1.jar: na]
at feign.SynchronousMethodHandler.executeAndDecode (SynchronousMethodHandler.java:97) ~ [feign-core-9.3.1.jar: na]
at feign.SynchronousMethodHandler.invoke (SynchronousMethodHandler.java:76) ~ [feign-core-9.3.1.jar: na]
at feign.ReflectiveFeign $ FeignInvocationHandler.invoke (ReflectiveFeign.java:103) ~ [feign-core-9.3.1.jar: na]
at com.sun.proxy $ Proxy112.send (Unknown Source) ~ [na: na]

person Diego Cândido da Silva    schedule 23.04.2018    source источник


Ответы (3)


Мне удалось разрешить конфигурацию прокси-сервера при симуляции с помощью okHttpClient следующим образом:

@Configuration
public class FeignConfigurationProxy {

    @Value("${url.proxy_host}")
    private String HOST_PROXY;
    @Value("${url.proxy_port}")
    private Integer PORT_PROXY;

    private OkHttpClient okHttpClient;
    private Proxy proxy;

    @PostConstruct
    public void init() {
        buildProxy();
        buildOkHttpClient();
    }

    @Bean(name = "feign")
    public Feign buildClient() {
        return Feign.builder().client(new feign.okhttp.OkHttpClient(okHttpClient)).build();
    }


    @Bean(name = "okhttpclient")
    public OkHttpClient okHttpClient() {
        return okHttpClient;
    }

    public void buildOkHttpClient() {
        buildProxy();
        okHttpClient = new OkHttpClient.Builder().proxy(proxy).build();
    }

    public void buildProxy() {
        proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(HOST_PROXY, PORT_PROXY));
    }

}

в pom.xml я добавил зависимости:

<dependency>
<groupId> io.github.openfeign </ groupId>
<artifactId> feign-okhttp </ artifactId>
<version> 9.5.0 </ version>
</ dependency>
<dependency>
<groupId> com.squareup.okhttp3 </ groupId>
<artifactId> okhttp </ artifactId>
<version> 3.10.0 </ version>
</ dependency>
person Diego Cândido da Silva    schedule 26.04.2018
comment
feign-okhttp работает лучше, чем apache? Каковы передовые методы настройки производительности? - person Tal Avissar; 02.07.2018
comment
возможно, такая же производительность, используя spring-cloud-feign, по умолчанию он использует клиент okhttp вместо клиента apache, что заставляет меня думать, что okhttp на самом деле имеет преимущество перед клиентом apache! Когда дело доходит до настройки http-клиента, я считаю, что лучший способ настроить его — это настроить по умолчанию, настроив минимально возможный, поскольку он уже спроектирован таким образом, чтобы в большинстве случаев он работал быстро и стабильно, оставляя настройки для таких случаев, как этот, когда мне приходилось фактически обрабатывать запросы через корпоративный прокси или нет. - person Diego Cândido da Silva; 02.07.2018
comment
@DiegoCândidodaSilva - Spring Cloud openfeign по умолчанию не OkHttpClient. Вместо этого feign.Client.Default. Клиенты OkHttpClient и ApacheHttpClient feign можно использовать, установив для feign.okhttp.enabled или feign.httpclient.enabled значение true соответственно и добавив их в путь к классам. Ссылка: cloud.spring.io /spring-cloud-openfeign/ссылка/html/ - person Amith Kumar; 12.03.2021

Spring cloud openfeign поддерживает три базовые реализации:

  1. По умолчанию
  2. ApacheHttpClient
  3. OkHttpClient

В зависимости от того, какая реализация используется в вашем проекте, вот как вы настраиваете ложный клиент для использования HTTP-прокси: ТРЮК: вы настраиваете ложный клиент, а затем переопределяете клиентский компонент по умолчанию в контексте приложения Spring.

По умолчанию:

import feign.Client;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.net.InetSocketAddress;
import java.net.Proxy;

@Configuration
public class FeignConfiguration {
  ...
  @Bean
  public Client feignClient() {
      return new Client.Proxied(null, null, 
                 new Proxy(Proxy.Type.HTTP,
                     new InetSocketAddress(proxyHost, proxyPort)));
  }
}

С ApacheHttpClient:

когда у вас feign.httpclient.enabled: true в application.yml и ниже в pom.xml или build.gradle:

pom.xml
<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-httpclient</artifactId>
</dependency>

build.gradle
implementation 'io.github.openfeign:feign-httpclient'


import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.apache.http.HttpHost;

@Configuration
public class FeignConfiguration {
  ...
  @Bean
  public CloseableHttpClient feignClient() {
    return HttpClientBuilder.create().setProxy(
              new HttpHost(proxyHost, proxyPort)).build();
  }
}

С OkHttpClient:

когда у вас feign.okhttp.enabled: true в application.yml и ниже в pom.xml или build.gradle:

pom.xml
<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-okhttp</artifactId>
</dependency>

build.gradle
implementation 'io.github.openfeign:feign-okhttp'


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.net.InetSocketAddress;
import java.net.Proxy;
import okhttp3.OkHttpClient;

@Configuration
public class FeignConfiguration {
  ...
  @Bean
  public OkHttpClient okHttpClient() {
    return new OkHttpClient.Builder()
       .proxy(new Proxy(Proxy.Type.HTTP, 
             new InetSocketAddress(proxyHost, proxyPort)))
       .build();
  }
}
person Amith Kumar    schedule 12.03.2021

Просто определите свой CloseableHttpClient как Spring Bean.

Начиная с выпуска Spring Cloud Edgware, если вы определяете CloseableHttpClient как Spring Bean, он будет использоваться вместо компонента по умолчанию.

person yongsung.yoon    schedule 24.04.2018
comment
У вас есть примеры такой конфигурации, как бы вы использовали притворство? - person Diego Cândido da Silva; 24.04.2018
comment
Никакой специальной настройки не требуется. Текущий класс FeignAutoConfiguration загружает только свой собственный компонент CloseableHttpClient, если он не существует, как показано ниже. @ConditionalOnMissingBean(CloseableHttpClient.класс). Поэтому, если вы определите свой CloseableHttpClient как spean, он будет использоваться внутри feign. - person yongsung.yoon; 25.04.2018
comment
Я отредактировал тему с новыми ошибками после предложенной реализации, если вы можете помочь мне с этим решением, это мне очень поможет. - person Diego Cândido da Silva; 25.04.2018
comment
какую версию весеннего облака вы используете? И вам не нужно использовать @ConditionalOnMissingBean для вас. - person yongsung.yoon; 25.04.2018