Nginx 基础架构简介

2023-05-16

Nginx Vs Apache

 

对比项目nginxapache备注
进程结构master/worker

prefork

thread

mpm

 
网络结构nio/aio

<=2.2 BIO

>=2.4 BIO/NIO

 
模块处理异步callback大多同步处理 
内存管理效率高,没有浪费效率高,没有浪费 
反向代理

upstream(三种工作模式)

proxy(基于upstream)

proxy/mod_jk 

Nginx 源码结构

源代码目录结构

├── core

├── event

├── http

├── mail

├── misc

├── os

└── stream

  • core  :Nginx的核心源代码,包括常用数据结构的以及Nginx 内核实现的核心代码;
  • event:Nginx事件驱动模型,以及定时器的实现相关代码;
  • http   :Nginx 实现http 服务器相关的代码;
  • mail  :Nginx 实现邮件代理服务器相关的代码;
  • misc :辅助代码,测试C++头 的兼容性,以及对Google_PerfTools 的支持;
  • os     :不同体系统结构所提供的系统函数的封装,提供对外统一的系统调用接口;
  • stream:nginx(tcp/udp)反向代理及与上游通信的基础模块

模块结构

  • 核心模块功能:为其他模块提供一些基本功能:字符串处理、时间管理、文件读写等功能;
  • 配置解析:主要包括文件语法检查、配置参数解析、参数初始化等功能;
  • 内存管理:内存池管理、共享内存的分配、缓冲区管理等功能;
  • 事件驱动:进程创建与管理、信号接收与处理、所有事件驱动模型的实现、高级 IO 等功能;
  • 日志管理:错误日志的生成与管理、任务日志的生成与管理等功能;
  • HTTP 服务:提供 Web 服务,包括客户度连接管理、客户端请求处理、虚拟主机管理、服务器组管理等功能;

源码代码行数

core 核心模块结构

/* 实现对各模块的整体控制,是 Nginx 程序 main 函数 */

├── nginx.c

├── nginx.h

       

/* 以下是基本数据结构及其操作 */

├── ngx_array.c

├── ngx_array.h

├── ngx_hash.c

├── ngx_hash.h

├── ngx_list.c

├── ngx_list.h

├── ngx_queue.c

├── ngx_queue.h

├── ngx_radix_tree.c

├── ngx_radix_tree.h

/* 红黑树实现 */

├── ngx_rbtree.c

├── ngx_rbtree.h

├── ngx_output_chain.c

├── ngx_buf.c

├── ngx_buf.h

/* 整个Nginx 模块构架基本配置管理  */

├── ngx_conf_file.c

├── ngx_conf_file.h

├── ngx_config.h

/* 网络连接管理 */

├── ngx_connection.c

├── ngx_connection.h

/* 定义一些头文件与结构别名 */

├── ngx_core.h

├── ngx_cpuinfo.c

/* CRC 校验表信息 */

├── ngx_crc32.c

├── ngx_crc32.h

├── ngx_crc.h

/* 实现对系统运行过程参数、资源的通用管理 */

├── ngx_cycle.c

├── ngx_cycle.h

/* 实现文件读写相关的功能 */

├── ngx_file.c

├── ngx_file.h

/* socket 网络套接字功能 */

├── ngx_inet.c

├── ngx_inet.h

/* 实现日志输出、管理的相关功能 */

├── ngx_log.c

├── ngx_log.h

├── ngx_syslog.c

├── ngx_syslog.h

/* hash字符串操作 */

├── ngx_md5.c

├── ngx_md5.h

├── ngx_murmurhash.c

├── ngx_murmurhash.h

/* 内存管理相关文件 */

├── ngx_open_file_cache.c

├── ngx_open_file_cache.h

├── ngx_palloc.c

├── ngx_palloc.h

├── ngx_shmtx.c

├── ngx_shmtx.h

├── ngx_slab.c

├── ngx_slab.h

/* PCRE 上层封装 */

├── ngx_parse.c

├── ngx_parse.h

/* 反向代理的协议信息 */

├── ngx_proxy_protocol.c

├── ngx_proxy_protocol.h

/* 实现支持正则表达式 */

├── ngx_regex.c

├── ngx_regex.h

/* 字符串处理功能 */

├── ngx_string.c

├── ngx_string.h

/* 时间获取与管理功能 */

├── ngx_times.c

└── ngx_times.h

/* 其他文件 */

├── ngx_resolver.c

├── ngx_resolver.h

├── ngx_sha1.h

├── ngx_spinlock.c

├── ngx_crypt.c

├── ngx_crypt.h

event 事件驱动模型结构

event 目录里面包含一种子目录 module 以及一些文件,除了 module 子目录,其他文件提供了事件驱动模型相关数据结构的定义、初始化、事件接收、传递、管理功能以及事件驱动模型调用功能。module 子目录里面的源码实现了Nginx 支持的事件驱动模型:AIO、epoll、kqueue、select、/dev/poll、poll 等事件驱动模型;

.

├── modules

│   ├── ngx_aio_module.c           /* AIO 事件驱动模型 */

│   ├── ngx_devpoll_module.c       /* dev/poll 事件驱动模型 */

│   ├── ngx_epoll_module.c         /* epoll 事件驱动模型 */

│   ├── ngx_eventport_module.c     /* 事件驱动模型端口 */

│   ├── ngx_kqueue_module.c        /* kqueue 事件驱动模型 */

│   ├── ngx_poll_module.c          /* poll 事件驱动模型 */

│   ├── ngx_rtsig_module.c         /* rtsing 事件驱动模型 */

│   ├── ngx_select_module.c        /* Linux 平台下的 select 事件驱动模型 */

│   └── ngx_win32_select_module.c  /* Win32 平台下的 select 事件驱动模型 */

├── ngx_event_accept.c

├── ngx_event_busy_lock.c

├── ngx_event_busy_lock.h

├── ngx_event.c

├── ngx_event_connect.c

├── ngx_event_connect.h

├── ngx_event.h

├── ngx_event_mutex.c

├── ngx_event_openssl.c

├── ngx_event_openssl.h

├── ngx_event_openssl_stapling.c

├── ngx_event_pipe.c

├── ngx_event_pipe.h

├── ngx_event_posted.c

├── ngx_event_posted.h

├── ngx_event_timer.c

└── ngx_event_timer.h

Nginx 基础数据结构

整型数据

/* Nginx 简单数据类型 */

/* 在文件 src/core/ngx_config.h 定义了基本的数据映射 */

typedef intptr_t        ngx_int_t;

typedef uintptr_t       ngx_uint_t;

typedef intptr_t        ngx_flag_t;

typedef unsigned long int   uintptr_t;

typedef int                   intptr_t;

typedef unsigned int             uintptr_t;

/* 因此,Nginx 的简单数据类型的操作和整型或指针类型类似 */

字符串类型

/* Nginx 字符串数据类型 */

/* Nginx 字符串类型是对 C 语言字符串类型的简单封装,

* 其定义在 core/ngx_string.h 或 core/ngx_string.c 中

* 定义了 ngx_str_t, ngx_keyval_t, ngx_variable_value_t

*/

/* ngx_str_t 在 u_char 的基础上增加了字符串长度的信息,即len变量 */

typedef struct {

    size_t      len;    /* 字符串的长度 */

    u_char     *data;   /* 指向字符串的第一个字符 */

} ngx_str_t;

内存池类型

/* 内存池结构 */

typedef struct {/* 内存池数据结构模块 */

    u_char               *last; /* 当前内存分配的结束位置,即下一段可分配内存的起始位置 */

    u_char               *end;  /* 内存池的结束位置 */

    ngx_pool_t           *next; /* 指向下一个内存池 */

    ngx_uint_t            failed;/* 记录内存池内存分配失败的次数 */

} ngx_pool_data_t;  /* 维护内存池的数据块 */

struct ngx_pool_s {/* 内存池的管理模块,即内存池头部结构 */

    ngx_pool_data_t       d;    /* 内存池的数据块 */

    size_t                max;  /* 内存池数据块的最大值 */

    ngx_pool_t           *current;/* 指向当前内存池 */

    ngx_chain_t          *chain;/* 指向一个 ngx_chain_t 结构 */

    ngx_pool_large_t     *large;/* 大块内存链表,即分配空间超过 max 的内存 */

    ngx_pool_cleanup_t   *cleanup;/* 析构函数,释放内存池 */

    ngx_log_t            *log;/* 内存分配相关的日志信息 */

};

/* 文件 core/ngx_core.h */

typedef struct ngx_pool_s   ngx_pool_t;

缓冲区数据类型

缓冲区 ngx_buf_t 的定义如下:

/* 缓冲区结构 */

typedef struct ngx_buf_s  ngx_buf_t;

struct ngx_buf_s {

    u_char          *pos;   /* 缓冲区数据在内存的起始位置 */

    u_char          *last;  /* 缓冲区数据在内存的结束位置 */

    /* 这两个参数是处理文件时使用,类似于缓冲区的pos, last */

    off_t            file_pos;

    off_t            file_last;

    /* 由于实际数据可能被包含在多个缓冲区中,则缓冲区的start和end指向

     * 这块内存的开始地址和结束地址,

     * 而pos和last是指向本缓冲区实际包含的数据的开始和结尾

     */

    u_char          *start;         /* start of buffer */

    u_char          *end;           /* end of buffer */

    ~~blabla~~

};

chain 数据类型

ngx_chain_t 数据类型是与缓冲区类型 ngx_buf_t 相关的链表结构,定义如下:

struct ngx_chain_s {

    ngx_buf_t    *buf;  /* 指向当前缓冲区 */

    ngx_chain_t  *next; /* 指向下一个chain,形成chain链表 */

};

typedef struct ngx_chain_s  ngx_chain_t;

链表图如下:

extern volatile ngx_cycle_t  *ngx_cycle;

Nginx 基础服务模块

nginx conf

core/upstream/

main/srv/loc config 

#define NGX_DIRECT_CONF            0x00010000 

#define NGX_MAIN_CONF              0x01000000 

#define NGX_ANY_CONF               0x0F000000

 

#define NGX_EVENT_CONF            0x02000000

#define NGX_HTTP_MAIN_CONF          0x02000000 

#define NGX_HTTP_SRV_CONF           0x04000000 

#define NGX_HTTP_LOC_CONF           0x08000000 

#define NGX_HTTP_UPS_CONF           0x10000000 

#define NGX_HTTP_SIF_CONF           0x20000000 

#define NGX_HTTP_LIF_CONF           0x40000000 

#define NGX_HTTP_LMT_CONF           0x80000000 

nginx 时间处理

nginx 的时间是缓存的时间,如果需要获得最新时间,需要调用ngx_time_update来更新时间,

详细:http://blog.csdn.net/mrzhangjwei/article/details/77150335

nginx 定时器

 

在 Nginx 中定时器事件的实现与内核无关,是通过红黑树来实现。在事件模块中,当等待的事件不能在指定的时间内到达,则会触发Nginx 的超时机制,超时机制会对发生超时的事件进行管理,并对这些超时事件作出处理。对于定时事件的管理包括两方面:定时事件对象的组织形式 和 定时事件对象的超时检测。

 

nginx Event module

EveryThing Is event driven.

epoll/kqueue/select/poll/aio :

https://www.cnblogs.com/linganxiong/p/5583415.html

https://www.nginx.com/blog/thread-pools-boost-performance-9x/

NGX_AGAIN/NGX_ERROR/NGX_OK

多次调用同一个处理函数,需要从同步编程模式转换到异步编程思维,中间变量都是通过context来保存。

nginx connection

client/upstream/other module 只要是可以抽象为文件的,都需要占用一个

file descriptor

nginx upstream

三种工作模式

  1. 不转发响应
  2. 以下游网速优先来转发响应
  3. 以上游网速优先来转发响应

根据buffer_size的大小,工作方式不一致,如果buffer太小,会导致写盘操作,所以需要配置的时候进来可以覆盖大部分upstream返回值大小。

Nginx 处理Http的流程

除了上述几个核心模块之外,其他一切皆为模块。

typedef enum {

    NGX_HTTP_POST_READ_PHASE = 0,

    NGX_HTTP_SERVER_REWRITE_PHASE,

    NGX_HTTP_FIND_CONFIG_PHASE,

    NGX_HTTP_REWRITE_PHASE,

    NGX_HTTP_POST_REWRITE_PHASE,

    NGX_HTTP_PREACCESS_PHASE,

    NGX_HTTP_ACCESS_PHASE,

    NGX_HTTP_POST_ACCESS_PHASE,

    NGX_HTTP_TRY_FILES_PHASE,

    NGX_HTTP_CONTENT_PHASE,

    NGX_HTTP_LOG_PHASE

} ngx_http_phases;

 

参考资料

https://www.kancloud.cn/digest/understandingnginx/202595

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Nginx 基础架构简介 的相关文章

随机推荐

  • 学习科大讯飞的StatQuest机器学习课笔记(3)

    Day3学习笔记07 21 最小二乘法 线性回归 用数据拟合一条直线y 61 ax 43 b 1 我们要使观测值与直线之间的距离 残差 的平方最小化 2 通过求导找到它等于0时的点 3 这条直线使平方和达到了最小化 odds 胜负比 和od
  • 七款经典4.2v锂电池充电电路图详解 - 全文

    4 2v锂电池充电电路图 xff08 一 xff09 xff1a 锂电池充电均衡电路 这个均衡电路用的是三个一模一样的并联稳压电路组成的 xff0c 每个电池上并一个 电路原理图如下 xff1a 每个稳压电源都调节到4 2V 均衡的原理是
  • sqlserver删除master数据库中的用户创建的表

    最近在使用SQL Server2019 xff0c 在程序中执行建表语句默认建到了master数据库中 xff0c 使用SSMS SQL Server Management studio 执行以下语句时提示 xff1a 不允许对系统目录进行
  • QLineEdit和QDateTimeEdit等含编辑框使用stylesheet配置背景透明时,鼠标进入离开背景闪烁问题的解决

    在使用QLineEdit和QDateTimeEdit等含编辑框的控件时如果使用stylesheet设置背景透明如下 xff1a QLineEdit background color transparent color white QLine
  • 使用Poco库进行加解密和签名验签

    最近一个朋友让我帮忙找一下使用Poco库进行非对称加密的例子 xff0c 通过百度 xff0c Google找到两个不错的在此总结一下 xff1a Poco开源代码库地址 xff1a https github com pocoproject
  • 走进开源代码(一)

    目录 前言 从哪里开始 xff1f 总结 前言 今天是个既特殊又年轻的节日 双十一 剁手节 xff0c 也算是个有纪念意义的开端吧 xff01 上周参加了系统架构设计师考试 xff0c 论文没有写完 xff0c 虽然这次肯定是过不了了 xf
  • 走进开源代码(二)

    目录 一 下载源代码 xff0c 了解目录结构 二 src目录介绍 总结 上一篇文章写了通过两篇文章大致了解比特币项目的目的和解决问题的策略 xff0c 本节正式走进源代码 xff1b 一 下载源代码 xff0c 了解目录结构 比特币项目的
  • [转]深度剖析闪电网络

    转自 xff1a https new qq com omn 20201108 20201108A04RZW00 html 闪电网络 xff08 Lighting Network xff09 是比特币的二层扩容方案 xff0c 由 Josep
  • 听李天飞《大话西游》有感

    作为一个老程序员搬砖之余喜欢看些传统文化相关的东西 xff0c 去年春节期间由于新冠疫情影响 xff0c 很多培训机构都把免费的网络课程作为力推的上课形式 xff0c 其中也包括学而思 在陪孩子上学而思网校的课程时 xff0c 有个 李天飞
  • 走进开源代码(三)

    由于工作的原因 xff0c 虽然是一名C 43 43 程序员 xff0c 平时工作中还是使用的C 43 43 99 xff0c 而比特币v0 20 1的源码是C 43 43 11写的 xff0c 虽然之前对C 43 43 11也有些了解 x
  • Linux下开发Qt界面程序时命令行传参数的一个坑

    今天在Linux下开发Qt界面程序时发现一个奇怪的问题 xff0c 程序执行如下命令却会打印日志和弹出对话框 test name xxx 代码如下 xff1a include lt QApplication gt include lt QM
  • 树莓派为连接不同Wifi分配固定IP的方法

    由于在家里和外面两种场景下使用树莓派 xff0c 家里的wifi是192 168 3 1 xff0c 在外面我用的我的360随身wifi xff0c 它的IP固定是192 168 253 1 xff08 百度未找到修改它的方法 xff09
  • ajax-Access-Control-Allow-Origin跨域问题解决

    首先 xff0c 在解决之个问题之前 xff0c 我们要弄明白为什么会出现跨域问题 跨域问题是浏览器对于ajax请求的一种安全限制 xff1a 一个页面发起的ajax请求 xff0c 只能是与当前页域名相同的路径 xff0c 这能有效的阻止
  • SSH Config 那些你所知道和不知道的事

    SSH xff08 Secure Shell xff09 是什么 xff1f 是一项创建在应用层和传输层基础上的安全协议 xff0c 为计算机上的 Shell xff08 壳层 xff09 提供安全的传输和使用环境 也是专为远程登录会话和其
  • 在虚拟云主机部署pure-ftpd后,从另一个虚拟云主机连接该ftp服务的一些问题

    问题描述 xff1a 最近的一个项目需要在公网搭建一个ftp服务器 xff0c 同时开发的Java程序需要运行在另一台公网服务器上 xff0c 开始时在本地开发机器上测试 xff0c 连接公网的ftp服务器 xff0c 上传文件都没有问题
  • 树莓派4B安装Ros 2 Foxy踩坑记录

    1 通过树莓派官方提供的写卡工具raspberry pi imager选择Ubuntu 20 04 5 xff08 64 bit xff09 xff0c 因为我打算用一个8G的存储卡安装ros 2 xff0c Ubuntu 22 04的比较
  • 浅谈第三方登录用户表结构设计方案

    国民两大流量入口 xff0c 大家不说也想到了 xff0c 分别是微信和QQ 所以为了方便获取用户来源都对接了微信登录或者QQ登录 xff0c 这一类型的第三方登录入口 今天就以对接微信登录 QQ登录与苹果登录 来说说对第三方用户体系与我方
  • Linux 网络命令

    1 ifconfig查看当前活着的网络接口信息 root 64 localhost ifconfig a 表示显示所有网卡包括没有启动的网卡 root 64 localhost ifconfig ens33 down 关闭网卡 root 6
  • 最新ffmpeg编译和用eclipse进行源码调试

    最近由于项目需要 xff0c 必须修改ffmpeg的源码进行修改才能满足项目的需求 xff0c 但以前我从来没有自己去编译和使用ffmpeg的源代码 xff0c 一直都是用别人编译好了的sdk xff0c 再加上习惯了vs方便的编译环境 x
  • Nginx 基础架构简介

    Nginx Vs Apache 对比项目nginxapache备注进程结构master worker prefork thread mpm 网络结构nio aio lt 61 2 2 BIO gt 61 2 4 BIO NIO 模块处理异步