connectex: Only one usage of each socket address (protocol/network address/port) is normally permitt

处理一个大文本数据,读取到内存,用多线程并发执行,存入数据库。经多次调试,在程序运行一段时间后间歇性报错——

connectex: Only one usage of each socket address (protocol/network address/port) is normally permitt

并发量也从10000逐步减少到80,chan的容量也从10000000减少到300,同时打开任务管理器,观察,当协程开到10000或者80,并没有多大的区别,使用率都是100%。这是个人电脑,i7-8。所以对于这样的配置,并发开的很大也没有太多的意义,CPU的处理速度是相对稳定的区间,已经使用100%了,开10000个相互等待,和80个相互等待没什么区别,反而我测试,并发开10000时,每秒存入数据库数据的条数保持在2000左右,而开80,每秒可达9000多!效率4倍!同时对内存进行检测,原来内存开的很大,内存使用率也100%,这时候就会报错了!CPU使用率100%是不会出问题的,我连续跑了2个多小时满载都没问题,内存不行,这个是要控制的,我开始测试写入内存的速度,从休眠0.1秒、0.01秒,1纳秒,0.001纳秒……到最后0.1纳秒。这其实就像一个水池,开启一个协程不停的读取大数据文本,把整理的数据流向水池,然后开辟N协程抽取水池里面被整理的数据,当这N多协程的抽水速度低于防水速度时!这时候就会报Only one usage of each socket address (protocol/network address/port) is normally permitt。

这之前我也看过csdn网友的文章,修改注册表的tcp的MaxFreeTcbs最大链接数,可以规避这种错误,但是我觉的CPU已经满载了,把池子扩大到最大确实可以,达到有足够的空间来容纳大数据文本,但是网友的文中也讲了:
系统为每个TCP 连接分配一个TCP 控制块(TCP control block or TCB),这个控制块用于缓存TCP连接的一些参数(源端口、目的端口、目的ip、序号、应答序号、对方窗口大小、己方窗口大小、tcp状态、tcp输入/输出队列、应用层输出队列、tcp的重传有关变量等),每个TCB需要分配 0.5 KB的pagepool 和 0.5KB 的Non-pagepool,也就说,每个TCP连接会占用 1KB 的系统内存。

我觉得一味的扩建池子和增加抽水管,并不可取,CPU已经百分百了,这N多协程相互等待着CPU来调度也没有太大的意义,倒不如控制好流入和流出,保证池子里一直有水,但又保证谁不会溢出池子就好。

【个人测试,以后测试再补充,留下我的思考】
 

猜你喜欢

转载自blog.csdn.net/ckx178/article/details/88737658
今日推荐