nginx创建和监听套接字分析

news2024/11/13 14:31:40

https://cloud.tencent.com/developer/article/1859856
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

简介
nginx作为一个web服务器,肯定是有listen套接字对外提供服务的,listen套接字是用于接收HTTP请求。

nginx监听套接字的创建是根据配置文件的内容来创建的,在nginx.conf文件中有多少个地址就需要创建多少个监听套接字。

本文不针对源码逐一注解分析,只是说明套接字创建监听流程。

流程
当客户端发来http请求与服务端创建一个连接,过程如下:

1.nginx首先在main函数中调用了ngx_init_cycle()函数,在这个函数的最后调用了ngx_open_listening_sockets函数,这个函数负责将创建的监听套接字进行套接字选项的设置(比如非阻塞、接受发送的缓冲区、绑定、监听处理)。

2.nginx创建套接字是在哪里呢?在解析http{}配置的时候,也就是在ngx_http_block()函数内,在这个函数的最后调用ngx_http_optimize_servers()函数。
在这个函数内最后调用了ngx_http_init_listening()函数,这个函数调用了ngx_http_add_listening函数,在这个函数总调用了ngx_create_listening()函数。

这个函数根据每一个IP地址:port这种配置创建一个监听套接字,这个函数还有一个很重要的任务,就是将监听套接字的回调函数设置为ngx_http_init_connection函数,记住这是监听套接字上的回调,而不是监听套接字对应的可读事件的回调函数。

3.nginx什么时候接受客户端http请求建立的连接呢?在ngx_event_process_init()函数内,这个函数是作为ngx_event_core_module模块创建的init_process函数。

这个函数是在worker进程初始化是被被调用的,ngx_event_process_init函数将每个监听套接字和一个连接(ngx_connection_t)相互创建关系。

在cycle内创建一个连接池,创建一个读事件池,创建一个写事件的池,然后创建for循环遍历cycle中的所有ngx_listening_t的结构体,对每一个ngx_listening_t结构体,也就是每一个监听套接字,从连接池中获取一个连接,将这个连接对应这个监听套接字,然后将读事件设置为ngx_event_accept,那么在对应的监听套接字上accept接受新的连接(划重点)!!!

4.连接结束完成后,调用这个监听套接字上的handler,也就是ngx_http_init_connection函数,从这个函数开始了HTTP请求的交互......

总结
总结首先对于一个初始化好的ngx_listening_t时,这里面只有一个套接字,没有可读可写事件,它需要ngx_connection_t托管,在ngx_connection_t中可读可写事件,在ngx_event_t结构中,data对应一个ngx_connection_t结构体。

参考资料:
https://blog.csdn.net/wangmanjie/article/details/52793847?utm_medium=distribute.pc_relevant.none-task-blog-2defaultBlogCommendFromBaidudefault-5.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2defaultBlogCommendFromBaidudefault-5.control
Nginx源码分析:3张图看懂启动及进程工作原理
图一:nginx 启动及内存申请过程分析
任何程序都离不开启动和配置解析。ngx 的代码离不开 ngx_cycle_s 和 ngx_pool_s 这两个核心数据结构,所以我们在启动之前先来分析下。

内存申请过程分为 3 步

假如申请的内存小于当前块剩余的空间,则直接在当前块中分配。

假如当前块空间不足,则调用 ngx_palloc_block 分配一个新块然后把新块链接到 d.next 中,然后分配数据。

假如申请的大小大于当前块的最大值,则直接调用 ngx_palloc_large 分配一个大块,并且链接到 pool→large 链表中

内存分配过程图解如下

(图片来自网络)

为了更好理解上面的图,可以参看文末附 2 的几个数据结构:ngx_pool_s 及 ngx_cycle_s。

知道了这两个核心数据结构之后,我们正式进入 main 函数,main 函数执行过程如下

调用 ngx_get_options() 解析命令参数;

调用 ngx_time_init() 初始化并更新时间,如全局变量ngx_cached_time;

调用 ngx_log_init() 初始化日志,如初始化全局变量 ngx_prefix,打开日志文件 ngx_log_file.fd;

清零全局变量 ngx_cycle,并为 ngx_cycle.pool 创建大小为 1024B 的内存池;

调用 ngx_save_argv() 保存命令行参数至全局变量 ngx_os_argv、ngx_argc、ngx_argv 中;

调用 ngx_process_options() 初始化 ngx_cycle 的 prefix, conf_prefix, conf_file, conf_param 等字段;

调用 ngx_os_init() 初始化系统相关变量,如内存页面大小 ngx_pagesize , ngx_cacheline_size , 最大连接数 ngx_max_sockets 等;

调用 ngx_crc32_table_init() 初始化 CRC 表 ( 后续的 CRC 校验通过查表进行,效率高 );

调用 ngx_add_inherited_sockets() 继承 sockets:

解析环境变量 NGINX_VAR = “NGINX” 中的 sockets,并保存至 ngx_cycle.listening 数组;

设置 ngx_inherited = 1;

调用 ngx_set_inherited_sockets() 逐一对 ngx_cycle.listening 数组中的 sockets 进行设置;

初始化每个 module 的 index,并计算 ngx_max_module;

调用 ngx_init_cycle() 进行初始化;

该初始化主要对 ngx_cycle 结构进行;

若有信号,则进入 ngx_signal_process() 处理;

调用 ngx_init_signals() 初始化信号;主要完成信号处理程序的注册;

若无继承 sockets,且设置了守护进程标识,则调用 ngx_daemon() 创建守护进程;

调用 ngx_create_pidfile() 创建进程记录文件;( 非 NGX_PROCESS_MASTER = 1 进程,不创建该文件 )

进入进程主循环;

若为 NGX_PROCESS_SINGLE=1模式,则调用 ngx_single_process_cycle() 进入进程循环;

否则为 master-worker 模式,调用 ngx_master_process_cycle() 进入进程循环;

在 main 函数执行过程中,有一个非常重要的函数 ngx_init_cycle,这个阶段做了什么呢?下面分析 ngx_init_cycle,初始化过程:

更新 timezone 和 time

创建内存池

给 cycle 指针分配内存

保存安装路径,配置文件,启动参数等

初始化打开文件句柄

初始化共享内存

初始化连接队列

保存 hostname

调用各 NGX_CORE_MODULE 的 create_conf 方法

解析配置文件

调用各NGX_CORE_MODULE的init_conf方法

打开新的文件句柄

创建共享内存

处理监听socket

创建socket进行监听

调用各模块的init_module

图二:master 进程工作原理及工作工程

以下过程都在ngx_master_process_cycle 函数中进行,启动过程:

暂时阻塞所有 ngx 需要处理的信号

设置进程名称

启动工作进程

启动cache管理进程

进入循环开始处理相关信号

master 进程工作过程

设置 work 进程退出等待时间

挂起,等待新的信号来临

更新时间

如果有 worker 进程因为 SIGCHLD 信号退出了,则重启 worker 进程

master 进程退出。如果所有 worker 进程都退出了,并且收到 SIGTERM 信号或 SIGINT 信号或 SIGQUIT 信号等,master 进程开始处理退出

处理SIGTERM信号

处理SIGQUIT信号,并且关闭socket

处理SIGHUP信号

平滑升级,重启worker进程

不是平滑升级,需要重新读取配置

处理重启 10处理SIGUSR1信号 重新打开所有文件 11处理SIGUSR2信号 热代码替换,执行新的程序 12处理SIGWINCH信号,不再处理任何请求

图三:worker 进程工作原理

启动通过执行 ngx_start_worker_processes 函数:

先在 ngx_processes 数组中找坑位if (ngx_processes[s].pid == -1) {break;}

进程相关结构初始化工作

创建管道 ( socketpair )

设置管道为非阻塞模式

设置管道为异步模式

设置异步 I/O 的所有者

如果 exec 执行的时候本 fd 不传递给 exec 创建的进程

fork 创建子进程。创建成功后,子进程执行相关逻辑:proc(cycle, data)。

设置 ngx_processes[s] 相关属性

通知子进程新进程创建完毕 ngx_pass_open_channel(cycle, &ch);

接下来是 ngx_worker_process_cycle worker 进程逻辑

ngx_worker_process_init

初始化环境变量

设置进程优先级

设置文件句柄数量限制

设置 core_file 文件

用户组设置

cpu 亲和度设置

设定工作目录

设置随机种子数

初始化监听状态

调用各模块的init_process方法进行初始化

关闭别人的fd[1],保留别人的fd[1]用于互相通信。自己的fd[1]接收master进程的消息。

监听channel读事件

进程模式

处理管道信号。这个过程由 ngx_channel_handler 完成,这部分具体实现在管道事件中讲解。

线程模式

ngx_worker_thread_cycle 是一个线程的循环:死循环中除了处理退出信号。主要进行ngx_event_thread_process_posted工作,这块具体内容在后面讲事件模型的时候再展开。

处理相关信号

master 和 worker 通信原理为:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/888304.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

视频音乐如何转换成mp3?教你超简单的转换方法

MP3文件通常比视频文件更小。因此,通过将音乐从视频中提取并转换为MP3格式,您可以更轻松地存储和传输它们。如果计划在手机或其他设备上存储音乐,转换为MP3格式可以帮助我们节省存储空间。而且,如果需要将音乐发送给朋友或上传到互…

基于JAVA高校校园点餐系统-lw+ppt

文章目录 前言一、主要技术javaMysql数据库JSP技术 二、系统设计1. 系统结构图 三、功能截图总结 前言 21世纪的今天,随着社会的发展与进步,人们对信息科学的认识已从低层次提升到高层次,从感性认识逐渐转变为理性认识。管理工作的重要性也逐…

新生录取查询系统怎么制作?

在制作新生录取查询系统前,先跟老师们介绍一下招生录取的详细流程,以便老师们更好的完成录取工作的筹备,顺利过渡招生季! 1. 招生宣传和报名:学校通过各种途径进行招生宣传,向学生和家长介绍学校的特色、教…

图数据库_Neo4j学习cypher语言_常用函数_关系函数_字符串函数_聚合函数_数据库备份_数据库恢复---Neo4j图数据库工作笔记0008

然后再来看一些常用函数,和字符串函数,这里举个例子,然后其他的 类似 可以看到substring字符串截取函数 可以看到截取成功 聚合函数 这里用了一个count(n) 统计函数,可以看到效果 关系函数,我们用过就是id(r) 可以取出对应的r的id来这样..

北京影视展BIRTV 2023亮点提前盘点

2023年8月23-26日,“融合创新 面向未来”——由国家广播电视总局和中央广播电视总台共同指导,中国广播电视国际经济技术合作总公司主办的第三十届北京国际广播电影电视展览会(BIRTV2023)将在北京中国国际展览中心(朝阳…

大股东被纪检监察调查,会否成为大牧人上市之路的又一拦路虎?

据悉,深圳证券交易所上市审核委员会已经定于2023年8月17日召开2023年第63次上市审核委员会审议会议,审核青岛大牧人机械股份有限公司(即“大牧人”)首发上市。这已经是大牧人因股东股权纷争(见相关媒体报道&#xff09…

项目经理掌控项目进度的重要手段——甘特图

项目经理最担心的是无法了解团队成员每天的工作内容以及项目的进展情况。因此,每天的会议和项目周报是项目经理掌控项目进度的重要手段,能够帮助项目经理及时了解和跟踪项目的进展。 进度控制是指监督项目状态、更新项目进展、管理进度基准变更&#x…

Python Tkinter 树状浏览图,类和函数及文件浏览的应用(由idlelib tree模块修改)

模块由idlelib tree模块修改,完善一些问题,重写了获取类和函数的方法,便于获取正在编辑代码的类和函数。重写了文件浏览模块,支持添加收藏,双击py(pyw)文件会打开函数浏览器,文件浏览…

【AGC】崩溃数据消失问题

【问题背景】 最近有开发者集成了AGC的崩溃服务,出现了一个问题,在集成完成后,触发崩溃事件测试,在AGC后台可以看到当天崩溃的数据,但是启动次数显示为0。等到第二天再看数据时,连昨天的崩溃数据都没有了。…

一文带你搞懂MySQL的隔离级别

一. 前言 最近遇到这样一个题目:【假设目前你们使用的数据库是MySQL,现在有一个事务A,在事务A开始时读取数据的结果是1;事务A中间有一段耗时操作,在事务A中做耗时操作的同时,有另外一个事务B把数据值改成了…

MFC为控件添加背景图片

1、 添加选择Bitmap导入图片,图片文件最好放在项目res目录中,同时是BMP格式。上传后的图片在资源视图,命名为IDB_BITMAP_M_BACK。 2、在cpp的C***Dlg::OnPaint()函数下添加如下代码 void C***Dlg::OnPaint() {CPaintDC dc(this); // device…

录制游戏视频的软件有哪些?分享3款软件!

“有录制游戏视频的软件推荐吗?最近迷上了网游,想录制点自己高端操作的游戏画面,但是不知道用什么软件录屏比较好,就想问问大家,有没有好用的录制游戏视频软件。” 在游戏领域,玩家们喜欢通过录制游戏视频…

DevExpress WinForms数据编辑器组件,提供丰富的数据输入样式!(一)

DevExpress WinForms超过80个高影响力的WinForms编辑器和多用途控件,从屏蔽数据输入和内置数据验证到HTML格式化,DevExpress数据编辑库提供了无与伦比的数据编辑选项,包括用于独立数据编辑或用于容器控件(如Grid, TreeList和Ribbon)的单元格。…

二、编写第一个 Spring MVC 程序(总结项目报 404 问题以及 Spring MVC 的执行流程)

文章目录 一、编写第一个 Spring MVC 程序二、项目运行时报 404错误原因总结三、Spring MVC 的执行流程 一、编写第一个 Spring MVC 程序 创建 maven 项目&#xff0c;以此项目为父项目&#xff0c;在父项目的 pom.xml 中导入相关依赖 <dependencies><dependency…

Planning Poker

计划扑克 一人一副牌&#xff0c;投票表决&#xff0c;这个功能、故事点的工作量是多少 0&#xff1a;没有工作量 &#xff1f;&#xff1a;需求不清楚 -------------------------------------- 数字越大&#xff0c;工作量越大&#xff0c;越要细化 100 和 ∞ ----------…

SQL-每日一题【1321. 餐馆营业额变化增长】

题目 表: Customer 你是餐馆的老板&#xff0c;现在你想分析一下可能的营业额变化增长&#xff08;每天至少有一位顾客&#xff09;。 计算以 7 天&#xff08;某日期 该日期前的 6 天&#xff09;为一个时间段的顾客消费平均值。average_amount 要 保留两位小数。 结果按 …

【第三阶段】kotlin语言使用replace完成加解密操作

fun main() {val password"ASDAFWEFWVWGEGSDFWEFEWGFS"println("原始密码&#xff1a;$password")//加密操作,就是把字符替换成数字&#xff0c;打乱加密var newPsdpassword.replace(Regex("[ADWF]")){when(it.value){//it.value 这里的每一个字…

国资委79号文解读:国央企OA办公系统信创替代落地实践与标杆案例

国资委79号文解读&#xff1a;国央企OA办公系统信创替代落地实践与标杆案例 2022年9月底&#xff0c;国资委下发了重要的国资发79号文件&#xff0c;全面指导并要求国央企落实信息化系统的信创国产化改造。其中&#xff0c;明确要求所有中央企业在2022年11月底前将安可替代总体…

有没有运动蓝牙耳机推荐?过来人告诉你选这几款不会出错

随着人们健身意识的加强&#xff0c;对于运动装备的需求也增加了不少&#xff0c;其中运动蓝牙耳机也成为了人们健身运动过程中必不可缺的一部分&#xff0c;那究竟什么款式最适合运动佩戴呢&#xff1f;作为一个深耕于运动领域以及探索耳机行业多年的爱好者&#xff0c;我为大…

电脑数据恢复,5招拯救你的数据!

“我都要对我自己无语了&#xff0c;在清理垃圾文件的时候我总是会一不小心就把重要的数据也删掉&#xff0c;然后也不知道该怎么才能恢复这些数据&#xff01;大家有什么好的方法吗&#xff1f;” 在数字化时代&#xff0c;电脑的使用越来越重要&#xff0c;它好像渐渐成了我们…