epoll

Nginx如此之快

邮差的信 提交于 2020-02-27 22:49:45
nignx的并发连接数,一般优化后,峰值能保持在 1~3w 左右。 Nginx 的进程模型 Nginx 服务器,正常运行过程中 1.多进程:一个 Master 进程、多个 Worker 进程 2.Master 进程:管理 Worker 进程 3.对外接口:接收外部的操作(信号) 4.对内转发:根据外部的操作的不同,通过信号管理 Worker 5.监控:监控 worker 进程的运行状态,worker 进程异常终止后,自动重启 worker 进程 6.Worker 进程:所有 Worker 进程都是平等的 7.实际处理:网络请求,由 Worker 进程处理; 8.Worker 进程数量:在 nginx.conf 中配置,一般设置为核心数,充分利用 CPU 资源,同时,避免进程数量过多,避免进程竞争 CPU 资源,增加上下文切换的损耗。 思考: 1.请求是连接到 Nginx,Master 进程负责处理和转发? 2.如何选定哪个 Worker 进程处理请求?请求的处理结果,是否还要经过 Master 进程? HTTP 连接建立和请求处理过程 1.Nginx 启动时,Master 进程,加载配置文件 2.Master 进程,初始化监听的 socket 3.Master 进程,fork 出多个 Worker 进程 4.Worker 进程,竞争新的连接,获胜方通过三次握手,建立 Socket

Nginx如此之快

纵饮孤独 提交于 2020-02-27 08:04:43
nignx的并发连接数,一般优化后,峰值能保持在 1~3w 左右。 Nginx 的进程模型 Nginx 服务器,正常运行过程中 1.多进程:一个 Master 进程、多个 Worker 进程 2.Master 进程:管理 Worker 进程 3.对外接口:接收外部的操作(信号) 4.对内转发:根据外部的操作的不同,通过信号管理 Worker 5.监控:监控 worker 进程的运行状态,worker 进程异常终止后,自动重启 worker 进程 6.Worker 进程:所有 Worker 进程都是平等的 7.实际处理:网络请求,由 Worker 进程处理; 8.Worker 进程数量:在 nginx.conf 中配置,一般设置为核心数,充分利用 CPU 资源,同时,避免进程数量过多,避免进程竞争 CPU 资源,增加上下文切换的损耗。 思考: 1.请求是连接到 Nginx,Master 进程负责处理和转发? 2.如何选定哪个 Worker 进程处理请求?请求的处理结果,是否还要经过 Master 进程? HTTP 连接建立和请求处理过程 1.Nginx 启动时,Master 进程,加载配置文件 2.Master 进程,初始化监听的 socket 3.Master 进程,fork 出多个 Worker 进程 4.Worker 进程,竞争新的连接,获胜方通过三次握手,建立 Socket

epoll 接口以及原理说明

我与影子孤独终老i 提交于 2020-02-27 07:09:01
实例代码 : https://github.com/xuchanglong/NtyTCP-v1.0.0-comments 主要接口 int epoll_create(int size) 创建 epoll 对象,同时创建一个空的 红黑树 以及空的 双向链表 ,返回 epoll 对象的文件描述符。 int epoll_ctl(int epid, int op, int sockid, struct epoll_event *event); 向 epoll 对象里面的红黑树中增加、删除、修改指定的节点。 int epoll_wait(int epid, struct epoll_event *events, int maxevents, int timeout); 等待双向链表中是否有节点,若有节点则取得不大于 maxevents 数量的节点并放入 events 中,最后返回。 int epoll_event_callback(struct eventpoll *ep, int sockid, uint32_t event) 有 显卡驱动 调用,判断当前事件(建立连接、断开连接、读写数据)对应的 socket 是否已经在红黑树中挂号,如果是,则将新的事件保存到对应的红黑树节点中并更新到双向链表中。 原理说明 1、上文在说明函数功能时提到了两个 epoll 核心结构: 红黑树 和 双向链表

nginx事件模块实现细节

冷暖自知 提交于 2020-02-27 05:45:31
在 nginx事件模块结构体详解 中,我们讲解nginx的事件模块的整体工作流程,并且着重讲解了组织事件模块的各个方法的作用,本文则主要围绕这整个流程,从源码的角度讲解nginx事件模块的实现细节。 1. ngx_events_block()----events配置块解析 nginx在解析nginx.conf配置文件时,如果当前解析的配置项名称为 events ,并且是一个配置块,则会调用 ngx_events_block() 方法解析该配置块,如下是该方法的源码: static char * ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { char *rv; void ***ctx; ngx_uint_t i; ngx_conf_t pcf; ngx_event_module_t *m; // 如果存储事件模块配置数据的配置项不为空,说明已经解析过配置项了,因而直接返回 if (*(void **) conf) { return "is duplicate"; } // 这里主要是计算event模块的个数,并且将各个event模块的相对顺序标记在了该模块的ctx_index属性中 ngx_event_max_module = ngx_count_modules(cf->cycle, NGX

redis学习-NIO和EPOLL(二)

放肆的年华 提交于 2020-02-26 23:44:10
redis如此之快,整体来说原因如下 绝大部分请求是纯粹的内存操作(非常快速) 采用单线程,避免了不必要的上下文切换和竞争条件 非阻塞IO 内部实现采用epoll,采用了epoll+自己实现的简单的事件框架。epoll中的读、写、关闭、连接都转化成了事件,然后利用epoll的多路复用特性,绝不在io上浪费一点时 对BIO、NIO的概念解析 所有的系统IO都分为两个阶段:等待就绪和操作。例如:读函数分为等待系统可读和真正的读;同理,写函数分为等待网卡可写和真正的写。 BIO里用户最关心" 我要读 ";我要一直等在这处理处理时间; NIO里用户最关心" 我可以读了 ";我不在这等了,如果有事件发生,你就通知我,我再来处理; BIO Java BIO : 同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。 每一个线程守着一个IO通道,当没有IO时这个线程就阻塞着,一旦有IO事件发生,这个线程就开始工作 缺点 严重依赖线程: 线程的创建和销毁成本很高; 线程本身占用较大内存; 线程切换成本很高; 容易造成锯齿状的系统负载; NIO 1.同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I

Redis 为什么这么快?

穿精又带淫゛_ 提交于 2020-02-26 22:33:55
1. 纯内存操作,肯定快 数据存储在内存中,读取的时候不需要进行磁盘的 IO 2. 单线程,无锁竞争损耗 单线程保证了系统没有线程的上下文切换 使用单线程,可以避免不必要的上下文切换和竞争条件,没有多进程或多线程引起的切换和 CPU 的消耗,不必考虑各种锁的问题,没有锁释放或锁定操作,不会因死锁而降低性能; 3. C 语言实现,更接近底层操作 Redis 是用 C 语言开发完成的 4. 多路 I/O 复用模型,非阻塞 IO 采用多路 I/O 复用技术可以让单个线程高效的处理多个网络连接请求(尽量减少网络 IO 的时间消耗) 非阻塞 IO 内部实现采用 epoll,采用了 epoll+自己实现的简单的事件框架。epoll 中的读、写、关闭、连接都转化成了事件,然后利用 epoll 的多路复用特性,绝不在 io 上浪费一点时间。 5. 数据结构简单,底层又做了优化 数据结构简单,对数据操作也简单,Redis 中的数据结构是专门进行设计的; 6. 源码精湛、简短 扩展: 在 Redis 中,常用的 5 种数据结构和应用场景 String: 缓存、计数器、分布式锁等。 List: 链表、队列、微博关注人时间轴列表等。 Hash: 用户信息、Hash 表等。 Set: 去重、赞、踩、共同好友等。 Zset: 访问量排行榜、点击量排行榜等。 多路 I/O 复用模型 多路 I/O 复用模型是利用

一线攻城狮实战经验:RDMA,好用却又很难用?

大兔子大兔子 提交于 2020-02-26 13:32:52
势不可挡的 RDMA 如今,服务器的网络带宽越来越高。当网络带宽迈过万兆这条线后,操作系统用于处理网络IO的开销就越来越难以忽视。在一些网络IO密集的业务中,操作系统本身成为了网络通信的瓶颈,这不仅会导致调用时延的增加(尤其是长尾),还会影响到服务的整体吞吐。 相对于网络带宽的发展速度,CPU性能的发展停滞是导致上述问题的主要原因。 因此,想从根本上解决CPU参与网络传输的低效问题,就要更多地借助专用芯片的能力,RDMA高性能网络势不可挡。 RDMA(Remote Direct Memory Access),可以简单理解为网卡完全绕过CPU实现两个服务器之间的内存数据交换。其作为一种硬件实现的网络传输技术,可以大幅提升网络传输效率,帮助网络IO密集的业务(比如分布式存储、分布式数据库等)获得更低的时延以及更高的吞吐。 具体来说,RDMA技术的应用要借助支持RDMA功能的网卡以及相应的驱动程序。由下图所示,一旦应用程序分配好资源,其可以直接把要发送的数据所在的内存地址和长度信息交给网卡。网卡从内存中拉取数据,由硬件完成报文封装,然后发送给对应的接收端。接收端收到RDMA报文后,直接由硬件解封装,取出数据后,直接放在应用程序预先指定的内存位置。 **由于整个IO过程无需CPU参与,无需操作系统内核参与,没有系统调用,没有中断,也无需内存拷贝,因此RDMA网络传输可以做到极高的性能。*

ZhaoWei-2020-02-01

↘锁芯ラ 提交于 2020-02-26 02:28:34
Web 服务器: 相比 Apache,Nginx 使用更少的资源,支持更多的并发连接,体现更高的效率,这点使 Nginx 尤其受到虚拟主机提供商的欢迎。在高连接并发的情况下,Nginx是Apache服务器不错的替代品: Nginx在美国是做虚拟主机生意的老板们经常选择的软件平台之一,能够支持高达 50000 个并发连接数的响应, 感谢Nginx 为我们选择了 epoll and kqueue 作为开发模型。 Nginx作为负载均衡服务器: Nginx 既可以在内部直接支持 Rails 和 PHP 程序对外进行服务, 也可以支持作为 HTTP代理 服务器对外进行服务。Nginx采用C进行编写, 不论是系统资源开销还是CPU使用效率都比 Perlbal 要好很多。 Nginx 配置简洁, Apache 复杂: Nginx 启动特别容易, 并且几乎可以做到7*24不间断运行,即使运行数个月也不需要重新启动. 你还能够不间断服务的情况下进行软件版本的升级。 Nginx 静态处理性能比 Apache 高 3倍以上,Apache 对 PHP 支持比较简单,Nginx 需要配合其他后端来使用 ,Apache 的组件比 Nginx 多。 Nginx的优点: 1、更快:单次请求会得到更快的响应;并发请求也会更快地响应请求。 2、高扩展性:完全由多个不同功能、不同层次、不同类型且耦合度极低的模块组成

select与epoll

三世轮回 提交于 2020-02-25 04:24:28
select 监听一组句柄fd_set,第一次调用的时候循环所有句柄对应的驱动函数xx_poll,socket的话就是sock_poll。 循环遍历完毕之后会如果发现有可用的(活跃状态的)fd,则返回,返回的时候会返回活跃的fd个数,同时会 把不活跃的fd在fd_set移除。如果循环fd_set一遍以后发现没有活跃的fd。假设此时socket在非阻塞模式下, 那么select会重复遍历这些fd_set直到超过了我们设置的时间限制,可是在阻塞模式下呢,怎么处理? 阻塞模式下我们没有必要设置超时限制,因为如果第一遍变量fd_set发现没有活跃的fd那么,这条进程会被 挂起的。进程怎么被激活呢,实际上进程是被挂在了n个fd的等待队列里,只要一个fd准备就绪那么进程就 会被唤醒,网卡接收了数据包发送一个中断给内核,内核处理这个中断,唤醒进程,这里是涉及到软中断的 ,有兴趣可以看看。select被唤醒之后,并不知道是哪一个fd把自己唤醒的,所以还要来一个遍历,过程跟 上面说的是一样的。select阻塞到返回经历的内核和用户空间的拷贝,先把fd_set从用户空间拷贝给内核空 间,内核空间处理完毕之后把活动的fd再copy回来。其实后者还好,但是前者当fd_set百万级别的时候,就 费劲了。个中细节我并非完全了解,可是单看这个设计模式就觉着有效率问题了,感觉真的很傻,copy不说,