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的话,说了很多理由:
alt

问题排查

还是靠线程栈分析,通过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的建议:

  1. 不用异步的方式调用,但是中断功能会有问题,因为如果任务时间太长,我这边要能够手动中断。
  2. 更换其他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

posted @ 2026-07-08 09:33  衣来伸手饭来张口  阅读(1)  评论(0)    收藏  举报