reactor -- 响应

reactor模式 -- 响应器模式

整体架构:

相较于epoll传统模型,reactor将整个epoll架构进行抽象,将read和write接口化,epoll整个机制封装在reactor中;简化程序编写。

具体实现就是基于epoll和回调函数的形式,从而在设置好回调函数之后,对应线程在epoll_wait返回时可以针对不同fd执行不同的注册函数操作;在此过程中还涉及到对epoll的设置的变化,设置相应的为读写状态;

同步与异步:

同步操作就是说流程A需要等待流程B完成之后再接着运行;实现就是直接等待;

异步操作就是说流程A执行过程中直接执行流程B,不需要等待流程B返回直接执行之后的流程,等到流程B完成后,流程A得到通知,执行流程A需要执行的部分;一般的措施就是回调函数。

关于epoll的ET与ET设置

这个设置可以在accept之后对套接字描述符使用fcntl对描述符直接设置,也可以在epoll_ctl的时候增加EPOLLET设置(LT是默认的,没有对应设置)。

边沿触发时当套接字缓冲区发生变化的时候就会被触发;而水平触发是只要缓冲区中有数据就会一直触发。也就是说使用边沿触发可以减少epoll_wait的触发,但是相应的处理相较于水平触发更为繁琐,需要在触发时就将socket缓冲区数据都读取完毕,好处就是整个过程中减少了内核与用户层的切换,提升程序执行效率。

还有个小的注意的点,就是说recv这个函数,如果recv的len参数设置为0,相应的recv也会返回0(不论是阻塞还是非阻塞的),此时需要区别与对端close的返回0的情况。

还有就是关于listen,listen如果设置了边沿触发,此时的listen就是当内核连接数量变化的时候才会触发listen,因此如果只是accept一个的话,就可能会造成连接丢失问题,因此需要将listenFd使用fcntl改为非阻塞套接字,然后使用while进行accept监听。另外,accept的功能就是从内核套接字连接池中提取连接,他和epoll_wait是相互独立的,也就是说在这种情况下,在accept处理过程中如果有新的连接,那么accept直接会处理,处理完毕后再次epoll_wait就不会触发条件了;而如果在accept处理过程中没有处理新连接的客户端,再次返回epoll_wait,边沿触发情况下依旧会触发epoll_wait.

那么如果在listen、epoll_add之后,epoll_wait之前有新的连接到来,测试发现他也是会触发epoll_wait的。

还有就是关于epoll_wait的接口中的epoll_event接收数组大小问题,这个本质上就是从内核的就绪链表中复制数据,即使传入数组大小无法一次性读取装在内核的就绪列表中的数据,但是他再次执行到epoll_wait的时候会继续转载,因此这个数组的大小无需设置太大。

关于select、poll和epoll

select实现了初步的IO复用,poll对单进程的IO复用监控描述符数量进行了解决,epoll对poll频繁的内核和用户层数据复制进行了解决。

关于65535个端口和百万连接

这里有个误区,就是说套接字描述符并不是和端口直接绑定的,套接字描述符是和五元组绑定的,本机端口只是五元组中的一个因素,当百万个客户端IP连接到服务器上的时候,服务器对每个连接都分配相同端口生成的套接字描述符都是有效的。

另外,在accept监听到客户端连接的时候会创建套接字描述符,而该连接套接字服务器的端口就是服务区对应监听的端口,这也可以一定程度上理解防火墙对端口的出入站规则。

百万连接的测试

首先,每个套接字都对应着一个文件描述符,关于文件描述符的数量限制就需要手动设定;有两个文件描述符的数量设定:一个是整个操作系统可以打开的文件描述符数量,另外一个就是进程可以打开的文件描述符数量;

后者使用ulimit -a查看,其中open file选项就是每个进程允许打开的文件描述符数量;通过ulimit -n去进行修改;这个过程中由于权限问题会修改失败,或者是sudo找不到ulimit,这种情况下可以使用su切换到管理员权限,然后进行ulimit设置。权限正常的话依旧报警"无法修改limit值:不允许的操作",那么就需要修改/etc/security/limits.conf文件,增加soft与hard参数,然后重启终端;

接下来就是修改协议栈相关的参数,tcp在使用过程中会在内核层创建缓冲区等,这个文件是/etc/sysctl.conf,具体参数搜索该文件,修改完毕之后使用sysctl -p将参数生效;

当然,测试的过程中考虑到硬件情况服务器端以及客户端可能都需要对以上参数进行修改;

关于端口绑定:

端口的绑定和本机的IP、端口、协议三个因素是有关的,tcp的话,协议固定,不同IP绑定相同端口也是可以进行通信的。相同IP、相同端口的情况下,TCP和UDP协议也是可以正常绑定套接字的。

客户端在发送的时候也可以使用bind对套接字进行绑定,绑定的话如果IP设置为0.0.0.0那么在发送数据的时候由内核指定IP,port如果绑定为0的话,那么就是由内核指定一个端口,且IP和port的bind是相互独立的,可以其中某个为0,也可以都为0;

关于端口复用:

当一个服务器要实现大量并发且监听一个端口的时候,首先遇到的问题就是集中性的accept问题和close问题,也就是惊群问题,处理这个问题一个是手动加锁,一个是端口复用。

关于为什么提升处理线程可以提升服务器效率问题:

个人认为:不论是否分解服务器服务到多个线程,最终要解决的服务都是一样的,因此这个问题和连接没有关系,应该和进程调度有关系,更多的线程可以获取到更大占比的CPU时间,从而提升服务器效率。因此分解服务到线程本质上就是向内核申请更多的时间。

epoll与reactor模式相关推荐

  1. 基于Epoll的Reactor模式

    Reactor模式 Reactor模式的定义 Reactor模式中的主要角色 Epoll (ET)服务器 EventItem类的设计 Reactor类的设计 回调函数 套接字相关 引入线程池 Reac ...

  2. swing的gui是通过何种模式进行事件响应与监听_【Vert.x准备篇2】C10K问题与Reactor模式...

    C10K问题是1999年一个叫Dan Kegel的美国人提出的概念,其中C为concurrently, 10K指的是1万个网络连接, 结合起来意为如何能够做到并发处理1万个连接. 这里首先要澄清一下, ...

  3. 高性能IO -Reactor模式的实现

    2019独角兽企业重金招聘Python工程师标准>>> 在了解Reactor模式之前, 首先了解什么是NIO. java.nio全称java non-blocking IO 即非阻塞 ...

  4. 【Netty】Netty 简介 ( 原生 NIO 弊端 | Netty 框架 | Netty 版本 | 线程模型 | 线程 阻塞 IO 模型 | Reactor 模式引入 )

    文章目录 一. NIO 原生 API 弊端 二. Netty 简介 三. Netty 架构 四. Netty 版本 五. Netty 线程模型 六. 阻塞 IO 线程模型 七. 反应器 ( React ...

  5. libevent之Reactor模式详解

    转自:http://blog.csdn.net/sparkliang/article/details/4957667 前面讲到,整个libevent本身就是一个Reactor,因此本节将专门对Reac ...

  6. ACE - Reactor模式源码剖析及具体实现(大量源码慎入)

    原文出自http://www.cnblogs.com/binchen-china,禁止转载. 在之前的文章中提到过Reactor模式和Preactor模式,现在利用ACE的Reactor来实现一个基于 ...

  7. Netty出现的原因以及多种Reactor模式

    一.原生NIO存在的问题 NIO的类库与API繁杂,需要熟练掌握Selector.ServerSocketChannel.SocketChannel.Bytebuffer等要求熟悉Java多线程编程和 ...

  8. Linux网络编程 | 事件处理模式:Reactor模式、Proactor模式

    文章目录 Reactor模式 Proactor模式 同步I/O模型模拟Proactor模式 两者的优缺点 Reactor Proactor 随着网络设计模式的兴起,Reactor和Proactor事件 ...

  9. 两种IO模式:Proactor与Reactor模式

    在高性能的I/O设计中,有两个比较著名的模式Reactor和Proactor模式,其中Reactor模式用于同步I/O,而Proactor运用于异步I/O操作. 在比较这两个模式之前,我们首先的搞明白 ...

最新文章

  1. LabVIEW实现PCB电路板坐标定位(实战篇—2)
  2. 系统架构的过程 浮现式设计
  3. 阿里开源的缓存框架JetCache,实现spring二级缓存
  4. Master 横扫围棋各路高手,是时候全面研究通用人工智能了!
  5. pandas 提取数字_经验轻松提取Meta原始文献特征
  6. word2vec中文相似词计算和聚类的使用说明及c语言源码
  7. ipython怎么安装numpy_在TensorFlow教程中安装numpy后仍然无法导入
  8. P3462-[POI2007]ODW-Weights【贪心】
  9. 新功能:阿里云负载均衡SLB支持HTTP访问强制跳转HTTPS
  10. 三、Java面向对象编程有四个特征
  11. spingbot 与 activiti 整个 中创建表而找不到表的问题(创建表失败)
  12. 你是否真的适合搞NDK开发?
  13. 信噪比计算方式(小问题解惑)
  14. 训练指南 UVALive - 5713(最小生成树 + 次小生成树)
  15. 使用hardhat 开发以太坊智能合约-发布合约
  16. rap技术原理_学rap最基本的都要学什么
  17. 公司研发人员(含测试)经理、组长能力评价表
  18. 【搬运】1 简谱和基本知识
  19. Eclipse for C/C++ 版本怎么安装JDT(Java Development Tools)
  20. EditPlus设置远程连接Linux管理文件

热门文章

  1. mtd分区创建linux,浅析linux下mtd设备onenand存储器的分区和节点创建流程及yaffs2文件系统挂载...
  2. java 比较两个字符串大小
  3. SAP财务凭证常见的冲销步骤详细操作手册(FB08、AB08、VF11、FBRA等)
  4. 送书 | 《从零开始学Selenium自动化测试》
  5. 机器学习 (十五) 关联分析之Apriori算法
  6. mysqladmin - 管理 MySQL 服务器、获取运行状态
  7. php hook类,基于 CodeIgniter 构建 JWT RESTfull API Server
  8. LCD1602液晶 - 开发技术详解
  9. EMMC和NandFlash的区别
  10. go 验证字符串中是否包含中文或英文