前言
之前接手了一个调度程序,业务是读取文件中信息,通过请求业务接口获取数据,记录并整理数据到文件,输出给客户。做过一次优化开发后,发现有时候程序执行时会报 Connection refused 异常,虽然比例不大,但是很恼人,现在记录下解决问题的整个过程。
问题描述
描述一下调度程序的大致架构。为了提高执行速度,程序使用多线程的方式同时请求接口获取数据。使用固定大小为200的线程池,通过控制加入到线程池中任务的间隔时间10ms,来间接实现期望tps为100。在跑10w的量时,有十几笔连接不上。
问题分析
从客户端,网络,服务端三方分析。
1.客户端
是不是客户端资源不够,导致连接拒绝。连接拒绝的含义应该是客户端尝试向服务器端建立连接,但是被拒绝。应该不是客户端问题。
2.网络
是否是当时网络问题,导致拒绝连接。好像有可能。但是仔细分析下,这样的情况基本上都会发送,异常率是万分之几。如果是网络问题,出现异常的概率不应该这么稳定,再说公司里都是内网,延迟极低。
3.服务端
是否服务端负载比较大,达到了最大处理上限,没有多余的资源处理新的请求。客户端线程池的大小固定是200,最坏情况下有200个工作线程同时请求接口。服务器配置的资源是否能满足这样需求?服务器配置的响应请求的资源池是最小100,最大200。服务器可以同时处理200个请求。
我陷入了沉思:是不是有其他的业务也会同时访问接口,导致最大的并发超过200。回想起还真有一个业务,和这个业务并行的,都会访问接口。这个业务设置的线程池大小为100。也就是说,最坏的情况下,有两个业务发起300个请求同时访问接口服务器端,而服务器端同时处理的最大能力为200,导致服务端程序无法处理新请求,导致请求积累在tcp端,当tcp端积累到了一定的量,它就选择放弃某些请求。
解决方案
修改服务端的处理请求的线程池大小为300。
后续
我们又发起了好几个大批量的请求,均未发现 拒绝连接异常。
收获
站在别人的角度考虑问题 生活和工作都是相同的。不能你自己爽了就ok,还要让别人一起爽。使用多线程解决问题时,要考虑到实际程序的处理能力。他好,我也好。哈哈