来源:《Go 夜读》微信群
时间:2018-07-02
- 问题来源:
HundredLee 在微信群里分享了一个掘金网的文章 GO千万级消息推送服务,然后另一个大佬 bye 说 goim 是哔哩哔哩在用的一个框架,可以支撑百万级并发连接,于是在“单机百万并发”这个问题上展开了热烈的讨论。
问题:我以前对并发的理解几乎都是错的,误以为每有一个客户端连接到服务器上就会多占用服务器的一个新TCP端口,但是看了文章和其他的QQ群的讨论,我终于搞明白了并发的概念。那么我的疑惑是单机如何才能支撑起100万的并发量呢?
Linux服务器的并发连接数需要优化内核参数,在使用比较新的内核版本时,会有更好的优化效果。并发连接数主要和操作系统允许打开的文件描述符数量有关,需要设置 fs.file-max
和 fs.nr_open
参数,fs.file-max
参数设置的是整个操作系统允许创建的文件描述符数量的最大值,fs.nr_open
参数设置的是每个进程各自最多可以打开的文件描述符数量,这两个值限制 pam_limits.so 模块定义 的可打开文件描述符数量的参数上限。pam_limits.so
模块在定义了可打开的文件描述符数量的同时也就规定了 socket
的最大数量。所以服务能否支撑百万连接数首先取决于内核参数,然后取决于 pam_limits.so
模块的限制,pam_limits.so 模块决定了每个用户和组可用的资源。
另外还要对每一个TCP套接字连接占用的内存做分析,大概占4KByte;维护百万连接需要占用的内存就是 1000000 * 4KByte,大约是4GByte,还没有计算进去发送消息的开销,保守估算需要的内存是16GByte,如果要推送消息给这100万客户端,很显然非常吃力,反过来如果是100万的客户端排队发请求,就可以轮询处理队列里的请求了。