在编写高并发的tcp连接应用时,必须使用
1、合适的网络I/O技术
2、合适的网络I/O事件分派机制
可用的io技术有:
I/O技术有同步I/O
非阻塞式同步I/O(也称反应式I/O)
异步I/O。
非阻塞式同步I/O的技术包括:select(),poll(),epoll等机制
异步I/O的技术:就是使用AIO
事件分派机制:
从I/O事件分派机制来看,使用select()是不合适的,因为它所支持的并发连接数有限(通常在1024个以内)
如果考虑性能,poll()也是不合适的,尽管它可以支持的较高的TCP并发数,但是由于其采用“轮询”机制,当并发数较高时,其运行效率相当低,并可能存在I/O事件分派不均,导致部分TCP连接上的I/O出现“饥饿”现象
而如果使用epoll或AIO,则没有上述问题(早期Linux内核的AIO技术实现是通过在内核中为每个 I/O请求创建一个线程来实现的,这种实现机制在高并发TCP连接的情形下使用其实也有严重的性能问题。但在最新的Linux内核中,AIO的实现已经得到改进)。
综上所述,在开发支持高并发TCP连接的Linux应用程序时,应尽量使用epoll或AIO技术来实现并发的TCP连接上的I/O控制,这将为提升程序对高并发TCP连接的支持提供有效的I/O保证。
推荐配置(把原/etc/sysctl.conf内容清掉,把下面内容复制进去):
net.ipv4.ip_local_port_range = 1024 65536 #默认:32768到61000 net.core.rmem_max=16777216 net.core.wmem_max=16777216 net.ipv4.tcp_rmem=4096 87380 16777216 net.ipv4.tcp_wmem=4096 65536 16777216 net.ipv4.tcp_fin_timeout = 10 net.ipv4.tcp_tw_recycle = 1 net.ipv4.tcp_timestamps = 0 net.ipv4.tcp_window_scaling = 0 net.ipv4.tcp_sack = 0 net.core.netdev_max_backlog = 30000 net.ipv4.tcp_no_metrics_save=1 net.core.somaxconn = 262144 net.ipv4.tcp_syncookies = 0 net.ipv4.tcp_max_orphans = 262144 net.ipv4.tcp_max_syn_backlog = 262144 net.ipv4.tcp_synack_retries = 2 net.ipv4.tcp_syn_retries = 2
参数讲解
net.ipv4.tcp_syncookies = 1 #开启SYN cookies。当SYN溢出时,启用cookies处理,可防范少量SYN共计。默认是:0 net.ipv4.tcp_tw_reuse = 1 #开启重用。允许time-await的建立新的tcp连接。默认是:0 net.ipv4.tcp_tw_recycle = 1 #开启快速回收。time-waint socket的快速回收。默认是:0 net.ipv4.tcp_fin_timeout = 30 #timeout时间 net.ipv4.tcp_tw_buckets = 5000 #
#表示系统同时保持TIME_WAIT套接字的最大数量,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息。
默认为180000,改为5000。对于Apache、Nginx等服务器,上几行的参数可以很好地减少TIME_WAIT套接字数量,但是对于 Squid,效果却不大。此项参数可以控制TIME_WAIT套接字的最大数量,避免Squid服务器被大量的TIME_WAIT套接字拖死。
(抄的哈哈)
压测
# netstat -n | awk '/^tcp/ {++y[$NF]} END {for(w in y) print w, y[w]}'
查看设置
sysctl -a