Indy TIdHTTPWebBrokerBridge线程持续增长无法释放问题求助
线程持续增长的可能原因及解决方向
1. 未设置合理的读取超时时间
Indy的TIdCustomHTTPServer继承自TIdTCPServer,其ReadTimeout属性决定线程等待客户端请求数据的超时时间。如果该值设为0(无限等待),当客户端未主动关闭连接且无后续请求时,线程会永久阻塞等待,不会自动释放。
解决:
将ReadTimeout设为合理值(如30000毫秒,即30秒),与KeepAliveTimeout保持一致,确保空闲连接超时后线程能正常终止。
2. KeepAlive配置问题
虽然启用KeepAlive能减少SSL握手开销,但如果KeepAliveTimeout设置过长,线程会在空闲连接上停留更久。更关键的是,若ReadTimeout未正确设置,KeepAliveTimeout的超时逻辑可能无法生效。
解决:
- 确认
KeepAliveTimeout设置为适合业务的时长(如30秒)。 - 确保
ReadTimeout不大于KeepAliveTimeout,保证空闲连接能被及时清理。
3. 未处理请求过程中的异常
你的DoCommandGet代码中,DispatchAction调用仅包裹了try-finally但无except块。若请求处理过程中抛出未捕获异常,可能导致连接状态异常,线程无法正确判断连接是否已失效,进而持续等待后续请求。
优化代码:
添加异常处理逻辑,确保异常发生时能发送错误响应并主动断开连接:
procedure TIdHTTPWebBrokerBridge.DoCommandGet(AThread: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo); var LRequest: TIdHTTPAppRequest; LResponse: TIdHTTPAppResponse; begin LRequest := TIdHTTPAppRequest.Create(AThread, ARequestInfo, AResponseInfo); try LResponse := TIdHTTPAppResponse.Create(AThread, LRequest, ARequestInfo, AResponseInfo); try AResponseInfo.FreeContentStream := False; try if TWebDispatcherAccess(FWebModule).DispatchAction(LRequest, LResponse) then begin if not LResponse.Sent then begin LResponse.SendResponse; end; end; except on E: Exception do begin // 记录异常日志 // 确保错误响应已发送 if not LResponse.Sent then begin LResponse.ResponseNo := 500; LResponse.ContentText := 'Internal Server Error'; LResponse.SendResponse; end; // 主动断开连接,避免线程阻塞 AThread.Connection.Disconnect; end; end; finally FreeAndNil(LResponse); end; finally FreeAndNil(LRequest); end; end;
4. 客户端未正确关闭连接
部分客户端可能未发送Connection: close头,或异常断开后未释放连接,导致服务器线程持续等待后续请求。
验证:
使用netstat等工具查看服务器上的空闲连接数量,若存在大量未关闭的ESTABLISHED状态连接,即可确认此问题。结合超时配置可自动清理这类连接。
5. Indy线程缓存或版本问题
- 检查
ThreadCacheSize属性:若该值设置过大,Indy会缓存大量线程供复用,导致线程数居高不下(默认值为10,一般不会有问题)。 - 确认Indy v10.6.3.3是否存在已知的线程泄漏Bug,可尝试查看官方更新日志或社区反馈。
内容的提问来源于stack exchange,提问作者clj
相关产品推荐
相关产品推荐

