升级Spring Boot至HTTP/2后RestTemplate跨应用通信协议降级问题
解决Spring Boot RestTemplate调用HTTP/2服务时协议降级问题
问题背景
我们将Spring Boot微服务从HTTP/1.1升级至HTTP/2,服务端已通过application.properties配置启用HTTP/2并正常运行,单个应用端点访问时协议为HTTP/2,但通过App1的RestTemplate调用App2端点时,App2接收到的请求协议降级为HTTP/1.1。
核心原因
当前RestTemplate使用的是默认HTTP/1.1客户端实现,未启用HTTP/2支持;尝试的异步HTTP客户端CloseableHttpAsyncClient与RestTemplate依赖的同步请求工厂不兼容,导致配置失效。
解决方案
1. 确认依赖完整性
确保项目已引入HTTP/2相关依赖(你已配置,可跳过此步):
<dependency> <groupId>org.apache.httpcomponents.client5</groupId> <artifactId>httpclient5</artifactId> <version>5.3.1</version> </dependency> <dependency> <groupId>org.apache.httpcomponents.core5</groupId> <artifactId>httpcore5-h2</artifactId> <version>5.2.5</version> </dependency>
2. 配置支持HTTP/2的同步RestTemplate
替换原有RestTemplate配置,使用HttpClient5的HTTP/2同步客户端构建:
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder; import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; import org.apache.hc.client5.http.io.HttpClientConnectionManager; import org.apache.hc.client5.http.ssl.ClientTlsStrategyBuilder; import org.apache.hc.core5.ssl.TLS; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplateBuilder; import org.springframework.web.client.ResponseErrorHandler; import org.springframework.web.client.DefaultResponseErrorHandler; @Configuration public class RestTemplateConfig { private final int restTemplateHttpMaxConnection = 100; private final int restTemplateHttpMaxPerRouteConnection = 50; @Bean public RestTemplate restTemplate() { // 构建支持HTTP/2的连接管理器 HttpClientConnectionManager connectionManager = PoolingHttpClientConnectionManagerBuilder.create() .setMaxTotal(restTemplateHttpMaxConnection) .setDefaultMaxPerRoute(restTemplateHttpMaxPerRouteConnection) // 配置TLS策略,HTTP/2要求至少TLS 1.2 .setTlsStrategy(ClientTlsStrategyBuilder.create() .setTlsVersions(TLS.V_1_3, TLS.V_1_2) .build()) .build(); // 构建支持HTTP/2的同步HttpClient CloseableHttpClient httpClient = HttpClientBuilder.create() .setConnectionManager(connectionManager) .build(); // 配置同步请求工厂 HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient); requestFactory.setConnectTimeout(30000); requestFactory.setConnectionRequestTimeout(30000); // 构建RestTemplate return new RestTemplateBuilder() .requestFactory(() -> requestFactory) .errorHandler(responseErrorHandler()) .additionalInterceptors(new LoggingInterceptor()) .build(); } // 保留原有错误处理器实现 private ResponseErrorHandler responseErrorHandler() { return new DefaultResponseErrorHandler(); } }
3. 关键配置说明
- 使用
PoolingHttpClientConnectionManagerBuilder替代直接实例化连接管理器,方便配置TLS策略以启用HTTP/2支持。 - 明确指定TLS版本为1.2或更高,HTTP/2协议要求必须使用加密传输(明文h2c不推荐生产环境使用)。
- 必须使用同步的CloseableHttpClient,
HttpComponentsClientHttpRequestFactory仅支持同步客户端,异步客户端无法适配。
4. 验证结果
配置完成后,在App2中打印请求协议:
System.out.println("Received request protocol: " + request.getProtocol());
此时应输出HTTP/2.0,确认协议未降级。
内容的提问来源于stack exchange,提问作者MPPNBD
相关产品推荐
相关产品推荐

