Spring Boot REST接口可通过Keep-Alive复用TCP连接、RestTemplate连接池优化及SSE实现单向长连接推送,提升高频调用性能,但非WebSocket式全双工持久通道。

Spring Boot 的 REST 接口本身基于 HTTP 协议,而标准 REST 是无状态、短连接的——每次请求响应后连接默认关闭。所谓“REST 接口实现长连接”,实际是指在保持 HTTP 语义的前提下,通过配置底层 HTTP 客户端或服务端行为,复用 TCP 连接、减少握手开销,或配合其他机制(如 SSE)实现近似长连接效果。它不等于 WebSocket 那种全双工持久通道,但能显著提升高频调用场景下的性能。
一、服务端启用 HTTP Keep-Alive(最基础支持)
这是所有 Spring Boot 应用默认已支持的行为,无需额外编码:
- Spring Boot 内嵌 Tomcat(或 Jetty/Undertow)默认开启 HTTP/1.1,并自动设置
Connection: keep-alive响应头 - 客户端(如浏览器、curl、RestTemplate)只要不显式关闭连接,就会复用底层 TCP 连接
- 可通过配置调整空闲连接超时时间,避免连接堆积:
application.ymlserver: tomcat: connection-timeout: 20000 # 连接建立后等待请求的超时(毫秒) max-keep-alive-requests: 100 # 单连接最大请求数(-1 表示不限)注意:这属于连接复用优化,不是服务端主动推送能力。
二、客户端用 RestTemplate 复用连接池(关键实践)
如果你的 Spring Boot 应用作为 HTTP 客户端(比如调用第三方 API),要真正发挥长连接优势,必须替换默认的
SimpleClientHttpRequestFactory,改用带连接池的HttpComponentsClientHttpRequestFactory:- 配置连接池管理器,控制最大连接数、空闲检测等
- 设置请求超时为 0(表示不超时),让连接长期存活(需配合服务端 Keep-Alive 设置)
- 避免每次请求都新建 TCP 连接,大幅降低延迟和资源消耗
示例 Bean 配置:
java-api-doc-generator下载分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
@Bean public RestTemplate restTemplate() { PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); connManager.setMaxTotal(200); connManager.setDefaultMaxPerRoute(50); connManager.setValidateAfterInactivity(5000); // 空闲 5 秒后校验连接有效性 <pre class="brush:php;toolbar:false;">RequestConfig requestConfig = RequestConfig.custom() .setConnectTimeout(5000) .setSocketTimeout(10000) .setConnectionRequestTimeout(0) // 关键:获取连接不超时,支持长连接 .build(); CloseableHttpClient httpClient = HttpClientBuilder.create() .setConnectionManager(connManager) .setDefaultRequestConfig(requestConfig) .build(); HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient); return new RestTemplate(factory);}
三、用 Server-Sent Events(SSE)实现单向长连接推送
当需要服务端主动向客户端持续推送数据(如日志流、实时通知),又不想引入 WebSocket 复杂性时,SSE 是 REST 风格下的理想选择:
- 基于 HTTP,兼容性好;客户端用
EventSource即可监听 - 服务端返回
text/event-stream响应体,连接保持打开,持续写入事件 - 天然支持重连、事件 ID、自定义事件类型
Controller 示例:
@GetMapping(value = "/events", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public SseEmitter handleEvents() { SseEmitter emitter = new SseEmitter(30_000L); // 超时 30 秒 executorService.submit(() -> { try { for (int i = 0; i < 5; i++) { emitter.send(SseEmitter.event().name("update").data("msg-" + i)); Thread.sleep(2000); } } catch (Exception e) { emitter.completeWithError(e); } finally { emitter.complete(); } }); return emitter; }四、不推荐:强行在 REST 接口里“模拟”长连接
比如在 Controller 中用
while(true)循环写响应、禁用 response flush、设置极大超时等——这类做法风险高:- 阻塞 Tomcat 工作线程,极易引发线程耗尽、服务不可用
- 反向代理(如 Nginx)可能主动断开长时间无响应连接
- 违反 HTTP 语义,难以调试和监控
真正需要双向实时通信,请直接选用 WebSocket;需要服务端单向推送,请优先考虑 SSE。

















