JDK HttpClient接口hang住,永远没有返回
背景
这两天遇到一个问题,我有两个服务,java端和Python fast API,java通过JDK的HttpClient调用接口。
其他调用都是正常的,就是有一个接口非常慢,而且我没有设置超时时间,因为这是一个任务处理的程序,我知道很慢。
Python端的日志都返回了完成了,但是Java端还是在等待,几个小时了还没有完成:
10:55:37.522 INFO c.y.r.s.a.asr.WhisperApiRecognizer - 调用 OpenAI Whisper API:task=a000480719b14b0b, audio=/app/workfolder/local/Kubernetes Tutorial for Beginners [FULL COURSE in 4 Hours]__a000480719b14b0b/media/audio_vocals.wav, url=http://192.168.1.2:8001/v1/audio/transcriptions?model=whisper-1&response_format=verbose_json&language=en
2026-07-07 12:02:41,195 | INFO | unified-python-services | Request completed: file=audio, audio_dur=13014.99s, transcribe=3899.91s, total=4007.34s, device=cpu(int8)
INFO: 172.17.80.1:6036 - "POST /v1/audio/transcriptions?model=whisper-1&response_format=verbose_json&language=en HTTP/1.1" 200 OK
问题猜测
问AI的话,说了很多理由:

问题排查
还是靠线程栈分析,通过jstack <vmid>查看线程堆栈,发现这两个线程:
- task-1 线程等了几个小时还在等,实际Python端早都返回200了。
- SelectorManager 虽然 RUNNABLE,但已丢失对该连接的事件跟踪
说明是JDK HttpClient 内部状态机出了问题
"task-1" #42 [73] prio=5 os_prio=0 cpu=1901.98ms elapsed=50948.30s tid=0x0000719fdc8671d0 nid=73 waiting on condition [0x0000719b462fd000]
java.lang.Thread.State: WAITING (parking)
at jdk.internal.misc.Unsafe.park(java.base@21.0.11/Native Method)
- parking to wait for <0x000004000ce26818> (a java.util.concurrent.CompletableFuture$Signaller)
at java.util.concurrent.locks.LockSupport.park(java.base@21.0.11/Unknown Source)
at java.util.concurrent.CompletableFuture$Signaller.block(java.base@21.0.11/Unknown Source)
at java.util.concurrent.ForkJoinPool.unmanagedBlock(java.base@21.0.11/Unknown Source)
at java.util.concurrent.ForkJoinPool.managedBlock(java.base@21.0.11/Unknown Source)
at java.util.concurrent.CompletableFuture.waitingGet(java.base@21.0.11/Unknown Source)
at java.util.concurrent.CompletableFuture.get(java.base@21.0.11/Unknown Source)
at com.youdub.replica.util.HttpUtil.sendInterruptible(HttpUtil.java:34)
at com.youdub.replica.service.adapter.asr.WhisperApiRecognizer.transcribe(WhisperApiRecognizer.java:85)
"HttpClient-1-SelectorManager" #41 [71] daemon prio=5 os_prio=0 cpu=1025.90ms elapsed=15302.29s tid=0x0000719fdcfdc1d0 nid=71 runnable [0x0000719b46d2e000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.EPoll.wait(java.base@21.0.11/Native Method)
at sun.nio.ch.EPollSelectorImpl.doSelect(java.base@21.0.11/Unknown Source)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(java.base@21.0.11/Unknown Source)
- locked <0x000004001957d518> (a sun.nio.ch.Util$2)
- locked <0x000004001957d230> (a sun.nio.ch.EPollSelectorImpl)
at sun.nio.ch.SelectorImpl.select(java.base@21.0.11/Unknown Source)
at jdk.internal.net.http.HttpClientImpl$SelectorManager.run(java.net.http@21.0.11/Unknown Source)
问题解决
有相关类似的bugJDK-8377796,但是要升级JDK,所以根据AI的建议:
- 不用异步的方式调用,但是中断功能会有问题,因为如果任务时间太长,我这边要能够手动中断。
- 更换其他http client,目前来看可以试试。
选择Ok http的原因:
- OkHttp 的 enqueue() 工作在线程池回调上,没有 SelectorManager 单点故障
- call.cancel() 可靠关闭底层 TCP socket(vs JDK future.cancel(true) 不保证释放连接)
- 广泛验证的生产级 HTTP 客户端
原文链接:https://blog.dengwei.site/article/jdk-httpclient-hang-bug
本文来自博客园,作者:衣来伸手饭来张口,转载请注明原文链接:https://www.cnblogs.com/autowin/p/21231635

浙公网安备 33010602011771号