文章链接:https://codemouse.online/archives/2020-06-26-17-51-36
网络五元组
五元组标识一个网络fd的唯一
网络fd --> 五元组(sip,dip,sport,dport,proto)
c1000k服务器的并发量条件(百万并发)
- 服务器能够承载的客户端数量。(最基本条件)
- 5w以上的应供应操作。(也就是客户端的5%)
- 对数据库的操作。
- 磁盘的操作。(日志,文件。。)
- CPU占用率60%。(留下40%用来应付突发情况)
- 内存占用率80%。
系统限制并发的地方
- open_files 的值,这个值代表了一个进程可以打开的文件的数量。当然这个值不能超过file-max,超出file-max的部分是无效的。
# 方法一:重启后无效
ulimit -HSn 102400
# 方法二:重启后依旧生效
# 将方法一内容写到/etc/profile中,因为每次登录终端时,都会自动行/etc/profile
# 方法三:重启后生效
vim /etc/security/limits.conf
* soft nofile 65535
* hard nofile 65535
- fs.file-max的值,这个值代表了所有进程一共可以打开的文件数量。一些程序可以通过setrlimit调用,设置每个进程的限制。这项参数是系统级别的。
# 方法一:重启后无效
echo 1048576 > /proc/sys/fs/file-max
# 方法二:重启后无效
sysctl -w "fs.file-max=1048576"
# 方法三:重启后生效
vim /etc/sysctl.conf
fs.file-max = 6553560
ulimit命令
-H 使用硬资源控制
-S 使用软资源控制
-a 查看所有的当前限制
-n 能打开的最大文件描述符数
-t 限制最大的 CPU 占用时间(每秒)
-u 限制最大用户进程数
-v 限制虚拟内存大小(kB)
例子:
#硬资源和软资源同时限制为最大打开文件描述符数65546
ulimit -HSn 65536
#将虚拟内存限制改为无限制
ulimit -v ulimited
reactor的核心
- reactor将网络IO转化为了事件。
因为每一个网络IO在某一时刻只有一个事件,所以网络IO等同于了事件。
客户端发起连接只能发起6w多个连接的原因
执行sudo sysctl -p 查看
看net.nf_conntrack_max的值,这个值默认65535,限制了发起数量
系统默认不加载的,需要加载一下,因为客户端发起超大量请求才会出现这个问题。
# 开启:
sudo modprobe ip_conntrack
# 方法一:重启后无效
echo 1048576 > /proc/sys/net/nf_conntrack_max
# 方法二:重启后无效
sysctl -w "net.nf_conntrack_max=1048576"
# 方法三:重启后生效
vim /etc/sysctl.conf
net.nf_conntrack_max = 6553560
单个客户端可发起连接数已经修改,还是连上不去的原因
报错:cannot assign requested address
解决方式:
- 如果单个客户机子往服务器发送超过最大端口个链接,只能让服务器多开端口,否则无解,因为他需要五元组进行fd标识。
- 由于源ip和目的ip固定,源端口最大数量也固定,那么能改变的也只有目的端口了,所以服务器多开端口可以解决同一个机子发起大量链接的问题。
- 网络五元组(sip,dip,sport,dport,proto)
如何把客户端链接的耗时变短???
限制原因:服务器的accept的限制,一个accept可处理的事件太少太慢。
解决办法:增加accept。
多个accept如何配合多个线程或者进程
配合方式:
- 多个accept放在一个线程。(无法解决问题)
- 多个accept分配在不同的线程。
- 多个accept分配在不同的进程(nginx的做法)
多线程与多进程的区别???
- 多进程不需要加锁。
- fd的上限比多线程多。(参考fs.file-max的定义)
在c10k的时候,当时无法突破到c100K的限制在哪??
当时没有epoll这种获取监听事件机制,用的是select/poll等轮询机制
为什么select/poll等机制慢?
select每次去监听等待的时候,需要把用户的fd集合复制到内核中,并且是以遍历的方式带出来给应用程序。
为什么epoll快??
这个方式不在需要每次都将用户的fd集合复制一份到内核,而是将要用到的IO通过epoll_ctl的方式加入到内核里面,内核里面有一颗红黑树存储这些IO,一旦某个结点活跃有数据,就将结点通过链表的方式连接成一个队列(注意:加入队列但并没有移出红黑树)。而epoll_wait所做的事情,就说将就绪队列从内核中复制出来。此时就只需要复制有数据的结点,且不需要拷贝大量数据到内核,所以快。
想从C1000K提升到C10M要怎么办??
在数据到应用程序的过程中,要经过网卡->协议栈->应用。这时候可以选择将协议栈放弃,直接应用与网卡进行交互,减少了协议栈这一层,提升速度。
用mmap将网卡映射到内存中,应用与网卡交互,也就是所谓的用户协议栈的方式。
影响服务器的性能的五元组
- CPU
- 内存
- 网络带宽
- 操作系统
- 应用程序