老师,我开了大概100个线程
来源:8-3 线程池-3
伟少_will
2018-08-18
//这里会循环180次 for (Date date : concurrentSet) { //每天一个线程处理 executorService.execute(() -> { //一些查询操作 xxxService.select(); //还有一些添加操作 xxxService.batchInsert(); }
老师,我的代码大概长的跟上面那样子,抛开业务处理,大概就是每天执行预先生成未来180天的数据,想您给点意见
由于环境问题(测试环境在外网)和带宽问题(每人限制只有1M带宽)会发生很多超时错误,导致我本地测试起来很不方便,但是又暂时没法在测试环境测试
所以想你给点意见,这段代码大体上结构有问题吗
2回答
-
你好,说一下我的想法,100个线程有点多,而且是对数据库的操作,感觉这个线程数目可能已经超过了你数据库连接池配置的连接数目了,这直接会带来这么多线程,即使是同步执行,也很多会阻塞在数据库连接那里,并出现或许数据库连接失败的异常。这是第一个问题。
第二个问题,数据库资源通常是项目里最紧缺的,这里过分消耗,可能会导致那个时间点其他功能受影响。数据库连接是一方面,即使能拿到连接,同时进行大量的操作,数据库的压力也会突然变大。如果数据库要做主从同步,还可能造成同步的延迟。
第三个问题,不知道你目前这样操作,一次select() 和 batchInsert() 数据量有多大,如果很大的话,1M的带宽可能直接打满,导致项目无法对外提供功能。而如果很小的话,线程数少一些,也会做的特别快。
第四个问题,你也提到了1M的带宽,这个限制确实不适合过多线程同时执行。说到这里,你可以在本地启动10个线程、20个线程、30个线程去做些测试,对比一下10到20、20到30这个过程中内存、CPU等的变化。你基本上可以大致评估达到100个线程的影响。
回到标准做法,当我不知道一个新环境我可以用多少个线程,而又想尽可能快的完成时,我也会选择从10开始,每次10个递增去尝试,看应用的表现,这样相对安全很多。你可以会认为每次调整都要发布重新部署,我们通常会预置一个开关代替线程数,然后每次测试时只需要动态的去修正这个开关配置的数值就可以了,不断的调整到最佳。这个验证过程中,也要考虑应用高峰和低峰的时间段,和本身启动多线程处理时间段的对比。
对于任何一个应用,可以启动多少个线程都是不一样的,在寻找最佳线程数的时候,需要优先保证应用的“安全”,但一定不要一开始就给一个特别大的线程数,这样不但可能完成不了,反而可能直接让项目出现各种问题。
112019-07-16 -
伟少_will
提问者
2018-08-18
我每一个字都认真看,非常感谢老师的建议
00
相似问题