Delphi XE4 Indy TCP服务高并发线程过载 求介于Indy与ICS间的可行方案
可行解决方案
方案1:优化现有Indy架构
- 替换调度组件:将当前使用的
TSchedulerOfThread替换为TIdSchedulerOfThreadPool,可独立配置最大工作线程数为800~1000,超出的连接会进入待调度队列,不会每个连接独占一个线程,符合线程数限制要求。 - 调整调度参数:取消线程实时优先级配置(实时优先级会抢占系统内核调度资源,触发Windows线程调度阈值导致集体阻塞,之前遇到的10秒无响应多为该原因),将工作线程优先级设为
tpHigher,TIdTCPServer的ListenQueue参数调整至500以上,ReadTimeout设为10000,避免空闲连接长期占用线程资源。 - 业务逻辑解耦:不要在Indy连接线程内执行耗时业务处理,收到消息后推入无锁队列,单独启动10~20个工作线程消费队列处理业务,主动推送逻辑也单独开线程批量执行,进一步降低连接线程的占用时长。
方案2:基于Windows IOCP完成端口实现通信层
- 直接调用Windows原生IOCP API或集成成熟的Delphi IOCP封装实现通信层,IOCP为高并发长连接场景设计,默认工作线程数仅为CPU核心数*2,即使承载上万连接线程数也不会超过100,远低于线程数限制要求。
- IOCP无ICS的消息机制依赖,不会出现高并发下消息队列溢出、跨线程消息同步错误的问题,可完全规避ICS运行数小时随机崩溃的问题。
- 集成成本低,仅需实现接收回调、连接断开回调、发送完成回调三个核心接口,上层业务处理逻辑可完全复用。
方案3:修复现有ICS架构问题
- 跨线程操作ICS组件时必须投递到ICS所在的消息线程执行,禁止在业务工作线程直接操作ICS连接对象,可规避90%以上的无栈崩溃问题。
- 程序启动时调用
SetMessageQueueAPI将Windows消息队列长度调整至10000以上,配合ChangeWindowMessageFilterEx放开消息过滤限制,避免高并发下消息丢失触发空指针访问。
内容的提问来源于stack exchange,提问作者Dusan
相关产品推荐
相关产品推荐

