ad
close

架构驿站的Nginx进阶实战课

本课Nginx的进阶课程,学员通过课程掌握Nginx的架构机制、模块设计和底层工作原理等。

210人学习

中级34课时2023/11/28更新

二维码下载学堂APP缓存视频离线看

架构驿站
架构驿站中级讲师讲师评分5.0学员24161课程14

为进阶而生

更多
  • 畅销套餐
  • 精选套餐
  • 人气套餐
  • 尊享套餐
  • 高薪套餐
Java Web全栈工程师之路【买视频送书】
XML需知需会:Java、C#、Python多种语言解析XML文档
67929人学习
¥49.00
jQuery必知必会:老程序员手把手带您完成一个【MyNotes】Web前端项目
45169人学习
¥49.00
师傅带徒弟学Java Web:老程序员带您完成一个【网上商城】Web项目
131699人学习
¥268.00
更 多 9 门 课 程
Java基础入门项目实战专题【买课送书】
师傅带徒弟学Java第1篇 Java基础视频课程
645348人学习
¥29.00
师傅带徒弟学Java第2篇 【Java】面向对象视频课程
525276人学习
¥49.00
师傅带徒弟学Java第4篇项目实战视频课程1——【Java】PetStore宠物商店
320207人学习
¥159.00
更 多 5 门 课 程
Java软件开发全套课程(笔记+项目案例)
SpringCloud微服务快速入门实战课程【2020版】
6698人学习
¥48.00
Redis入门视频课程(适合初学者的教程)
25409人学习
¥29.00
Dubbo快速入门视频课程(通俗易懂)
28787人学习
¥29.00
更 多 42 门 课 程
鸟哥门徒课程专题(Java全套+Web前端全套+数据库全套)
PS快速入门视频教程
3729人学习
¥39.00
全套精讲C语言基础视频课程【答疑+课件下载】
4277人学习
¥78.00
Java基础与提高全套视频上卷[IDEA版本]
4227人学习
¥198.00
更 多 59 门 课 程
鸟哥门徒课程专题(Java全套+Web前端全套+数据库全套)
PS快速入门视频教程
3729人学习
¥39.00
全套精讲C语言基础视频课程【答疑+课件下载】
4277人学习
¥78.00
Java基础与提高全套视频上卷[IDEA版本]
4227人学习
¥198.00
更 多 59 门 课 程
  • 课程介绍
  • 课程大纲

适合人群:

1. 对Nginx技术有进阶学习/面试需求 2. 团队有意向或已经引入Nginx 3. Java开发工程师

你将会学到:

本课Nginx的进阶课程,学员通过课程掌握Nginx的架构机制、模块设计和底层工作原理等。

课程简介:

架构驿站,让更多人可以因为学习和分享而受益。

大师兄

2012年入行,毕业于北京交通大学计算机科学与技术专业,曾服役于广联达、三快在线(美团)、拉勾网,技术专家。


课程大纲:

image.png


课程内容节选:

事件驱动模型

通常,事件驱动框架主要由3部分组成:事件收集器(收集事件)、事件发生器/分发器/分发者(分发事件)、事件处理器/消费者。

通常,我们在编写服务器处理模型的程序时,基于事件驱动模型,“目标对象”中的“事件处理器”可以有以下几种实现办法:

  • “事件发送器”每传递过来一个请求,“目标对象”就创建一个新的进程,调用“事件处理器”来处理该请求。

  • “事件发送器”每传递过来一个请求,“目标对象”就创建一个新的线程,调用“事件处理器”来处理该请求。

  • “事件发送器”每传递过来一个请求,“目标对象”就将其放入一个待处理事件的列表,使用非阻塞I/O方式调用“事件处理器”来处理该请求(Nginx)。

上面的三种处理方式,各有特点:

  • 第一种,创建进程开销比较大,导致服务器性能比较差,编码实现较为简单。

  • 第二种,涉及到多线程开发、编码比较复杂,涉及到线程同步、有可能面临死锁等一系列的问题。

  • 第三种,编码逻辑比前两种都要复杂,大多数网络服务器都采用第三种方式,逐渐形成了所谓的“事件驱动处理库”。

不同操作系统提供了不同事件驱动模型,例如Linux 2.6系统同时支持epoll、poll、select模型,FreeBSD系统支持kqueue模型,Solaris 10系统支持eventport模型。为了保持其跨平台特性,Nginx的事件驱动框架完美地支持各类操作系统的事件驱动模型。

针对每一种模型,Nginx设计了一个Event模块,包括ngx_epoll_module、ngx_poll_module、ngx_select_module、ngx_kqueue_module等事件驱动模块。

事件驱动框架会在模块初始化时(Nginx启动时)选取其中一个作为Nginx进程的事件驱动模块。对于大多数生产环境中Liunx系统的Web服务器,Nginx默认选取最强大的事件驱动模型epoll。


(1)epoll原理详解

当某一进程调用epoll_create方法时,Linux内核会创建一个eventpoll结构体,这个结构体中有两个成员与epoll的使用方式密切相关,如下所示:

struct eventpoll {
  ...
  /*红黑树的根节点,这棵树中存储着所有添加到epoll中的事件,也就是这个epoll监控的事件*/
  struct rb_root rbr;
  /*双向链表rdllist保存着将要通过epoll_wait返回给用户的、满足条件的事件,需要处理的,有意义的*/
  struct list_head rdllist;
  ...
};

我们在调用epoll_create时,内核除了帮我们在epoll文件系统里建了个file结点,在内核cache里建了个红黑树用于存储以后epoll_ctl传来的socket外,还会再建立一个rdllist双向链表,用于存储准备就绪的事件。当epoll_wait调用时,仅仅观察这个rdllist双向链表里有没有数据即可。有数据就返回,没有数据就sleep,等到timeout时间到后即使链表没数据也返回。所以,epoll_wait非常高效。

所有添加到epoll中的事件都会与硬件设备(如网卡)驱动程序建立回调关系,也就是说相应事件的发生时会调用这里的回调方法,它会把这样的事件放到上面的rdllist双向链表中。

一般来说,在程序的整个运行周期中只有一个epoll句柄。例如,nginx的每个工作进程只维护一个epoll句柄。句柄创建后,我们的程序监听的每个端口本质上都是文件描述符,可以在此上发生Accept事件,即接收客户端请求。因此,最初我们将添加与要通过epoll的ctl()方法监听的端口相对应的文件描述符。成功添加后,每个监听文件描述符对应于eventpoll红黑树中的节点。

我们在这里可以看到,在使用epoll的过程中,将有两种类型的文件描述符:

  • 一种是与我们正在收听的端口相对应的文件描述符,我们通常监听其Accept事件以等待客户端连接

  • 一种是与每个客户端连接对应的文件描述符,它监听其读写事件以接收数据并将其发送到客户端


在epoll中对于每一个事件都会建立一个epitem结构体,如下所示:

struct epitem {
  ...
  //红黑树节点
  struct rb_node rbn;
  //双向链表节点
  struct list_head rdllink;
  //事件句柄等信息
  struct epoll_filefd ffd;
  //指向其所属的eventepoll对象
  struct eventpoll *ep;
  //期待的事件类型
  struct epoll_event event;
  ...
}; // 这里包含每一个事件对应着的信息。

当调用epoll_wait检查是否有发生事件的连接时,只是检查eventpoll对象中的rdllist双向链表是否有epitem元素而已,如果rdllist链表不为空,则这里的事件复制到用户态内存(使用共享内存提高效率)中,同时将事件数量返回给用户。

epoll_ctl在向epoll对象中添加、修改、删除事件时,从rbr红黑树中查找事件也非常快,也就是说epoll是非常高效的,它可以轻易地处理百万级别的并发连接。

image.png

  • 执行epoll_create()时,创建了红黑树和就绪链表

  • 执行epoll_ctl()时,如果增加socket句柄,则检查在红黑树中是否存在,存在立即返回,不存在则添加到树干上,然后向内核注册回调函数

  • 执行epoll_wait()时立刻返回准备就绪链表里的数据即可

展开更多

“架构驿站”老师的其他课程更多+

close
  • 课程介绍
  • 课程大纲
在线
客服
APP
下载

下载Android客户端

下载iphone 客户端

官方
微信

关注官方微信

返回
顶部
adv-image