C10K问题—高并发网络IO模型

本文探讨了C10K问题,即如何在单机上服务10000个并发用户。主要从操作系统层面的文件句柄、系统内存和网络带宽三个方面分析,并提出了多种解决方案,包括阻塞I/O+进程/线程、非阻塞I/O+readiness notification+单线程/多线程以及异步I/O+多线程。重点介绍了epoll在Linux中的作用,它是解决C10K问题的关键。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C10K 问题

随着互联网的蓬勃发展,一个非常重要的问题摆在计算机工业界面前。这个问题就是如何使用最低的成本满足高性能和高并发的需求。这个问题在过去可能不是一个严重的问题,但是在 2000 年前后,互联网用户的人数井喷,如果说之前单机服务的用户数量还保持在一个比较低的水平,比如说只有上百个用户,那么在互联网逐渐普及的情况下,服务于成千上万个用户就将是非常普遍的情形,在这种情形下,如果还按照之前单机的玩法,成本就将超过人们想象,只有超级有钱的大玩家才可以继续下去。

于是,C10K 问题应运而生。C10K 问题是这样的:如何在一台物理机上同时服务 10000 个用户?这里 C 表示并发,10K 等于 10000。得益于操作系统、编程语言的发展,在现在的条件下,普通用户使用 Java Netty、Libevent 等框架或库就可以轻轻松松写出支持并发超过 10000 的服务器端程序,甚至于经过优化之后可以达到十万,乃至百万的并发,但在二十年前,突破 C10K 问题可费了不少的心思,是一个了不起的突破。

操作系统层面

C10K 问题本质上是一个操作系统问题,要在一台主机上同时支持 1 万个连接需要考虑以下方面:

文件句柄

首先我们知道每个客户连接都代表一个文件描述符,一旦文件描述符不够用了,新的连接就会被放弃,产生如下的错误:

Socket/File:Can't open so many files

在 Linux 下,单个进程打开的文件句柄数是有限制的,没有经过修改的值一般都是 1024。

$ulimit -n
1024

这意味着最多可以服务的连接数上限只能是 1024。不过,我们可以对这个值进行修改,比如用 root 权限修改 /etc/sysctl.conf 文件,使得系统可用支持 10000 个描述符上限。

fs.file-max = 10000
net.ipv4.ip_conntrack_max = 10000
net.ipv4.netfilter.ip_conntrack_max = 10000

系统内存

每个 TCP 连接占用的资源可不止一个连接套接字这么简单,在前面的章节中,我们多少接触到了类似发送缓冲区、接收缓冲区这些概念。每个 TCP 连接都需要占用一定的发送缓冲区和接收缓冲区。

下面一段 shell 代码,分别显示了在 Linux 4.4.0 下发送缓冲区和接收缓冲区的值。

$cat   /proc/sys/net/ipv4/tcp_wmem
4096	16384	4194304
$ cat   /proc/sys/net/ipv4/tcp_rmem
4096	87380	6291456
</
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值