epoll

Linux(服务器编程):44---TCP长连接、短连接(心跳检测)

折月煮酒 提交于 2020-08-04 14:19:14
一、TCP连接的相关说明 ①使用TCP协议时,会在客户端和服务器之间建立一条虚拟的信道,这条虚拟信道就是指连接,而建议这条连接需要3次握手,拆毁这条连接需要4次挥手, 可见,我们建立这条连接是有成本的,这个成本就是效率成本,简单点说就是时间成 本 ,你要想发送一段数据,必须先3次握手(来往3个包),然后才能发送数据,发送完了,你需要4次挥手(来往4个包) 来断开这个连接 ②CPU资源成本, 三次握手和4次挥手和发送数据都是从网卡里发送出去和接收的,还有其余的设备,比如防火墙, 路由器等等,站在操作系统内核的角度来讲,如果我们是一个高并发系统的话,如果大量的数据包都经历过这么一个过 程,那是很耗CPU的。 ③每个socket是需要耗费系统缓存的, 比如系统提供了一些接口设置socket缓存的,比如: /proc/sys/net/ipv4/tcp_rmem /proc/sys/net/ipv4/tcp_wmem /proc/sys/net/ipv4/tcp_mem 因为TCP的可靠传输,所以我们有大量的应用程序使用TCP协议作为通信,但是每个应用因为产品功能的原因,对TCP的使用是不一样的,比如即时聊天系统(微信,钉钉,探探) 二、TCP长连接、TCP短连接 TCP短连接 概念: 如下图所示,客户端与服务器建立连接开始通信,一次/指定次数通信结束之后就断开本次TCP连接

你真的懂Linux内核中的阻塞和异步通知机制吗?(花了五天整理,墙裂推荐!)

早过忘川 提交于 2020-07-29 07:48:09
工科生一枚,热衷于底层技术开发,有强烈的好奇心,感兴趣内容包括单片机,嵌入式Linux,Uboot等,欢迎学习交流! 爱好跑步,打篮球,睡觉。 欢迎加我QQ1500836631(备注CSDN),一起学习交流问题,分享各种学习资料,电子书籍,学习视频等。 文章目录 阻塞/非阻塞简介 阻塞/非阻塞例程 等待队列简介 等待队列相关函数 定义等待队列 初始化等待队列头 定义并初始化一个等待队列项 将队列项添加到等待队列头 将队列项从等待队列头移除 等待唤醒 等待事件 轮询 select poll epoll 异步通知概念 Linux信号 异步通知代码 驱动中的信号处理 fasync_struct结构体 fasync函数 kill fasync函数 应用程序对异步通知的处理 阻塞/非阻塞简介   阻塞操作是指在执行设备操作时,若不能获得资源,则 挂起进程 直到满足可操作的条件后再进行操作。被挂起的进程进入 睡眠状态 ,被从调度器的运行队列移走, 直到等待的条件被满足 。而非阻塞操作的进程在不能进行设备操作时, 并不挂起,它要么放弃,要么不停地查询 ,直至可以进行操作为止。 阻塞/非阻塞例程   阻塞方式 int fd ; int data = 0 ; fd = open ( "/dev/xxx_dev" , O_RDWR ) ; /* 阻塞方式打开 */ ret = read ( fd ,

Redis 6.0 多线程重磅发布!!!

时间秒杀一切 提交于 2020-07-29 06:01:47
Redis 6.0在5.2号这个美好的日子里悄无声息的发布了,这次发布在IT圈犹如一颗惊雷一般,因为这是redis最大的一次改版,首次加入了 多线程 。 作者Antirez在RC1版本发布时在他的博客写下: the most “enterprise” Redis version to date // 最”企业级”的 the largest release of Redis ever as far as I can tell // 最大的 the one where the biggest amount of people participated // 参与人数最多的 这次改变,性能有个飞速的提升~ 先po出新版和旧版性能图 从上面可以看到 GET/SET 命令在 4 线程 IO 时性能相比单线程是几乎是翻倍了。另外,这些数据只是为了简单验证多线程 IO 是否真正带来性能优化,并没有针对严谨的延时控制和不同并发的场景进行压测。数据仅供验证参考而不能作为线上指标,且只是目前的 unstble分支的性能,不排除后续发布的正式版本的性能会更好。 Redis 6.0 之前的版本真的是单线程吗? Redis基于Reactor模式开发了网络事件处理器,这个处理器被称为文件事件处理器。它的组成结构为4部分:多个套接字、IO多路复用程序、文件事件分派器、事件处理器。

一个工业级、跨平台、轻量级的 tcp 网络服务框架:gevent

时光毁灭记忆、已成空白 提交于 2020-07-29 04:58:54
作为公司的公共产品,经常有这样的需求:就是新建一个本地服务,产品线作为客户端通过 tcp 接入本地服务,来获取想要的业务能力。 与印象中动辄处理成千上万连接的 tcp 网络服务不同,这个本地服务是跑在客户机器上的,Win32 上作为开机自启动的 windows 服务运行; Linux 上作为 daemon 在后台运行。总的说来就是用于接收几个产品进程的连接,因此轻量化是其最重要的要求,在这个基础上要能兼顾跨平台就可以了。 其实主要就是 windows,再兼顾一点儿 linux。 考察了几个现有的开源网络框架,从 ACE 、boost::asio 到 libevent,都有不尽于人意的地方: a) ACE:太重,只是想要一个网络框架,结果它扒拉扒拉一堆全提供了,不用还不行; b) boost::asio:太复杂,牵扯到 boost 库,并且引入了一堆 c++ 模板,需要高版本 c++ 编译器支持; c) libevent:这个看着不错,当时确实用这个做底层封装了一版,结果发版后发现一个比较致命的问题,导致在防火墙设置比较严格的机器上初始化失败,这个后面我会详细提到。 其它的就更不用说了,之前也粗略看过陈硕的 muddo,总的感觉吧,它是基于其它开源框架不足地方改进的一个库,有相当可取的地方,但是这个改进的方向也主要是解决更大并发、更多连接,不是我的痛点,所以没有继续深入研究。 好了

Nginx均衡TCP协议服务器案例

╄→гoц情女王★ 提交于 2020-07-29 00:53:20
nginx在1.9版本之后可以充当端口转发的作用,即:访问该服务器的指定端口,nginx就可以充当端口转发的作用将流量导向另一个服务器,同时获取目标服务器的返回数据并返回给请求者。 nginx的TCP代理功能跟nginx的反向代理不同的是:请求该端口的所有流量都会转发到目标服务器,而在反向代理中可以细化哪些请求分发给哪些服务器;另一个不同的是,nginx做TCP代理并不仅仅局限于WEB的URL请求,还可以转发如memcached、MySQL等点到点的请求 实现步骤如下: (1)nginx在编译时添加“–with-stream”: ./configure –prefix=/usr/local/nginx –user=www –group=www –with-http_stub_status_module –with-pcre=/usr/local/src/pcre-8.38 –add-module=/usr/local/src/ngx_cache_purge-2.3 –with-http_gzip_static_module –with-stream 其中 /usr/local/src/ngx_cache_purge-2.3 是下载 ngx_cache_purge-2.3 解压后的目录 /usr/local/src/pcre-8.38 是下载 pcre-8.38 解压后的目录 (2

常用高并发网络线程模型设计及mongodb线程模型优化实践(最全高并发网络IO线程模型设计及优化)

对着背影说爱祢 提交于 2020-07-28 17:24:47
常用高并发网络线程模型设计及mongodb线程 模型优化实践(最全高并发网络IO线程模型设计) 1. 线程模型一. 单线程网络IO复用模型 1.1 说明: 1. 所有网络IO事件(accept事件、读事件、写事件)注册到epoll事件集 2. 主循环中通过epoll_wait一次性获取内核态收集到的epoll事件信息,然后轮询执行各个事件对应的回调。 3. 事件注册、epoll_wait事件获取、事件回调执行全部由一个线程执行 1.2 该网络线程模型缺陷 1. 所有工作都由一个线程执行,只要任一一个请求的事件回调处理阻塞,其他请求都会阻塞。例如redis的hash结构,如果filed过多,例如一个hash key包含数百万filed,则该Hash key过期的时候,整个redis阻塞。 2. 单线程工作模型,CPU会成为瓶颈,如果QPS超过10万,整个CPU负载会达到100%。 1.3 典型案例 1. redis缓存 1.4 主循环工作流程: while (1) { //epoll_wait等待网络事件,如果有网络事件则返回,或者超时范围 size_t numevents= epoll_wait(); //遍历前面epoll获取到的网络事件,执行对应事件回调 for (j = 0; j < numevents; j++) { if(读事件) //读事件处理、读到数据后的业务逻辑处理

Nginx和Tomcat调优

生来就可爱ヽ(ⅴ<●) 提交于 2020-07-28 13:28:26
一、Nginx和Tomcat定义    tomcat 是一个中间件,在B/S架构中,浏览器发出的http请求经过tomcat中间件,转发到最终的目的服务器上,响应消息再通过tomcat返回给浏览器。tomcat更多用来做一个应用容器,让java web跑在里面的东西。    nginx 常用做静态内容服务和反向代理服务器,以及页面前端高并发服务器。适合做负载均衡,直面外来请求转发给后面的应用服务(tomcat什么的)。   nginx+tomcat响应速度明显要低于直接请求tomcat,性能不如直接请求tomcat,但是nginx由于多了中间一层转发,使得请求压力不会一次性都集中在tomcat上,因此nginx+tomcat的CPU明显低于直接请求tomcat,也大大避免了因请求量过大导致tomcat服务不可用。   单点tomcat在不使用nginx的情况下,能承载的最多也就是200-300的并发量,而加上了nginx之后,能大幅度提升服务器的并发承载量,不仅仅是因为nginx可以做负载均衡(load-banlance),更重要的是nginx可以让请求进行排队,而不是将压力赋予给tomcat,这样tomcat可以更加专注地完成业务操作,从而提高性能。 二、Nginx调优   这里只说nginx的简单优化,即让nginx处理html静态文件,图片,css,js等非动态文件

Netty 传输

末鹿安然 提交于 2020-07-28 10:50:52
Netty 为每种传输的实现都暴露了相同的API,所以无论选用哪一种传输的实现,你的代码都仍然几乎不受影响。在所有的情况下,传输的实现都依赖于 interface Channel 、ChannelPipeline 和 ChannelHandler。 传输 API 的核心是 interface Channel,它被用于所有的I/O操作。 每个 Channel 都将会被分配一个 ChannelPipeline 和 ChannelConfig。ChannelConfig 包含了该 Channel 的所有配置设置,并且支持热更新。由于特定的传输可能具有独特的设置,所以它可能会实现一个 ChannelConfig 的子类型。 由于 Channel 是独一无二的,所以为了保证顺序将 Channel 声明为 java.lang.Comparable 的一个子接口。因此,如果两个不同的 Channel 实例都返回了相同的散列码,那么 AbstractChannel 中 compareTo() 方法的实现将会抛出一个 Error。 ChannelPipeline 持有所有将应用于入站和出战数据以及事件的 ChannelHandler 实例,这些 ChannelHandler 实现了应用程序用于处理状态变化以及数据处理的逻辑。 ChannelHandler 的典型用途包括:

[apue] epoll 的一些不为人所注意的特性

拜拜、爱过 提交于 2020-07-28 07:36:40
之前曾经使用 epoll 构建过一个轻量级的 tcp 服务框架: 一个工业级、跨平台、轻量级的 tcp 网络服务框架:gevent 在调试的过程中,发现一些 epoll 之前没怎么注意到的特性。 a) iocp 是完全线程安全的,即同时可以有多个线程等待在 iocp 的完成队列上;   而 epoll 不行,同时只能有一个线程执行 epoll_wait 操作,因此这里需要做一点处理,   网上有人使用 condition_variable + mutex 实现 leader-follower 线程模型,但我只用了一个 mutex 就实现了,   当有事件发生了,leader 线程在执行事件处理器之前 unlock 这个 mutex,   就可以允许等待在这个 mutex 上的其它线程中的一个进入 epoll_wait 从而担任新的 leader。   (不知道多加一个 cv 有什么用,有明白原理的提示一下哈) b) epoll 在加入、删除句柄时是可以跨线程的,而且这一操作是线程安全的。   之前一直以为 epoll 会像 select 一像,添加或删除一个句柄需要先通知 leader 从 epoll_wait 中醒来,   在重新 wait 之前通过 epoll_ctl 添加或删除对应的句柄。但是现在看完全可以在另一个线程中执行 epoll_ctl 操作   而不用担心多线程问题

select、poll、epoll之间的区别(搜狗面试)

巧了我就是萌 提交于 2020-07-28 04:06:02
(1)select==>时间复杂度O(n) 它仅仅知道了,有I/O事件发生了,却并不知道是哪那几个流(可能有一个,多个,甚至全部),我们只能无差别轮询所有流,找出能读出数据,或者写入数据的流,对他们进行操作。所以 select具有O(n)的无差别轮询复杂度 ,同时处理的流越多,无差别轮询时间就越长。 (2)poll==>时间复杂度O(n) poll本质上和select没有区别,它将用户传入的数组拷贝到内核空间,然后查询每个fd对应的设备状态, 但是它没有最大连接数的限制 ,原因是它是基于链表来存储的. (3)epoll==>时间复杂度O(1) epoll可以理解为event poll ,不同于忙轮询和无差别轮询,epoll会把哪个流发生了怎样的I/O事件通知我们。所以我们说epoll实际上是 事件驱动(每个事件关联上fd) 的,此时我们对这些流的操作都是有意义的。 (复杂度降低到了O(1)) select,poll,epoll都是IO多路复用的机制。I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。 但select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的 ,而异步I/O则无需自己负责进行读写,异步I