NGINX源码阅读
前言
- 源码版本:2018-10-02 nginx-1.15.5
- 本文主要描述Darwin环境下的流程,与Linux环境下类似,Win32环境下可能会减少部分流程
- Darwin/Linux等*nix类系统使用多进程方式运行,而Win32使用多线程方式运行
- ngx_ 开头的变量多为全局变量
- ngx_model_name.c 多为处理nginx配置中相应模块的配置处理,ngx_model_name_core_module.c 多为该模块的核心(通用)处理逻辑
nginx架构
进程工作模式
多进程
- master进程
- 用于接收外部信号发送给worker进程,如stop、restart、reload等
- 监控worker进程运行状态,worker异常退出后重新启动新的worker进程
- 缓存管理
- worker进程
- 处理基本网络事件,如http、mail请求等
单进程
调试情况下使用,直接使用单进程处理网络事件
配置
- daemon
- 配置块:main
- 值类型:flag
- 默认值:1
- 可选范围:on、off
- 说明:是否使用守护进程模式开启服务
- master_process
- 配置块:main
- 值类型:flag
- 默认值:1
- 可选范围:on、off
- 说明:是否开启master管理进程,主要用于nginx开发调试,关闭状态下不会开启accept互斥锁
- timer_resolution
- 配置块:main
- 值类型:time
- 默认值:0
- 可选范围:y、M、w、d、h、m、s、ms,解析出的毫秒值 1-[32位:2147483647;64位:9223372036854775807;]
- 说明:用于控制gettimeofday()的系统调用时机,未设置的情况下每次系统事件都将调用gettimeofday(),设置后将以该时间调用gettimeofday()
- pid
- 配置块:main
- 值类型:string
- 默认值:logs/nginx.pid(根据编译时设置,未设置则为该值)
- 可选范围:—
- 说明:用于设置主进程pid的存放路径
- lock_file
- 配置块:main
- 值类型:string
- 默认值:logs/nginx.lock(根据编译时设置,未设置则为该值)
- 可选范围:—
- 说明:用于不支持原子操作的系统使用文件锁作为accept互斥锁,支持原子操作的系统将忽略该值
- worker_processes
- 配置块:main
- 值类型:unit|string(auto)
- 默认值:1
- 可选范围:1-[32位:2147483647;64位:9223372036854775807;]
- 说明:设置worker进程数,建议使用auto由程序根据当前系统环境CPU核数设置(等于CPU核数,如果小于1则设置为1)
- debug_points
- 配置块:main
- 值类型:uint
- 默认值:0
- 可选范围:1-[32位:2147483647;64位:9223372036854775807;]
- 说明:用于监测到内部错误时中止或停止进程以进行进一步的调试
- user
- 配置块:main
- 值类型:string
- 默认值:nobody [nobody]
- 可选范围:-
- 说明:设置worker进程使用什么用户和用户组身份启动
- worker_priority
- 配置块:main
- 值类型:int
- 默认值:0
- 可选范围:-20-20
- 说明:设置worker进程的调度优先级,数值越小表示优先级越高
- worker_cpu_affinity
- 配置块:main
- 值类型:umask|string(auto)
- 默认值:—
- 可选范围:—
- 说明:将工作进程绑定到CPU组用以减少CPU上下文切换,默认情况下不绑定,设置不存在的CPU掩码将被忽略
- worker_rlimit_nofile
- 配置块:main
- 值类型:uint
- 默认值:—
- 可选范围:—
- 说明:修改worker进程的最大文件描述符限制,用于在不重新启动master进程的情况下修改限制
- worker_rlimit_core
- 配置块:main
- 值类型:uint
- 默认值:—
- 可选范围:—
- 说明:修改worker进程的核心文件最大限制,用于在不重新启动master进程的情况下修改限制
- worker_shutdown_timeout
- 配置块:main
- 值类型:time
- 默认值:0
- 可选范围:y、M、w、d、h、m、s、ms,解析出的毫秒值 1-[32位:2147483647;64位:9223372036854775807;]
- 说明:设置worker进程的结束等待时间(收到结束信号后worker可能还有未处理完的请求,默认系统将等待所有请求处理完成后退出),设置该时间后worker将在到期时直接关闭所有持有的连接
- working_directory
- 配置块:main
- 值类型:string
- 默认值:—
- 可选范围:—
- 说明:设置工作目录
- env
- 配置块:main
- 值类型:string
- 默认值:TZ
- 可选范围:—
- 说明:默认情况下程序在启动时将移除除了时区外的所有环境变量,可用该参数设置需要的环境变量
- load_module
- 配置块:main
- 值类型:string
- 默认值:—
- 可选范围:—
- 说明:用于加载动态模块
启动阶段
master处理流程
- 日志初始化
- 初始化日志格式
- 打开日志文件获取文件句柄(读写删共享锁)
- SSL初始化
- 保存启动参数
- 解析配置文件路径
- 运行环境系统初始化
- 获取cpu缓存块大小(如果有一级CPU缓存则使用一级缓存大小)ngx_cacheline_size
- 获取内存页大小 ngx_pagesize
- 获取CPU核数(如果小于一核则设置为1核)
- 压缩表初始化
- 如果为继承关系则继承原socket信息
- 模块预初始化(将所需加载的模块信息加入全局变量,程序所需加载的模块列表在程序编译时根据配置输出至ngx_modules全局变量中)
- 轮训初始化
- 加载配置
- 加载模块
- 创建共享内存
- 关闭无用socket和已打开文件
- socket监听及配置
- 如果是检查配置文件错误则返回结果
- 如果有接收到nginx信号则转发外部信号给worker进程(通过跨进程事件OpenEvent/SetEvent)
- 注册信号处理器
- 守护进程模式下fork出子进程(当前进程结束),重定向子进程输入、输出至/dev/null(通过tup2)
- 创建pid文件
- 启动worker进程循环
- 设置信号处理器(阻塞部分系统信号,接收到系统信号后转由信号处理函数处理,避免master在处理事件过程中被系统直接kill。在循环管理状态中通过sigsuspend进行阻塞等待信号,子进程退出会接收到CHLD信号)
- 启动worker进程
- 检查是否有模块使用缓存服务如有则启动缓存管理进程
- 进入循环管理状态(处理nginx和系统信号,监控worker进程)
worker处理流程
- 初始化
- 设置进程执行优先级
- 设置进程可打开的最大文件描述符
- 如果以root身份启动进程则根据nginx.conf配置设置进程运行的用户、用户组
- 如果有配置尝试设置CPU亲缘性(限定进程在某个特定的CPU中调度,减少CPU上下文切换,均衡CPU利用率)
- 解除阻塞系统信号
- 执行各模块init_process
- 设置通道读事件回调
- 循环处理事件及定时器
- 从定时事件红黑树中查找出最近需要执行的定时器时间
- 执行各模块事件初始化
- 检查当前worker是否繁忙(todo),不繁忙则尝试获取事件监听锁(避免惊群效应),如果获取不到则退出本次处理,也可通过配置忽略锁
- 等待I/O事件唤起(如果超时仍未接收到事件则),保存I/O事件相关信息,将读写事件放入队列等待后续处理
- 处理accept事件中接收的post数据
- 释放事件监听锁(允许其他worker继续获取监听锁处理事件)
- 处理时间到达的定时器
- 处理普通事件(非accept事件)中接收的post数据
- 循环处理master通知信号
- ngx_exiting 检查定时器中是否仍有未处理的事件,没有则退出worker
- ngx_terminate 直接退出worker
- ngx_quit 关闭定时器、关闭socket监听、关闭闲置连接
- ngx_reopen rotate logs
缓存管理处理流程
备注:缓存分为manager和loader
- 设置进程类型为helper
- 关闭当前进程的socket监听
- 重置当前进程的最大连接数为512
- 初始化
- 设置进程执行优先级
- 设置进程可打开的最大文件描述符
- 如果以root身份启动进程则根据nginx.conf配置设置进程运行的用户、用户组
- 解除阻塞系统信号
- 执行各模块init_process
- 设置通道读事件回调
- 设置定时器
- 循环处理事件及定时器
- 从定时事件红黑树中查找出最近需要执行的定时器时间
- 执行各模块事件初始化
- 检查当前worker是否繁忙(todo),不繁忙则尝试获取事件监听锁(避免惊群效应),如果获取不到则退出本次处理,也可通过配置忽略锁
- 等待I/O事件唤起(如果超时仍未接收到事件则),保存I/O事件相关信息,将读写事件放入队列等待后续处理
- 处理accept事件中接收的post数据
- 释放事件监听锁(允许其他worker继续获取监听锁处理事件)
- 处理时间到达的定时器(manager目前ngx_http_file_cache_manager仅一个事件,主要用于清理过期的缓存文件;cache目前仅ngx_http_file_cache_loader一个事件,主要用于缓存数据到缓存文件和记录最新访问时间便于LRU)
- 处理普通事件(非accept事件)中接收的post数据
事件模块
加载流程
- ngx_init_cycle
- create_conf
- command->set
- init_conf
- init_module
- ngx_event_process_init
- init_event(actions.init)
- init_process(init_thread)
- add_event
- 事件唤起
- process_events
- event_handle
- ngx_worker_process_exit
- exit_process
- ngx_master_process_exit
- exit_master
主要函数解析
- 事件结构
static ngx_event_module_t ngx_kqueue_module_ctx = {
&kqueue_name,
ngx_kqueue_create_conf, /* create configuration */
ngx_kqueue_init_conf, /* init configuration */
{
ngx_kqueue_add_event, /* add an event */
ngx_kqueue_del_event, /* delete an event */
ngx_kqueue_add_event, /* enable an event */
ngx_kqueue_del_event, /* disable an event */
NULL, /* add an connection */
NULL, /* delete an connection */
#ifdef EVFILT_USER
ngx_kqueue_notify, /* trigger a notify */
#else
NULL, /* trigger a notify */
#endif
ngx_kqueue_process_events, /* process the events */
ngx_kqueue_init, /* init the events */
ngx_kqueue_done /* done the events */
}
};
- 模块结构
ngx_module_t ngx_event_core_module = {
NGX_MODULE_V1,
&ngx_event_core_module_ctx, /* module context */
ngx_event_core_commands, /* module directives */
NGX_EVENT_MODULE, /* module type */
NULL, /* init master */
ngx_event_module_init, /* init module */
ngx_event_process_init, /* init process */
NULL, /* init thread */
NULL, /* exit thread */
NULL, /* exit process */
NULL, /* exit master */
NGX_MODULE_V1_PADDING
};
- ngx_event_module_init
- 检查进程允许打开的最大文件描述符
- 分配进程间共享内存(空间=ngx_accept_mutex+ngx_connection_counter+ngx_temp_number[+ngx_stat_accepted+ngx_stat_handled+ngx_stat_requests+ngx_stat_active+ngx_stat_reading+ngx_stat_writing+ngx_stat_waiting])
- ngx_event_process_init
- 进程数设置大于1且配置开启竞争锁(默认禁用)则使用 accept 竞争锁
- ngx_posted_accept_events队列、ngx_posted_events队列、事件定时器、连接池 等资源初始化
- event_init
- 移除旧cycle事件
- 添加监听事件
- ngx_event_core_create_conf
- 对配置参数进行初始化
- ngx_event_core_init_conf
- 判断当前使用的I/O事件(epoll、devpoll、kqueue、select)
- 对部分未设置值的参数默认值
- ngx_event_accept
- 新增读事件
- 从等待连接的socket队列中获取第一个连接请求(非阻塞)
- 如果连接尚未准备就绪则直接返回
- 如果当前进程可用最大文件描述符超过限制则删除读事件,标记当前进程暂时停止接收新请求
- 重新计算当前进程的忙碌指数(ngx_cycle->connection_n / 8 - ngx_cycle->free_connection_n)
- 将socket信息保存至当前进程连接池中
- 设置I/O事件处理函数
- 监听函数处理(ngx_http_init_connection、ngx_mail_init_connection、ngx_stream_init_connection)
- ngx_trylock_accept_mutex
- 尝试获取共享accept锁
- 如果锁获取成功则添加accept事件
- 如果获取锁失败且成功添加过accept事件则移除accept事件
- ngx_event_connect_peer
- 从待连接池中(根据规则)获取一个可用的连接对象
- 创建空白socket
- 从连接池获取一个空闲的连接资源
- 设置socket为非阻塞
- 如果为 stream_proxy 则绑定本地端口
- 建立远端(upstream、proxy等)连接
- 添加读写事件
- ngx_event_pipe
- 从上游读取数据写入下游
- 为上游添加读事件,如果没有设置过读延迟标识项则添加或删除读超时定时器
- 为下游添加写事件,如果没有设置过写延迟标识项则添加或删除写超时定时器
- ngx_event_pipe_read_upstream
- 如果上游发生错误、读取完成或读事件尚未就绪则返回
- 如果为预读事件则从预读缓冲区获取数据
- 如果有配置带宽控制策略则计算当前是否超过限制(limit = limit_rate * (now_sec - start_sec + 1) - read_length),如超过则加入定时器延时读取
- 根据条件从各类管道缓冲区中选取合适的读取
- 对上游输入数据进行过滤(input_filter)
- 如果设置有缓存项则将读取的上游数据存储至临时文件中
- ngx_event_pipe_write_to_downstream
- 对将向下游数据输出及下游输入的数据进行过滤(output_filter)
- 如果循环池内的缓冲区占用大于所设置大小则输出数据
- 缓冲区资源回收
- 如果连续输出超过10次则返回系统繁忙
- 如果所有缓冲区数据均已输出则重置临时文件游标
- 将空闲的缓冲拷贝放回空闲缓冲区中
- ngx_event_recvmsg
- 如果事件已经到达执行时间则添加到accept事件
- 设置对应的消息控制器
- 从socket获取消息
- 如果尚未有任何消息到达则返回
- 如果消息有截断则循环多次获取
- 从消息中提取其他辅助信息(如socket的头字段、拓展的错误描述等)
- 查找连接是否已经存在udp连接池中,如果存在则执行事件的处理程序,否则将socket信息保存至当前进程udp连接池中再则执行事件的处理程序
- 计算当前进程的忙碌指数
- ngx_process_events_and_timers(详见:worker处理流程-循环处理事件及定时器)
- ngx_handle_write_event
- 如果有设置缓冲区最小发送值则添加设置到写socket(写入缓冲区的数据大小超过最小值后才将数据传到协议层)
- 根据事件标识和事件状态添加或移除对应写事件
配置
event
- worker_connections
- 配置块:events
- 值类型:uint
- 默认值:512
- 可选范围:1-[32位:2147483647;64位:9223372036854775807;select事件模型:FD_SETSIZE;同时受限于系统设置的单进程最大文件描述符,如果设置超过将忽略设置值]
- 说明:设置单worker可同时处理的最大连接数(包括接收的请求以及upstream之类对外的请求),已经在运行的nginx减小此值设置小于已经监听的连接数可能引发错误
- use
- 配置块:events
- 值类型:string
- 默认值:根据当前系统支持的I/O事件通知机制按先后顺序选择(epoll、/dev/poll、kqueue、select)
- 可选范围:epoll、/dev/poll、kqueue、select
- 说明:设置使用特定I/O事件通知机制,不同的事件通知机制可能影响程序运行效率;需在程序编译时加入对应可选参数以支持事件,否则无法设置
- multi_accept
- 配置块:events
- 值类型:string
- 默认值:0(off)
- 可选范围:on、off
- 说明:设置同一worker是否尽可能多的(在一次accept后继续)接收等待监听队列中的socket,如果程序使用kqueue事件机制强制关闭
- accept_mutex
- 配置块:events
- 值类型:string
- 默认值:0(off)
- 可选范围:on、off
- 说明:设置是否开启accept互斥锁,用于控制是否多个worker同时accept(避免惊群效应但是会降低一定效率,由于worker数一般与CPU核数一致进程数少影响较小故默认关闭),如果worker数小于等于1或Win32环境下强制关闭
- accept_mutex_delay
- 配置块:events
- 值类型:uint
- 默认值:500(毫秒)
- 可选范围:1-[32位:2147483647;64位:9223372036854775807;]
- 说明:设置accept互斥锁延迟时间,当某个worker超过文件最大描述符且未启用互斥锁时下一次尝试accept事件的等待时间,以及I/O事件的最大等待时间
- debug_connection
- 配置块:events
- 值类型:string
- 默认值:无
- 可选范围:
- 说明:设置开启debug日志的连接,需编译时开启debug参数方可设置生效
devpoll
- devpoll_changes
- devpoll_events
epoll
- epoll_events
- worker_aio_requests
eventport
- eventport_events
iocp
- iocp_threads
- post_acceptex
- acceptex_read
kqueue
- kqueue_changes
- kqueue_events
openssl
- ssl_engine
http服务
初始化流程
- create_main_conf
- create_srv_conf
- create_loc_conf
- preconfiguration
- init_main_conf
- merge_srv_conf
- merge_loc_conf
- ngx_http_init_static_location_trees
- ngx_http_init_phases
- postconfiguration
- ngx_http_optimize_servers
- 优化server信息列表
- 添加各server所需地址的监听
- 设置监听参数(如:backlog、reuseport等),并将监听处理器设置为ngx_http_init_connection
建立连接流程
- 查找请求对应的server配置
- 设置当前server的读控制器(根据配置可能为:ssl、http2、http)
- 如果读事件尚未准备就绪则将连接放回队列并添加读事件
- 如果读事件(数据)已经准备就绪则执行对应读控制器(对应https、http2、http)
https
- 尝试从socket中读取数据,没有则添加读事件后返回
- 创建ssl连接并和客户端完成握手,若尚未完成则返回等待下次处理
- 如果客户端使用的是http2协议则进入http2处理流程,否则进入http处理流程
http2
- 发送http2的headers frame
- 设置单个stream的流量控制
- 接收客户端请求数据
- 确认客户端请求数据包含http2连接序言,提取sid等信息并根据请求的frame类型调用对应处理方法
HEADERS frame处理
- 检查客户端发送的frame数据是否有错误(包括数据大小是否超过限制、当前处理中的请求是否超过限制等),有错误则发送中止stream推送信号或关闭连接返回错误
- 如果有设置优先级则根据权重及依赖流构建依赖树以确定每个流的发送次序
- 根据stream状态字段格式(压缩或者非压缩)处理状态值
- 如果状态字段未处理完成则继续处理CONTINUATION frame
- 处理header相关信息
- 检查cookie是否有变动,有则缓存cookie
- 进入请求处理流程
- 添加读事件
- 处理输出队列
- 处理已经建立的连接
- 如果输出缓冲区中有数据添加到输出队列中
- 如果请求尚未处理完成则返回继续处理
- 清理临时资源占用,将连接放回连接池中以待复用
- 添加连接闲置超时关闭事件
http
- 读取socket中已接收信息,如果信息尚未接收完成则添加读事件后返回
- 从复用连接池中移除当前连接
- 处理header相关信息(host合法性检查、解析uri、header数据是否超过大小限制等)
- 进入请求处理流程
- 添加输出写事件
请求处理流程
- 如果为https请求则检查客户端证书是否正确
- 执行各阶段检查器
NGX_HTTP_POST_READ_PHASE
读取请求内容阶段
- ngx_http_realip_handler
根据配置从请求header的x_real_ip、x_forwarded_for、代理请求来源IP或请求来源IP中获取客户端真实IP
NGX_HTTP_SERVER_REWRITE_PHASE
server级别的uri重写阶段
- ngx_http_rewrite_handler
根据rewrite命令(rewrite、return、break、if、set、rewrite_log、uninitialized_variable_warn)执行对应命令的方法(在ngx_http_rewrite_commands中映射)
NGX_HTTP_FIND_CONFIG_PHASE
寻找location配置阶段,该阶段使用重写之后的uri来查找对应的location,因为location级别可能有重写指令所以可能会被执行多次
- ngx_http_core_find_config_phase
- 不能添加外部检查器
- 优先静态location、后正则匹配location
- 检查客户端将要发送的body大小是否超过限制,超过则丢弃body数据结束请求
NGX_HTTP_REWRITE_PHASE
location级别的uri重写阶段,该阶段执行location基本的重写指令,也可能会被执行多次
- ngx_http_rewrite_handler
NGX_HTTP_POST_REWRITE_PHASE
location级别重写的最后处理阶段
- ngx_http_core_post_rewrite_phase
- 不能添加外部检查器
- 用来检查上阶段是否有uri重写,并根据结果跳转到合适的阶段
NGX_HTTP_PREACCESS_PHASE
访问权限控制的前一阶段,该阶段在权限控制阶段之前,一般用于访问控制
- ngx_http_degradation_handler
当可用内存低于配置阀值时提供降级处理方式(返回204或444 http状态码)
- ngx_http_limit_conn_handler
最大连接数限制
- ngx_http_limit_req_handler
请求频率限制
- ngx_http_realip_handler
NGX_HTTP_ACCESS_PHASE
访问权限控制阶段
- ngx_http_core_access_phase
根据配置综合其他权限控制阶段的结果决定是否拒绝访问
- ngx_http_access_handler
基于IP黑白名单权限控制
- ngx_http_auth_basic_handler
基于Basic的用户密码权限控制
- ngx_http_auth_request_handler
使用外部服务进行权限控制,当外部服务返回2xx时允许访问,当外部服务返回401或403则限制访问
NGX_HTTP_POST_ACCESS_PHASE
访问权限控制的最后处理阶段
- ngx_http_core_post_access_phase
- 不能添加外部检查器
- 根据权限控制阶段的执行结果进行相应处理
NGX_HTTP_PRECONTENT_PHASE
开始内容生成前的阶段
- ngx_http_mirror_handler
将当前接收到的请求镜像一份(创建一份相同的子请求)异步请求第三方服务,可用于流量放大压测、跨环境测试等,第三方服务的返回将被忽略
- ngx_http_try_files_handler
检查指定顺序的文件是否存在,并使用第一个找到的文件进行请求处理,如果未找到任何文件则内部重定向到最后一个参数指定的uri
NGX_HTTP_CONTENT_PHASE
内容生成阶段,该阶段产生响应,并发送到客户端
- ngx_http_core_content_phase
- 如果该请求对应location有设置内容控制器(如fastcgi、grpc、proxy等)则使用对应内容控制器生成内容,否则轮询其他内容生成阶段控制器
- 最终如果没有任何内容生成阶段控制器响应该请求则根据访问资源类型,目录访问返回失败(403),文件访问返回失败(404)
- ngx_http_autoindex_handler
处理以 '/' 结尾的GET、HEAD请求,并生成目录列表。 当ngx_http_index_module模块找不到索引文件时,通常会将请求传递给ngx_http_autoindex_module模块
- ngx_http_dav_handler
用于通过WebDAV协议进行文件管理,默认未编译该模块,需使用 --with-http_dav_module 编译启用
- ngx_http_gzip_static_handler
用于发送带有".gz"文件扩展名的预压缩文件,只处理GET、HEAD请求,默认未编译该模块,需使用 --with-http_gzip_static_module 编译启用
- ngx_http_index_handler
处理以 '/' 结尾的GET、POST、HEAD请求,可以触发内部重定向至其他location
- ngx_http_random_index_handler
处理以 '/' 结尾的GET、POST、HEAD请求,并在目录中选择一个随机文件作为索引文件,在ngx_http_index_module模块处理之前,默认未编译该模块,需使用 --with-http_random_index_module 编译启用
- ngx_http_static_handler
用于读取静态文件,只处理GET、POST、HEAD请求
NGX_HTTP_LOG_PHASE
日志记录阶段
- ngx_http_log_handler
- 不能添加外部检查器
- 记录访问日志
配置
http
- variables_hash_max_size
- 配置块:http
- 值类型:uint
- 默认值:1024
- 可选范围:1-[32位:2147483647;64位:9223372036854775807;]
- 说明:设置变量哈希表的最大大小
- variables_hash_bucket_size
- 配置块:http
- 值类型:uint
- 默认值:64
- 可选范围:1-[32位:2147483647;64位:9223372036854775807;]
- 说明:设置变量哈希表的桶大小
- server_names_hash_max_size
- 配置块:http
- 值类型:uint
- 默认值:512
- 可选范围:1-[32位:2147483647;64位:9223372036854775807;]
- 说明:设置服务器名称哈希表的最大大小
- server_names_hash_bucket_size
- 配置块:http
- 值类型:uint
- 默认值:ngx_cacheline_size
- 可选范围:1-[32位:2147483647;64位:9223372036854775807;]
- 说明:设置服务器名称哈希表的存储桶大小
- server
- 配置块:http
- 值类型:配置块
- 默认值:无
- 可选范围:无
- 说明:设置虚拟服务器的配置
- connection_pool_size
- 配置块:mainhttp、server
- 值类型:string
- 默认值:64 * 指针长度
- 可选范围:k、K、M、m
- 说明:精确调整每个连接的内存分配
- request_pool_size
- 配置块:http、server
- 值类型:string
- 默认值:4096
- 可选范围:k、K、M、m
- 说明:精确调整每个请求的内存分配
- client_header_timeout
- 配置块:http、server
- 值类型:time
- 默认值:60000
- 可选范围:y、M、w、d、h、m、s、ms,解析出的毫秒值 1-[32位:2147483647;64位:9223372036854775807;]
- 说明:设置读取客户端请求头信息的超时时间
- client_header_buffer_size
- 配置块:http、server
- 值类型:string
- 默认值:1024
- 可选范围:k、K、M、m
- 说明:设置缓冲区大小以读取客户端请求头信息,当请求头大于此值时将尝试使用large_client_header_buffers用以缓冲信息(但large_client_header_buffers的可用数量一般较小)
- large_client_header_buffers
- 配置块:http、server
- 值类型:uint size
- 默认值:4 8192
- 可选范围:1-[32位:2147483647;64位:9223372036854775807;];k、K、M、m
- 说明:设置用于读取客户端大请求头信息缓冲区的最大数量和大小
- ignore_invalid_headers
- 配置块:http、server
- 值类型:flag
- 默认值:1
- 可选范围:on、off
- 说明:控制是否应忽略具有无效名称的请求头字段(有效名称由英文字母、数字、连字符、下划线组成)
- merge_slashes
- 配置块:http、server
- 值类型:flag
- 默认值:1
- 可选范围:on、off
- 说明:设置是否将请求URI中重复的 '/' 压缩成单个
- underscores_in_headers
- 配置块:http、server
- 值类型:flag
- 默认值:0
- 可选范围:on、off
- 说明:设置是否禁用请求头中包含下划线字段的使用
- location
- 配置块:server
- 值类型:配置块
- 默认值:无
- 可选范围:无
- 说明:根据请求URI单独设置配置(支持正则)
- listen
- 配置块:http、server
- 值类型:string
- 默认值:*:80(以超级用户权限运行)、*:8000
- 可选范围:无
- 说明:设置监听请求的地址(IP、端口、Unix域套接字)
- server_name
- 配置块:http、server
- 值类型:string
- 默认值:""
- 可选范围:无
- 说明:设置虚拟服务器的名称(支持正则)
- types_hash_max_size
- 配置块:http、server、location
- 值类型:uint
- 默认值:1024
- 可选范围:1-[32位:2147483647;64位:9223372036854775807;]
- 说明:设置类型哈希表的最大大小
- types_hash_bucket_size
- 配置块:http、server、location
- 值类型:uint
- 默认值:64
- 可选范围:1-[32位:2147483647;64位:9223372036854775807;]
- 说明:设置类型哈希表的存储桶大小
- types
- 配置块:http、server、location
- 值类型:配置块
- 默认值:NULL
- 可选范围:无
- 说明:将文件扩展名映射到对应的MIME类型
- default_type
- 配置块:http、server、location
- 值类型:string
- 默认值:text/plain
- 可选范围:types中配置的映射
- 说明:定义默认响应的MIME类型
- root
- 配置块:http、server、location、location=>if
- 值类型:string
- 默认值:{ 0, NULL }
- 可选范围:无
- 说明:设置请求根目录
- alias
- 配置块:location
- 值类型:string
- 默认值:无
- 可选范围:无
- 说明:为特定location定义别名路径,如alias /www/www.mudoom.com/,uri为 mudoom.icon,则实际访问 /www/www.mudoom.com/mudoom.icon 资源
- limit_except
- 配置块:location
- 值类型:配置块
- 默认值:无
- 可选范围:无
- 说明:为特定location增加对某种HTTP请求方法的特殊限制,如限制GET请求只允许某些IP访问
- client_max_body_size
- 配置块:http、server、location
- 值类型:buf
- 默认值:1 1024 1024
- 可选范围:k、K、M、m、g、G
- 说明:设置客户端请求体的最大大小,Content-Length大于此值的请求将被拒绝,设为0则不限制大小
- client_body_buffer_size
- 配置块:http、server、location
- 值类型:size
- 默认值:2 * ngx_pagesize
- 可选范围:k、K、M、m、g、G
- 说明:设置客户端请求体的缓冲区大小
- client_body_timeout
- 配置块:http、server、location
- 值类型:time
- 默认值:60000
- 可选范围:y、M、w、d、h、m、s、ms,解析出的毫秒值 1-[32位:2147483647;64位:9223372036854775807;]
- 说明:设置读取客户端请求头信息的超时时间
- client_body_temp_path
- 配置块:http、server、location
- 值类型:string
- 默认值:NGX_HTTP_CLIENT_TEMP_PATH(编译时设置)
- 可选范围:无
- 说明:设置用于存储客户端请求信息的临时文件的目录
- client_body_in_file_only
- 配置块:http、server、location
- 值类型:flag
- 默认值:0
- 可选范围:on、clean、off
- 说明:设置是否将请求体保存至文件中,on为保存且请求结束后不删除临时文件,clean则在请求结束后删除临时文件
- client_body_in_single_buffer
- 配置块:http、server、location
- 值类型:flag
- 默认值:0
- 可选范围:on、off
- 说明:设置是否将整个客户端请求体保存在单个缓冲区中
- sendfile
- 配置块:http、server、location、location=>if
- 值类型:flag
- 默认值:0
- 可选范围:on、off
- 说明:设置是否使用sendfile发送文件数据
- sendfile_max_chunk
- 配置块:http、server、location
- 值类型:size
- 默认值:0
- 可选范围:k、K、M、m
- 说明:设置单个sendfile最大传输量,设置为0表示无限制,无限制的情况下一个快速连接可能导致整个worker进程被占用
- subrequest_output_buffer_size
- 配置块:http、server、location
- 值类型:size
- 默认值:ngx_pagesize
- 可选范围:k、K、M、m
- 说明:设置用于存储子请求输出缓冲区大小
- aio
- 配置块:http、server、location
- 值类型:flag|string
- 默认值:0
- 可选范围:on、off、threads[=pool](pool为所使用的线程池名称)
- 说明:设置是否启用异步I/O,仅在FreeBSD和Linux中生效,当在Linux上同时启用AIO和sendfile时,AIO用于大于或等于directio设置中指定大小的文件,而sendfile用于小于该大小的文件或禁用directio被禁用时。默认情况下程序只启用单线程异步I/O,如需启用多线程则在编译时添加参数 --with-threads ,仅在epoll、kqueue、eventport I/O事件类型中有效
- aio_write
- 配置块:http、server、location
- 值类型:flag
- 默认值:0
- 可选范围:on、off
- 说明:设置是否使用异步I/O写数据,需再aio开启下使用,且仅用于写入从代理服务模块接收的临时文件数据
- read_ahead
- 配置块:http、server、location
- 值类型:size
- 默认值:0
- 可选范围:k、K、M、m
- 说明:设置读取文件时内核的预读取量
- directio
- 配置块:http、server、location
- 值类型:flag|size
- 默认值:NGX_OPEN_FILE_DIRECTIO_OFF
- 可选范围:off、k、K、M、m
- 说明:设置使用异步I/O还是sendfile的临界点
- directio_alignment
- 配置块:http、server、location
- 值类型:size
- 默认值:512
- 可选范围:k、K、M、m
- 说明:设置directio的对齐大小,在Linux下使用XFS时,需要将其增加到4K
- tcp_nopush
- 配置块:http、server、location
- 值类型:flag
- 默认值:0
- 可选范围:on、off
- 说明:设置在socket中是否设置(Linux中)TCP_CORK或(FreeBSD中)TCP_NOPUSH参数,仅在sendfile开启有可用。该设置可能会导致数据不会立即发送给客户端,而是等待待发送数据长度超过设定值或手动取消阻塞后发送,可以有助于提高大数据量的发送效率
- tcp_nodelay
- 配置块:http、server、location
- 值类型:flag
- 默认值:1
- 可选范围:on、off
- 说明:设置在socket中是否设置TCP_NODELAY参数,仅在长连接、无缓冲代理、WebSocket代理中启用。该设置会立即将数据发送给客户端而无需等待到指定长度或时间,可以有助于提高小数据量的发送效率
- send_timeout
- 配置块:http、server、location
- 值类型:time
- 默认值:60000
- 可选范围:y、M、w、d、h、m、s、ms,解析出的毫秒值 1-[32位:2147483647;64位:9223372036854775807;]
- 说明:设置将响应数据发送给客户端的超时时间,该设置用于两次写操作时间的超时时间而非整个请求响应的时间,客户端在这个时间内如果未响应任何信息则连接将被关闭
- send_lowat
- 配置块:http、server、location
- 值类型:size
- 默认值:0
- 可选范围:k、K、M、m
- 说明:设置socket最小读写数据量,仅在kqueue I/O事件模型中生效。该设置会使内核在读、写缓冲区中数据量达到该值时才通知进程可读写,可以有助于内核唤起进程次数提高CPU利用率
- postpone_output
- 配置块:http、server、location
- 值类型:size
- 默认值:1460
- 可选范围:k、K、M、m
- 说明:设置向客户端传输响应数据的最小值,当请求未结束、程序未强制执行刷写指令且待传输数据大于该值时才开始向客户端传输响应数据
- limit_rate
- 配置块:http、server、location
- 值类型:size
- 默认值:0
- 可选范围:k、K、M、m
- 说明:设置向客户端每个连接传输响应数据的速率(bytes/second),为0时表示无限制
- limit_rate_after
- 配置块:http、server、location
- 值类型:size
- 默认值:0
- 可选范围:k、K、M、m
- 说明:设置初始无响应速率限制阀值,超过该值后开始按limit_rate限制
- keepalive_timeout
- 配置块:http、server、location
- 值类型:time [time]
- 默认值:75000
- 可选范围:y、M、w、d、h、m、s、ms,解析出的毫秒值 1-[32位:2147483647;64位:9223372036854775807;]
- 说明:第一个值用于控制程序长连接超时时间,第二个值用于向客户端响应的header中添加长连接超时时间,部分浏览器会根据该header控制长连接
- keepalive_requests
- 配置块:http、server、location
- 值类型:uint
- 默认值:100
- 可选范围:1-[32位:2147483647;64位:9223372036854775807;]
- 说明:设置一个长连接的最大请求数,当请求数超过该值则关闭该长连接
- keepalive_disable
- 配置块:http、server、location
- 值类型:string
- 默认值:NGX_CONF_BITMASK_SET | NGX_HTTP_KEEPALIVE_DISABLE_MSIE6
- 可选范围:user_agent中配置的映射
- 说明:设置在某些浏览器下禁用长连接
- satisfy
- 配置块:http、server、location
- 值类型:flag
- 默认值:0
- 可选范围:all、any
- 说明:设置访问权限控制中是满足任意模块还是满足所有模块才允许访问
- internal
- 配置块:location
- 值类型:无
- 默认值:0
- 可选范围:无
- 说明:设置特定location只允许内部(重定向)请求,其他请求均返回404,且每个请求最多允许10次(NGX_HTTP_MAX_URI_CHANGES)内部重定向
- lingering_close
- 配置块:http、server、location
- 值类型:flag
- 默认值:1
- 可选范围:on、off、always
- 说明:控制程序如何关闭客户端连接,on为如果客户端正在发送数据则等待数据接收完成后关闭连接,always为无条件等待指定时间(受lingering_time、lingering_timeout综合影响)后关闭连接,off为立即关闭连接
- lingering_time
- 配置块:http、server、location
- 值类型:time
- 默认值:30000
- 可选范围:y、M、w、d、h、m、s、ms,解析出的毫秒值 1-[32位:2147483647;64位:9223372036854775807;]
- 说明:设置延迟关闭客户端连接等待时间
- lingering_timeout
- 配置块:http、server、location
- 值类型:time
- 默认值:5000
- 可选范围:y、M、w、d、h、m、s、ms,解析出的毫秒值 1-[32位:2147483647;64位:9223372036854775807;]
- 说明:设置延迟关闭连接每次接收数据的超时时间(每次超时时间内接收到数据都将进入下一次超时计算,但最长不会超过lingering_time)
- reset_timedout_connection
- 配置块:http、server、location
- 值类型:flag
- 默认值:0
- 可选范围:on、off
- 说明:设置是否重置连接超时,在socket关闭后tcp将向客户端RST以引导客户端重新建立连接
- absolute_redirect
- 配置块:http、server、location
- 值类型:flag
- 默认值:1
- 可选范围:on、off
- 说明:设置是否为绝对(路径)重定向,on为绝对(路径)重定向,off为相对(路径)重定向
- server_name_in_redirect
- 配置块:http、server、location
- 值类型:flag
- 默认值:0
- 可选范围:on、off
- 说明:设置是否根据客户端请求的host返回重定向,on为使用实际请求host重定向,off为使用客户端请求host重定向
- port_in_redirect
- 配置块:http、server、location
- 值类型:flag
- 默认值:1
- 可选范围:on、off
- 说明:设置是否在绝对(路径)重定向中返回端口
- msie_padding
- 配置块:http、server、location
- 值类型:flag
- 默认值:1
- 可选范围:on、off
- 说明:设置是否向IE客户端请求http状态码大于400的响应中添加空白填充以达到512字节
- msie_refresh
- 配置块:http、server、location
- 值类型:flag
- 默认值:0
- 可选范围:on、off
- 说明:设置是否向IE客户端请求发送refreshes(而非重定向)命令
- log_not_found
- 配置块:http、server、location
- 值类型:flag
- 默认值:1
- 可选范围:on、off
- 说明:设置收否记录文件不存在错误日志
- log_subrequest
- 配置块:http、server、location
- 值类型:flag
- 默认值:0
- 可选范围:on、off
- 说明:设置收否记录子请求日志
- recursive_error_pages
- 配置块:http、server、location
- 值类型:flag
- 默认值:0
- 可选范围:on、off
- 说明:设置是否使用error_page重定向请求
- server_tokens
- 配置块:http、server、location
- 值类型:flag|string
- 默认值:1
- 可选范围:off、on、build
- 说明:设置是否在请求响应header中添加nginx版本号等信息
- if_modified_since
- 配置块:http、server、location
- 值类型:flag
- 默认值:1
- 可选范围:off、exact、before
- 说明:设置如何根据请求header中的If-Modified-Since响应请求,off为忽略请求头,exact为精确匹配,before为小于或等于
- max_ranges
- 配置块:http、server、location
- 值类型:uint
- 默认值:0x7fffffff
- 可选范围:1-[32位:2147483647;64位:9223372036854775807;]
- 说明:设置请求header中Ranges允许接收的最大值
- chunked_transfer_encoding
- 配置块:http、server、location
- 值类型:flag
- 默认值:1
- 可选范围:off、on
- 说明:设置禁用 HTTP/1.1 的数据分片传输
- etag
- 配置块:http、server、location
- 值类型:flag
- 默认值:1
- 可选范围:off、on
- 说明:设置是否自动在请求响应header中根据返回的静态文件类型添加ETag类型
- error_page
- 配置块:http、server、location
- 值类型:code uri
- 默认值:无
- 可选范围:无
- 说明:根据http错误码响应指定URI资源(可以为变量)
- post_action
- 配置块:http、server、location
- 值类型:string
- 默认值:{ 0, NULL }
- 可选范围:无
- 说明:内容生成阶段结束后程序将请求内部重定向至指定的location处理(可用于请求统计之类用途)
- error_log
- 配置块:http、server、location
- 值类型:file level
- 默认值:logs/error.log error
- 可选范围:无
- 说明:设置日志记录路径
- open_file_cache
- 配置块:http、server、location
- 值类型:flag
- 默认值:NULL
- 可选范围:off、max、inactive
- 说明:设置文件(读取时)信息缓存,off关闭缓存,max设置最大缓存数,inactive设置缓存过期时间
- open_file_cache_valid
- 配置块:http、server、location
- 值类型:time
- 默认值:60(秒)
- 可选范围:解析出的毫秒值 1-[32位:2147483647;64位:9223372036854775807;]
- 说明:设置文件信息缓存后再次验证文件信息的时间
- open_file_cache_min_uses
- 配置块:http、server、location
- 值类型:uint
- 默认值:1
- 可选范围:1-[32位:2147483647;64位:9223372036854775807;]
- 说明:设置文件描述符保存进文件信息缓存的最小访问次数
- open_file_cache_errors
- 配置块:http、server、location
- 值类型:flag
- 默认值:0
- 可选范围:on、off
- 说明:设置是否保存文件访问错误进文件信息缓存
- open_file_cache_events
- 配置块:http、server、location
- 值类型:flag
- 默认值:0
- 可选范围:on、off
- 说明:暂未发现使用用途
- resolver
- 配置块:http、server、location
- 值类型:address ... [valid=time] [ipv6=on|off]
- 默认值:创建虚拟解析器
- 可选范围:无
- 说明:配置特定的DNS服务作为解析
- resolver_timeout
- 配置块:http、server、location
- 值类型:time
- 默认值:30000
- 可选范围:y、M、w、d、h、m、s、ms,解析出的毫秒值 1-[32位:2147483647;64位:9223372036854775807;]
- 说明:设置DNS解析超时时间
- disable_symlinks
- 配置块:http、server、location
- 值类型:flag
- 默认值:0
- 可选范围:off、on
- 说明:是否禁用符号连接类资源
http状态码
- 100
NGX_HTTP_CONTINUE目前为止一切正常, 客户端应该继续请求, 如果已完成请求则忽略。程序中定义未使用
- 101
NGX_HTTP_SWITCHING_PROTOCOLS服务器应客户端升级协议的请求(Upgrade请求头)正在进行协议切换。程序中proxy、uwsgi、scgi模块将进行协议切换(http2目前不支持该协议协商只支持指定协议请求)
- 102
NGX_HTTP_PROCESSING非通用协议,程序中定义未使用
- 200
NGX_HTTP_OK请求成功
- 201
NGX_HTTP_CREATED请求已经被成功处理,并且创建了新的资源。WebDAV模块中使用,表示(move、overwrite)文件或集合(mkcol)创建成功
- 202
NGX_HTTP_ACCEPTED服务器端已经收到请求消息,但是尚未进行处理。程序中定义未使用
- 204
NGX_HTTP_NO_CONTENT目前请求成功,但客户端不需要更新其现有页面。
- 206
NGX_HTTP_PARTIAL_CONTENT请求已成功,并且主体包含所请求的数据区间,该数据区间是在请求的 Range 首部指定的。
- 300
NGX_HTTP_SPECIAL_RESPONSE表示重定向的响应状态码,表示该请求拥有多种可能的响应。用户代理或者用户自身应该从中选择一个。程序中作为特殊响应码的分界值
- 301
NGX_HTTP_MOVED_PERMANENTLY被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个 URI 之一。
- 302
NGX_HTTP_MOVED_TEMPORARILY请求的资源现在临时从不同的 URI 响应请求。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。
- 303
NGX_HTTP_SEE_OTHER对应当前请求的响应可以在另一个 URI 上被找到,而且客户端应当采用 GET 的方式访问那个资源。程序定义未使用
- 304
NGX_HTTP_NOT_MODIFIED如果客户端发送了一个带条件的 GET 请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个状态码。
- 307
NGX_HTTP_TEMPORARY_REDIRECT请求的资源现在临时从不同的URI 响应请求。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。程序定义未使用
- 308
NGX_HTTP_PERMANENT_REDIRECT这意味着资源现在永久位于由 Location: HTTP Response 标头指定的另一个 URI。程序定义未使用
- 400
NGX_HTTP_BAD_REQUEST语义有误,当前请求无法被服务器理解。客户端请求信息有误或请求host不存在
- 401
NGX_HTTP_UNAUTHORIZED当前请求需要用户验证。该响应必须包含一个适用于被请求资源的 WWW-Authenticate 信息头用以询问用户信息。auth_basic模块权限校验失败或upstream上游返回
- 403
NGX_HTTP_FORBIDDEN服务器已经理解请求,但是拒绝执行它。访问权限控制阶段被限制、请求的资源无读取权限、upstream上游返回
- 404
NGX_HTTP_NOT_FOUND请求失败,请求所希望得到的资源未被在服务器上发现。
- 405
NGX_HTTP_NOT_ALLOWED请求行中指定的请求方法不能被用于请求相应的资源。
- 408
NGX_HTTP_REQUEST_TIME_OUT请求超时。接收客户端请求数据超时(客户端指定的Content-Length在指定时间内未能接收完成)
- 409
NGX_HTTP_CONFLICT由于和被请求的资源的当前状态之间存在冲突,请求无法完成。WebDAV模块中部分请求操作失败
- 411
NGX_HTTP_LENGTH_REQUIRED服务器拒绝在没有定义 Content-Length 头的情况下接受请求。程序定义未使用
- 412
NGX_HTTP_PRECONDITION_FAILED服务器在验证在请求的头字段中给出先决条件时,没能满足其中的一个或多个。WebDAV模块中overwrite发生错误或not_modified模块中客户端请求的判断条件没有满足
- 413
NGX_HTTP_REQUEST_ENTITY_TOO_LARGE服务器拒绝处理当前请求,因为该请求提交的实体数据大小超过了服务器愿意或者能够处理的范围。
- 414
NGX_HTTP_REQUEST_URI_TOO_LARGE请求的URI 长度超过了服务器能够解释的长度,因此服务器拒绝对该请求提供服务。
- 415
NGX_HTTP_UNSUPPORTED_MEDIA_TYPE对于当前请求的方法和所请求的资源,请求中提交的实体并不是服务器中所支持的格式,因此请求被拒绝。客户端请求时使用请求体访问WebDAV模块部分方法或image_filter模块中图片资源数据异常
- 416
NGX_HTTP_RANGE_NOT_SATISFIABLE如果请求中包含了 Range 请求头,并且 Range 中指定的任何数据范围都与当前资源的可用范围不重合,同时请求中又没有定义 If-Range 请求头,那么服务器就应当返回416状态码。客户端请求header中的Range不合法(格式不正确)
- 421
NGX_HTTP_MISDIRECTED_REQUEST该请求针对的是无法产生响应的服务器。 客户端尝试https请求的host于server配置中host不一致
- 429
NGX_HTTP_TOO_MANY_REQUESTS用户在给定的时间内请求过于频繁。upstream模块中根据上游服务的返回而返回
- 444
NGX_HTTP_CLOSE非通用协议。程序定义未使用
- 494
NGX_HTTP_NGINX_CODES非通用协议。程序定义未使用
NGX_HTTP_REQUEST_HEADER_TOO_LARGE
非通用协议。客户端请求header过大(large_header_buf已被分配完或者请求大于headerlarge_header_buf)
- 495
NGX_HTTPS_CERT_ERROR非通用协议。客户端以https协议请求但是程序对客户端证书校验失败
- 496
NGX_HTTPS_NO_CERT非通用协议。客户端以https协议请求但是对应的server块未配置证书信息
- 497
NGX_HTTP_TO_HTTPS非通用协议。客户端以https协议请求但是对应的server块未开启ssl
- 499
NGX_HTTP_CLIENT_CLOSED_REQUEST非通用协议。客户端在程序响应前断开了连接
- 500
NGX_HTTP_INTERNAL_SERVER_ERROR服务器遇到了不知道如何处理的情况。程序发生内部错误(如配置错误、重定向错误等)时使用
- 501
NGX_HTTP_NOT_IMPLEMENTED此请求方法不被服务器支持且无法被处理。WebDAV模块客户端PUT请求header中使用Range、http客户端请求header中的Transfer-Encoding无法识别时使用
- 502
NGX_HTTP_BAD_GATEWAY此错误响应表明服务器作为网关需要得到一个处理这个请求的响应,但是得到一个错误的响应。upstream模块中上游服务响应错误时使用
- 503
NGX_HTTP_SERVICE_UNAVAILABLE服务器没有准备好处理请求。 limit_conn(触发请求数限制)、limit_req(触发速率限制)、upstream模块中使用
- 504
NGX_HTTP_GATEWAY_TIME_OUT当服务器作为网关,不能及时得到响应时返回此错误代码。upstream模块中上游服务响应超时时使用
- 505
NGX_HTTP_VERSION_NOT_SUPPORTED服务器不支持请求中所使用的HTTP协议版本。
- 507
NGX_HTTP_INSUFFICIENT_STORAGE服务器有内部配置错误。WebDAV模块中发生NGX_ENOSPC错误时使用
mail服务
初始化流程
- create_main_conf
- create_srv_conf
- init_main_conf
- merge_srv_conf
- ngx_mail_add_ports
- ngx_mail_optimize_servers
- 优化监听列表,如果相同端口有泛IP监听则忽略其他指定IP地址的监听
- 添加各server所需地址的监听
- 设置监听参数(如:backlog、rcvbuf等),并将监听处理器设置为ngx_mail_init_connection
建立连接流程
- 查找请求对应的server配置(根据server配置可确定当前请求对应的mail协议)
- 设置当前server的读控制器(根据配置可能为:ssl、非ssl)
- 执行对应读控制器(对应ssl、非ssl)
ssl
- 创建ssl连接并和客户端完成握手,若尚未完成则添加超时定时器后返回等待下次处理
- 检查客户端证书
- 如果当前server配置中的STARTTLS命令未关闭则执行对应协议(imap、pop3、smtp)的init_protocol方法后返回
- 否则进入session初始化流程
非ssl
- 进入session初始化流程
session初始化流程
- imap
- 添加读(ngx_mail_imap_init_protocol)写(ngx_mail_send)事件
- pop3
- 如果server配置有apop、cram-md5两种身份验证方式则为请求输出加盐(避免暴露破解)
- 添加读(ngx_mail_imap_init_protocol)写(ngx_mail_send)事件
- smtp
- 添加读(ngx_mail_imap_init_protocol)写(ngx_mail_send)事件
协议初始化
- 检查请求是否超时,超时则关闭连接
- 创建临时缓冲区
- 读取客户端请求命令(一次无法读取完则添加读事件返回等待下次处理)
- 如果客户端发送命令数据过大则退出本次请求
- 解析客户端请求命令并根据命令提取相应鉴权验证信息
- 将授权验证信息发送至上游身份验证服务(根据auth_http配置)
- 检查上游身份验证服务的返回结果,如果失败则根据配置绝对是否返回错误信息给客户端,否则将严重服务器身份验证服务返回的邮件服务地址及授权信息(授权密钥)存储于输出缓冲区
- 如果输出缓冲区存在数据则向客户端发送数据
stream服务
初始化流程
- create_main_conf
- create_srv_conf
- preconfiguration
- init_main_conf
- merge_srv_conf
- postconfiguration
- ngx_stream_init_phase_handlers
初始化个请求阶段处理控制器
- ngx_stream_add_ports
- ngx_stream_optimize_servers
- 优化监听列表,如果相同端口有泛IP监听则忽略其他指定IP地址的监听
- 添加各server所需地址的监听
- 设置监听参数(如:backlog、keepalive等)
建立连接流程
- 查找请求对应的server配置
- 如果有配置使用accept互斥锁则将读事件添加到普通事件(非accept事件)队列中
- 进入请求处理流程
请求处理流程
NGX_STREAM_POST_ACCEPT_PHASE
读取请求内容阶段
- ngx_stream_realip_handler
获取客户端真实IP
NGX_STREAM_PREACCESS_PHASE
访问权限控制的前一阶段,该阶段在权限控制阶段之前,一般用于访问控制
- ngx_stream_limit_conn_handler
最大连接数限制
NGX_STREAM_ACCESS_PHASE
访问权限控制阶段
- ngx_stream_access_handler
基于IP黑白名单权限控制
NGX_STREAM_SSL_PHASE
访问建立ssl阶段
- ngx_stream_ssl_handler
建立ssl连接
NGX_STREAM_PREREAD_PHASE
请求数据预读阶段
- ngx_stream_core_preread_phase
- 创建临时缓冲区
- 读取客户端请求数据
- 如果客户端数据请求尚未接收完成则添加读事件后返回等待下次处理
- ngx_stream_ssl_preread_handler
读取SSL请求数据
NGX_STREAM_CONTENT_PHASE
内容生成阶段,该阶段产生响应,并发送到客户端
- ngx_stream_core_content_phase
- 转发客户端请求至对应上游服务,并将上游服务的响应返回给客户端
NGX_STREAM_LOG_PHASE
日志记录阶段
- ngx_stream_log_handler
- 不能添加外部检查器
- 记录访问日志
参考文档
- Nginx开发从入门到精通
- CPU缓存 - 维基百科
- Page (computer memory))
- OpenEvent
- Linux管道编程技术:dup函数,dup2函数,open函数详解
- Nginx Caching
- 红黑树
- nginx documentation
- Hypertext Transfer Protocol Version 2 (HTTP/2)
- HTTP 响应代码
- Configuring NGINX as a Mail Proxy Server
源地址 By佐柱
转载请注明出处,也欢迎偶尔逛逛我的小站,谢谢 :)