Nginx 基础架构简介

Nginx Vs Apache

 

对比项目 nginx apache 备注
进程结构 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

你可能感兴趣的:(Nginx)