详解Nginx 工作原理


Posted in Servers onMarch 31, 2021

Nginx工作原理

Nginx由内核和模块组成。

  Nginx本身做的工作实际很少,当它接到一个HTTP请求时,它仅仅是通过查找配置文件将此次请求映射到一个location block,而此location中所配置的各个指令则会启动不同的模块去完成工作,因此模块可以看做Nginx真正的劳动工作者。通常一个location中的指令会涉及一个handler模块和多个filter模块(当然,多个location可以复用同一个模块)。handler模块负责处理请求,完成响应内容的生成,而filter模块对响应内容进行处理。

用户根据自己的需要开发的模块都属于第三方模块。正是有了这么多模块的支撑,Nginx的功能才会如此强大。

Nginx的模块从结构上分为核心模块、基础模块和第三方模块:

  • 核心模块:HTTP模块、EVENT模块和MAIL模块
  • 基础模块:HTTP Access模块、HTTP FastCGI模块、HTTP Proxy模块和HTTP Rewrite模块,
  • 第三方模块:HTTP Upstream Request Hash模块、Notice模块和HTTP Access Key模块。

Nginx的模块从功能上分为如下三类:

  • Handlers(处理器模块)。此类模块直接处理请求,并进行输出内容和修改headers信息等操作。Handlers处理器模块一般只能有一个。
  • Filters (过滤器模块)。此类模块主要对其他处理器模块输出的内容进行修改操作,最后由Nginx输出。
  • Proxies (代理类模块)。此类模块是Nginx的HTTP Upstream之类的模块,这些模块主要与后端一些服务比如FastCGI等进行交互,实现服务代理和负载均衡等功能。

详解Nginx 工作原理

Nginx进程模型

  Nginx默认采用多进程工作方式,Nginx启动后,会运行一个master进程和多个worker进程。其中master充当整个进程组与用户的交互接口,同时对进程进行监护,管理worker进程来实现重启服务、平滑升级、更换日志文件、配置文件实时生效等功能。worker用来处理基本的网络事件,worker之间是平等的,他们共同竞争来处理来自客户端的请求。

nginx的进程模型如图所示:

详解Nginx 工作原理

  在创建master进程时,先建立需要监听的socket(listenfd),然后从master进程中fork()出多个worker进程,如此一来每个worker进程多可以监听用户请求的socket。一般来说,当一个连接进来后,所有在Worker都会收到通知,但是只有一个进程可以接受这个连接请求,其它的都失败,这是所谓的惊群现象。nginx提供了一个accept_mutex(互斥锁),有了这把锁之后,同一时刻,就只会有一个进程在accpet连接,这样就不会有惊群问题了。

先打开accept_mutex选项,只有获得了accept_mutex的进程才会去添加accept事件。nginx使用一个叫ngx_accept_disabled的变量来控制是否去竞争accept_mutex锁。ngx_accept_disabled = nginx单进程的所有连接总数 / 8 -空闲连接数量,当ngx_accept_disabled大于0时,不会去尝试获取accept_mutex锁,ngx_accept_disable越大,于是让出的机会就越多,这样其它进程获取锁的机会也就越大。不去accept,每个worker进程的连接数就控制下来了,其它进程的连接池就会得到利用,这样,nginx就控制了多进程间连接的平衡。

每个worker进程都有一个独立的连接池,连接池的大小是worker_connections。这里的连接池里面保存的其实不是真实的连接,它只是一个worker_connections大小的一个ngx_connection_t结构的数组。并且,nginx会通过一个链表free_connections来保存所有的空闲ngx_connection_t,每次获取一个连接时,就从空闲连接链表中获取一个,用完后,再放回空闲连接链表里面。一个nginx能建立的最大连接数,应该是worker_connections * worker_processes。当然,这里说的是最大连接数,对于HTTP请求本地资源来说,能够支持的最大并发数量是worker_connections * worker_processes,而如果是HTTP作为反向代理来说,最大并发数量应该是worker_connections * worker_processes/2。因为作为反向代理服务器,每个并发会建立与客户端的连接和与后端服务的连接,会占用两个连接。

Nginx处理HTTP请求流程

  http请求是典型的请求-响应类型的的网络协议。http是文件协议,所以我们在分析请求行与请求头,以及输出响应行与响应头,往往是一行一行的进行处理。通常在一个连接建立好后,读取一行数据,分析出请求行中包含的method、uri、http_version信息。然后再一行一行处理请求头,并根据请求method与请求头的信息来决定是否有请求体以及请求体的长度,然后再去读取请求体。得到请求后,我们处理请求产生需要输出的数据,然后再生成响应行,响应头以及响应体。在将响应发送给客户端之后,一个完整的请求就处理完了。

处理流程图:

详解Nginx 工作原理

以上就是详解Nginx 工作原理的详细内容,更多关于Nginx 工作原理的资料请关注三水点靠木其它相关文章!

Servers 相关文章推荐
阿里云Nginx配置https实现域名访问项目(图文教程)
Mar 31 Servers
解决使用了nginx获取IP地址都是127.0.0.1 的问题
Sep 25 Servers
Nginx虚拟主机的搭建的实现步骤
Jan 18 Servers
Nginx禁止ip访问或非法域名访问
Apr 07 Servers
阿里云k8s服务升级时502错误 springboot项目应用
Apr 09 Servers
nginx配置之并发频次限制
Apr 18 Servers
如何开启Apache,Nginx和IIS服务器的GZIP压缩功能
Apr 29 Servers
nginx 配置指令之location使用详解
May 25 Servers
安装harbor作为docker镜像仓库的问题
Jun 14 Servers
Docker与K8s关系介绍不会Docker也可以使用K8s
Jun 25 Servers
Zabbix对Kafka topic积压数据监控的解决方案
Jul 07 Servers
Nginx文件已经存在全局反向代理问题排查记录
Jul 15 Servers
fastdfs+nginx集群搭建的实现
Nginx域名转发https访问的实现
Mar 31 #Servers
Nginx本地目录映射实现代码实例
Mar 31 #Servers
nginx 防盗链防爬虫配置详解
Mar 31 #Servers
Nginx服务器如何设置url链接
nginx搭建图片服务器的过程详解(root和alias的区别)
Mar 31 #Servers
Nginx代理同域名前后端分离项目的完整步骤
Mar 31 #Servers
You might like
谈谈新手如何学习PHP
2006/12/23 PHP
PHP抓取远程图片(含不带后缀的)教程详解
2016/10/21 PHP
Laravel多域名下字段验证的方法
2019/04/04 PHP
Laravel中9个不经常用的小技巧汇总
2019/04/16 PHP
PHP Swoole异步读取、写入文件操作示例
2019/10/24 PHP
javascript中使用css需要注意的地方小结
2010/09/01 Javascript
jquery中使用ajax获取远程页面信息
2011/11/13 Javascript
让你的博客飘雪花超出屏幕依然看得见
2013/01/04 Javascript
防止按钮在短时间内被多次点击的方法
2014/03/10 Javascript
JavaScript控制图片加载完成后调用回调函数的方法
2015/03/20 Javascript
jquery validate.js表单验证入门实例(附源码)
2015/11/10 Javascript
AngularJS基础 ng-class-odd 指令示例
2016/08/01 Javascript
微信小程序实战之仿android fragment可滑动底部导航栏(4)
2020/04/16 Javascript
详解Vue2.0配置mint-ui踩过的那些坑
2018/04/23 Javascript
vue实现element-ui对话框可拖拽功能
2018/08/17 Javascript
jQuery实现input输入框获取焦点与失去焦点时提示的消失与显示功能示例
2019/05/27 jQuery
详解如何使用React Hooks请求数据并渲染
2020/10/18 Javascript
Python利用splinter实现浏览器自动化操作方法
2018/05/11 Python
查看python安装路径及pip安装的包列表及路径
2019/04/03 Python
Python的对象传递与Copy函数使用详解
2019/12/26 Python
Python爬虫爬取杭州24时温度并展示操作示例
2020/03/27 Python
使用Pycharm在运行过程中,查看每个变量的操作(show variables)
2020/06/08 Python
python实现mean-shift聚类算法
2020/06/10 Python
使用纯 CSS 创作一个脉动 loader效果的源码
2018/09/28 HTML / CSS
SIXPAD智能健身仪英国官网:革命性的训练装备品牌
2018/09/27 全球购物
新西兰最大、占有率最高的综合性药房:PharmacyDirect药房中文网
2020/11/03 全球购物
.TTL是什么?有什么用处,通常那些工具会用到它?(ping? traceroute? ifconfig? netstat?)
2016/05/09 面试题
怎样自定义一个异常类
2016/09/27 面试题
小学语文业务学习材料
2014/06/02 职场文书
幼儿园运动会口号
2014/06/07 职场文书
课外活动实习计划
2015/01/19 职场文书
科技活动总结范文
2015/05/11 职场文书
2015年物流客服工作总结
2015/07/27 职场文书
NodeJs内存占用过高的排查实战记录
2021/05/10 NodeJs
Java生成读取条形码和二维码的简单示例
2021/07/09 Java/Android
mysql下的max_allowed_packet参数设置详解
2022/02/12 MySQL