linux 高并发socket通信模型
------select
1 一个误区很多人认为它最大可以监听1024个,实际上却是文件描述符的值不能大于等于1024,所以除掉标准输入、输出、错误输出,一定少于1024个,如果在之前还打开了其他文件,那会更少
2 select返回后,一般要轮询fd_set,发现新连接要加上,连接断开要去掉,这个过程一定要这样做:select之前把fd_set临时拷贝一份,轮询中对它的修改只在临时fd_set上做,轮询完了,再对这个临时fd_set select,否则你可能明明有连接进来,却accept不到,这可能是因为轮询中如果直接修改fdset,select的底层就会定位错乱
------poll
性能测试发现,select与poll有相似的调用时间与cpu占用率,都随着数据量变大或者连接数变大(活动连接不变)而变大
连接进入时,返回POLLIN,连接关闭时返回POLLERR 或者 POLLIN
------epoll
正如传说的那样,epoll的调用时间与cpu占用率只会随数据量变大,而几乎不受连接数影响
当连接关闭时,会收到EPOLLIN事件
在ET模式下,不管是监听socket还是连接客户端的socket,在EPOLLIN时,都应该重复read一直到EAGAIN(多次连接进入或者客户端的多次send调用都只产生一次EPOLL事件),否则下次等待EPOLLIN将会挂起,这样对上层应用处理起来更复杂
所以还是推荐用默认的LT模式
在对客户端的发送也可能出现阻塞,所以epoll也应该注册EPOLLOUT,但不是在一开始(那会让所有文件描述符都返回可用,降低epoll的效率,合理的机制应该是这样:对accecpt的客户端连接一开始只注册EPOLLIN事件,触发后接收客户端消息,生成回复,将回复放到一个程序自己的缓冲区内,修改该文件描述符的注册事件为EPOLLIN|EPOLLOUT(视业务逻辑而定,如果要求必须应答发送之前不能接收请求,可只注册EPOLLOUT事件),当EPOLLOUT触发时,将回复发送出去,从缓冲区中删除回复,再修改该连接为注册EPOLLIN事件
即使在单线程程序中(运行在家用笔记本的虚拟机上),在3万个连接的1万个活动连接上,epoll也可以一秒内收发100MB数据(已经接近于Gbit网卡的理论上限),所以如果没有其它的IO活动或者计算处理,单线程的epoll完全可以应付高并发socket通信
如果连接爆发,比如一秒1万个,epoll server会在10+秒内accept完,没必要担心它accept过慢,因为当监听队列不足时,tcp会忽略客户端的SYN报文,这样客户端就会重传,只要给客户端设置一个合适的超时时间,例如15妙,epoll server处理每秒10000个新加连接没有问题
-----一般处理模型
生产者消费者模式,一个线程单独负责从监听socket上accept,它收到新连接后,加锁放入公共buffer,若干个工作线程加锁从公共buffer上取得连接,加入自己的epoll等待集中,等待一定的时间,有数据则进行收发,没数据继续从公共buffer上取连接,但是这里并不适用在线程间用条件变量通知,因为即使公共buffer上没有新连接,工作线程也不应该等待accept线程通知,而是应立即用epoll wait自己已有的连接
不能采用多个线程自主抢占连接的方式,数据在不同连接上是不均匀的,如果一些连接现在数据量现在过大,就会得到很少的新连接,以后又会出现数据饥饿,而那些当时抢占到过多连接的线程以后则会压力过大,处理变慢。应该由单独线程,例如负责accept的线程,分配到每个线程自己的连接队列中等待处理,另外,每个处理线程都采用LT模式,每个活动连接上轮流接收一次消息,然后就取回队列中的新连接,如果采用ET模式,就可能一直忙于在旧连接上收发数据,而冷落新连接。
公司的网络备份软件,采用的是poll/select模型,因为客户端一旦运行备份/恢复任务,在连接就一定有数据收发任务,这种情况下,epoll不能加快性能
对于某些输入io只有一路的程序,数据接收线程 + circle buffer + 数据处理线程是一个比较简单的模型
上面的方案仍然造成数据量的线程处理不过来,数据量小的线程又很空闲,应该采用如下方案
主线程内用epoll接收数据和accept新连接,并解析出消息,放入队列中让所有的线程去抢,至于如何多个线程同时对一个连接发送消息,可以采用与dedupe中多线程处理FP cache(一个hash table)的方案类似,分配与线程数目相同的锁,当处理完消息需要发送时,将连接的文件描述符数除以线程数目,余是多少,就加锁哪个锁,这样,多个线程能尽量分配到不同的锁上增加并发性,而对同一个连接加同一个锁进行互斥的发送
另外,这还需要处理SIGPIPE消息,以免前面一个线程关闭了连接,另一个线程又去发送,产生SIGPIPE信号,使进程exit
原文:http://blog.csdn.net/piaoairy219/article/details/17398545
linux 高并发socket通信模型的更多相关文章
- Linux下高并发socket链接数测试
一.如何增大service进程的max open files ulimit -n 只能改小max open files,不能改大.需要按照以下步骤: 修改/etc/security/limits.co ...
- Linux下高并发socket最大连接数所受的各种限制(详解)
1.修改用户进程可打开文件数限制 在Linux平台上,无论编写客户端程序还是服务端程序,在进行高并发TCP连接处理时,最高的并发数量都要受到系统对用户单一进程同时可打开文件数量的限制(这是因为系统为每 ...
- Linux高并发网络编程开发——10-Linux系统编程-第10天(网络编程基础-socket)
在学习Linux高并发网络编程开发总结了笔记,并分享出来.有问题请及时联系博主:Alliswell_WP,转载请注明出处. 10-Linux系统编程-第10天(网络编程基础-socket) 在学习Li ...
- GNU Linux高并发性能优化方案
/*********************************************************** * Author : Samson * Date : 07/14/2015 * ...
- linux中高并发socket最大连接数的优化详解
linux中高并发socket最大连接数的优化详解 https://m.jb51.net/article/106546.htm?from=singlemessage
- [转载] Linux下高并发socket最大连接数所受的各种限制
原文: http://mp.weixin.qq.com/s?__biz=MzAwNjMxNjQzNA==&mid=207772333&idx=1&sn=cfc8aadb422f ...
- Linux下高并发socket最大连接数所受的各种限制
http://blog.csdn.net/guowake/article/details/6615728 1.修改用户进程可打开文件数限制 在Linux平台上,无论编写客户端程序还是服务端程序,在进行 ...
- 教你修改Linux下高并发socket最大连接数所受的各种限制
1.修改用户进程可打开文件数限制 在Linux平台上,无论编写客户端程序还是服务端程序,在进行高并发TCP连接处理时,最高的并发数量都要受到系统对用户单一进程同时可打开 文件数量的限制(这是因为系统为 ...
- Linux下高并发socket最大连接数
http://soft.chinabyte.com/os/285/12349285.shtml (转载时原文内容做个修改) 1.修改用户进程可打开文件数限制 在Linux平台上,无论编写客户端程序还是 ...
随机推荐
- ORA-12560: 解决TNS:协议适配器错误
1)安装成功,但无法连接数据库 2)网上查找原因:32位的不能运行64位的oracle,而且不会有64位的版本 3)解决办法:大致是修改客户端数据库为32位的(此方法OK) (1)解压instantc ...
- 触宝科技基于Apache Hudi的流批一体架构实践
1. 前言 当前公司的大数据实时链路如下图,数据源是MySQL数据库,然后通过Binlog Query的方式消费或者直接客户端采集到Kafka,最终通过基于Spark/Flink实现的批流一体计算引擎 ...
- 修改MySQL时区
说明: 1.Windows版本暂无发现问题 2.CentOS-Docker版本需要修改时区 通过sql命令临时修改 mysql> set global time_zone = '+8:00'; ...
- 资源:docker-compose下载路径
docker-compose下载路径: compose所有版本:https://github.com/docker/compose/releases
- mysql过滤表中重复数据,查询相同数据的特定一条
待操作的表如下: p.p1 { margin: 0; font: 16px Menlo; color: rgba(0, 0, 0, 1) } span.s1 { font-variant-ligatu ...
- php-18个魔法函数
目录 php魔法函数 介绍 范例 1.__construct() 2.__destruct() 3.__call() 4.__callStatic 5.__get() 6.__set() 7.__is ...
- ICMP、ARP协议介绍和ping命令
交换机工作原理和常用的简单命令 一.ICMP协议 1)ICMP协议的封装 二.ARP协议 1)什么是ARP协议 2)ARP相关命令 三.Ping命令的使 ...
- PYTHON matplotlib入门
'''作为线性图的替代,可以通过向 plot() 函数添加格式字符串来显示离散值. 可以使用以下格式化字符. 字符 描述 '-' 实线样式 '--' 短横线样式 '-.' 点划线样式 ':' 虚线样式 ...
- Hive——简介
Hive--简介 Hive 是基于 Hadoop 构建的一套数据仓库分析系统,它提供了丰富的 SQL 查询方式来分析存储在 Hadoop 分布式文件系统中的数据, 可以将结构化的数据文件映射为一张数据 ...
- PO封装设计模式 -- App移动端测试
前言: 一.App_Po 封装 (用互联网上随便一个app进行) base 存放的是页面基础类,后续的类需继承基础类 common 存放的是公共部分,测试固件分离部分,新增截图功能部分 Data 存放 ...