RestTemplate не работает в Spring Boot 3. Я перехожу с Spring Boot 2.x на 3.x.

У меня RestTemplate настроен для взаимодействия с двумя службами, но, поскольку это режим обслуживания, можем ли мы использовать RestTemplate в Spring Boot 3?

Одна из реализаций, конечная точка, настроенная через RestTemplate, не работает. Я не могу обмениваться данными между службами.

Здесь я получаю эту ошибку:

      java.lang.IllegalArgumentException: Service Instance cannot be null
    at org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient.execute(BlockingLoadBalancerClient.java:98)

Многие блоги предлагали использовать WebClient вместо RestTemplate.

Это мой класс конфигурации. Когда я удаляю эту аннотацию, операция RestTemplate работает нормально, но в моем случае мне нужно иметьтак как это перенаправит мой трафик на инстансы. Пожалуйста, предложите мне любое решение, чтобы решить эту проблему.

      @Configuration
@Slf4j
@Data

public class RestTemplateConfigLoadBalanced {

    private static final int FIX_DELAY = 10000;
    private final RestTemplateConfigProperties loadBalancedProperties;

    @Value("${discovery.port:8080}")
    private Integer discoveryPort;

    @LoadBalanced
    @Bean(name = "loadBalancedClient")
    public RestTemplate restTemplate(OutboundRequestIdAppender outboundRequestIdAppender,
                                     RestTemplateRequestLogger outboundRequestLogger) throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
        RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory1());

        List<ClientHttpRequestInterceptor> interceptors = restTemplate.getInterceptors();
        interceptors.add(outboundRequestIdAppender);
        interceptors.add(outboundRequestLogger);
        restTemplate.setInterceptors(interceptors);

        return restTemplate;
    }

    @Bean
    public HttpComponentsClientHttpRequestFactory clientHttpRequestFactory1() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
        HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();
        clientHttpRequestFactory.setHttpClient(httpClient1());

        return clientHttpRequestFactory;
    }

    @Bean
    public CloseableHttpClient httpClient1() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
        org.apache.hc.client5.http.config.RequestConfig requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(Timeout.ofDays(loadBalancedProperties.getRequestTimeout()))
                .setConnectionRequestTimeout(Timeout.ofDays(loadBalancedProperties.getConnectTimeout()))
                .setResponseTimeout(Timeout.ofDays(loadBalancedProperties.getSocketTimeout()))
                .build();

        SSLContext sslContext = SSLContexts.custom()
                .loadTrustMaterial(new TrustSelfSignedStrategy())
                .build();

        SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, org.apache.hc.client5.http.ssl.NoopHostnameVerifier.INSTANCE);

        Duration evictIdleDuration = Duration.of(loadBalancedProperties.getEvictIdleConnectionsIdleTime(), ChronoUnit.DAYS);
        long evictIdleMilliseconds = evictIdleDuration.toMillis();


        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", PlainConnectionSocketFactory.getSocketFactory())
                .register("https", sslSocketFactory)
                .build();

        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);


        HttpRequestRetryStrategy customRetryStrategy = new HttpRequestRetryStrategy() {
            @Override
            public boolean retryRequest(HttpRequest httpRequest, IOException e, int executionCount, HttpContext httpContext) {
                return retryHttpRequest(executionCount);
            }

            @Override
            public boolean retryRequest(HttpResponse httpResponse, int i, HttpContext httpContext) {
                return false;
            }

            @Override
            public TimeValue getRetryInterval(HttpResponse httpResponse, int i, HttpContext httpContext) {
                return null;
            }
        };

        return HttpClients.custom()
                .setSchemePortResolver(new SchemePortResolver() {
                    @Override
                    public int resolve(org.apache.hc.core5.http.HttpHost httpHost) {
                        return discoveryPort;
                    }

                })
                .setDefaultRequestConfig(requestConfig)
                .setConnectionManager(connectionManager)
                .evictIdleConnections(TimeValue.ofMilliseconds(evictIdleMilliseconds))
                .evictExpiredConnections()
                .setKeepAliveStrategy(connectionKeepAliveStrategy1())
//                .setRetryStrategy((exception, executionCount, context) -> retryHttpRequest(executionCount))
                .setRetryStrategy(customRetryStrategy)
                .build();
    }

    @Bean(name = "loadbalancePoolingConnectionManager")
    public org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager poolingConnectionManager1() {
        return getPoolingHttpClientConnectionManager(log, loadBalancedProperties.getMaxTotalConnections(), loadBalancedProperties.getMaxRoutePerHost());
    }

    @Bean
    public ConnectionKeepAliveStrategy connectionKeepAliveStrategy1() {
        return (response, context) -> TimeValue.ofDays(determineConnectionKeepAliveTime(response));
    }

    @Bean
    public Runnable idleConnectionMonitor(@Qualifier("loadbalancePoolingConnectionManager") final PoolingHttpClientConnectionManager connectionManager) {
        return getRunnable(connectionManager, log, loadBalancedProperties.getCloseIdleConnectionWaitTimeSecs());
    }

    public long determineConnectionKeepAliveTime(HttpResponse response) {
        return getConnectionKeepAliveTime(response, loadBalancedProperties.getDefaultKeepAliveTimeMillis());
    }
    static long getConnectionKeepAliveTime(HttpResponse response, int defaultKeepAliveTimeMillis) {
        BasicHeaderElementIterator it = new BasicHeaderElementIterator(response.headerIterator(HTTP.CONN_KEEP_ALIVE));

        while (it.hasNext()) {
            HeaderElement he = it.next();
            String param = he.getName();
            String value = he.getValue();

            if (value != null && param.equalsIgnoreCase("timeout")) {
                return Long.parseLong(value) * 1000;
            }
        }
        return defaultKeepAliveTimeMillis;
    }
    static Runnable getRunnable(PoolingHttpClientConnectionManager connectionManager, Logger log, int closeIdleConnectionWaitTimeSecs) {
        return new Runnable() {

            @Override
            @Scheduled(fixedDelay = FIX_DELAY)
            public void run() {
                if (connectionManager != null) {
                    log.trace("run IdleConnectionMonitor - Closing expired and idle connections...");
                    connectionManager.closeExpired();
                    connectionManager.closeIdle(TimeValue.ofDays(closeIdleConnectionWaitTimeSecs));
                } else {
                    log.trace("run IdleConnectionMonitor - Http Client Connection manager is not initialised");
                }
            }
        };
    }
    static PoolingHttpClientConnectionManager getPoolingHttpClientConnectionManager(Logger log, int maxTotalConnections, int maxRoutePerHost) {
        SSLContextBuilder builder = new SSLContextBuilder();
        try {
            builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
        } catch (NoSuchAlgorithmException | KeyStoreException e) {
            log.warn("Exception occurred while building SSL context", e);
        }

        SSLConnectionSocketFactory sslsf = null;
        try {
            sslsf = new SSLConnectionSocketFactory(builder.build());
        } catch (KeyManagementException | NoSuchAlgorithmException e) {
            log.warn("Exception occurred while creating SSL connection socket factory", e);
        }

        assert sslsf != null;
        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder
                .<ConnectionSocketFactory>create().register("https", sslsf)
                .register("http", new PlainConnectionSocketFactory())
                .build();

        PoolingHttpClientConnectionManager poolingConnectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
        poolingConnectionManager.setMaxTotal(maxTotalConnections);
        poolingConnectionManager.setDefaultMaxPerRoute(maxRoutePerHost);

        return poolingConnectionManager;
    }
    public boolean retryHttpRequest(int executionCount) {
        if (executionCount > loadBalancedProperties.getMaxExecutionCount()) {
            log.warn("Maximum retries {} reached", loadBalancedProperties.getMaxExecutionCount());
            return false;
        }

        log.warn("Retry http request. Retry Count: {}", executionCount);
        return true;
    }

}

0 ответов

Другие вопросы по тегам