1. 代码目录结构
auto/ # 编译脚本
src/
core/ # 基础类型与函数:字符串、数组、日志、内存池等
event/ # 事件驱动核心
modules/ # 事件通知实现:epoll、kqueue、select 等
http/ # HTTP 核心模块与公共代码
modules/ # 其他 HTTP 模块
v2/ # HTTP/2 支持
mail/ # Mail 模块
os/ # 平台相关代码
unix/
win32/
stream/ # Stream 模块
include/ # 头文件
每个源文件开头必须包含:
#include <ngx_config.h>
#include <ngx_core.h>
HTTP 相关还需:
#include <ngx_http.h>
Mail 相关:
#include <ngx_mail.h>
Stream 相关:
#include <ngx_stream.h>
2. 基础类型与宏
整数类型
ngx_int_t
与ngx_uint_t
分别对应intptr_t
与uintptr_t
。
通用返回码
宏 | 含义 |
---|---|
NGX_OK | 成功 |
NGX_ERROR | 失败 |
NGX_AGAIN | 操作未完成,需要重试 |
NGX_DECLINED | 操作被拒绝(非错误,如配置禁用) |
NGX_BUSY | 资源不可用 |
NGX_DONE | 操作完成或在其他地方继续,也可做成功替代码 |
NGX_ABORT | 操作中止,也可做失败替代码 |
错误处理
ngx_errno
/ngx_socket_errno
获取最近系统或 socket 错误。- 使用
ngx_set_errno()
/ngx_set_socket_errno()
设置错误。 - 错误可传入
ngx_log_error()
添加系统错误文本。
ngx_int_t ngx_my_kill(ngx_pid_t pid, ngx_log_t *log, int signo) {
ngx_err_t err;
if (kill(pid, signo) == -1) {
err = ngx_errno;
ngx_log_error(NGX_LOG_ALERT, log, err,
"kill(%P, %d) failed", pid, signo);
if (err == NGX_ESRCH) return 2;
return 1;
}
return 0;
}
3. 字符串处理
ngx_str_t 定义
typedef struct {
size_t len;
u_char *data;
} ngx_str_t;
len
字符长度;data
指向字符数组。(通常非 null 终止)
常用字符串函数
包装标准 C 接口:
ngx_strcmp, ngx_strncmp, ngx_strstr, ngx_strlen,
ngx_strchr, ngx_memcmp, ngx_memset, ngx_memcpy, ngx_memmove
Nginx 专用:
ngx_memzero, ngx_explicit_memzero, ngx_cpymem, ngx_movemem,
ngx_strlchr, ngx_strlow, ngx_strcasecmp, ngx_strncasecmp
初始化宏:
ngx_string(text), ngx_null_string,
ngx_str_set(str, text), ngx_str_null(str)
格式化与数字转换
ngx_sprintf
,ngx_snprintf
,ngx_slprintf
,ngx_vslprintf
,ngx_vsnprintf
支持%O, %T, %z, %i, %p, %V, %s, %*s
等。- 数字转换:
ngx_atoi
,ngx_atosz
,ngx_atoof
,ngx_atotm
,ngx_atofp
,ngx_hextoi
。
4. 正则表达式接口
基于 PCRE,头文件:
#include <src/core/ngx_regex.h>
编译时需宏保护:
#if (NGX_PCRE)
ngx_regex_compile_t rc;
rc.pattern = ngx_string("(\d+)");
rc.pool = cf->pool;
if (ngx_regex_compile(&rc) != NGX_OK) {
ngx_conf_log_error(...); return NGX_CONF_ERROR;
}
ngx_regex_exec(rc.regex, &input, captures, size);
#endif
5. 时间与定时器
ngx_time_t
、ngx_tm_t
(映射struct tm
/SYSTEMTIME
)- 缓存时间变量:
ngx_cached_err_log_time
,ngx_cached_http_log_time
,ngx_cached_syslog_time
,ngx_cached_http_time
,ngx_cached_http_log_iso8601
- 获取时间:
ngx_time()
,ngx_timeofday()
,ngx_gettimeofday()
,ngx_time_update()
- 时间转换:
ngx_gmtime()
,ngx_libc_gmtime()
,ngx_localtime()
,ngx_libc_localtime()
,ngx_http_time()
,ngx_http_cookie_time()
6. 容器类型
数组 (ngx_array_t)
typedef struct {
void *elts; // 元素起始地址
ngx_uint_t nelts; // 元素数量
size_t size; // 元素大小
ngx_uint_t nalloc; // 分配容量
ngx_pool_t *pool;
} ngx_array_t;
- 创建:
ngx_array_create(pool, n, size)
- 添加:
ngx_array_push(a)
/ngx_array_push_n(a, n)
列表 (ngx_list_t)
typedef struct {
ngx_list_part_t *last;
ngx_list_part_t part;
size_t size;
ngx_uint_t nalloc;
ngx_pool_t *pool;
} ngx_list_t;
ngx_list_create
,ngx_list_init
,ngx_list_push
, 迭代…
队列 (ngx_queue_t)
双向链表,入队/出队:
ngx_queue_init, ngx_queue_insert_head/tail,
ngx_queue_remove, ngx_queue_split, ngx_queue_add,
ngx_queue_head, ngx_queue_last, ngx_queue_data
红黑树 (ngx_rbtree_t)
#include <src/core/ngx_rbtree.h>
ngx_rbtree_init
,ngx_rbtree_insert
,ngx_rbtree_delete
。
哈希表 (ngx_hash_t)
#include <src/core/ngx_hash.h>
- 先收集 keys:
ngx_hash_keys_array_init
,ngx_hash_add_key
;再构建ngx_hash_init
;查找ngx_hash_find
。 - 支持通配符:
ngx_hash_combined_t
,NGX_HASH_WILDCARD_KEY
,ngx_hash_wildcard_init
,ngx_hash_find_combined
。
7. 内存管理
堆分配
ngx_alloc, ngx_calloc, ngx_memalign, ngx_free
内存池 (ngx_pool_t)
ngx_create_pool, ngx_destroy_pool,
ngx_palloc, ngx_pcalloc, ngx_pnalloc, ngx_pfree
- 支持链路复用:
ngx_alloc_chain_link
,ngx_free_chain
- 清理回调:
ngx_pool_cleanup_add
共享内存
ngx_shared_memory_add -> ngx_shm_zone_t
- 基于 mmap / CreateFileMapping
- slab 池:
ngx_slab_pool_t
,ngx_slab_alloc
,ngx_slab_calloc
,ngx_slab_free
- 并行安全:
ngx_shmtx_lock
,ngx_shmtx_unlock
8. 日志系统
ngx_log_t
,支持 stderr、file、syslog、memory。- 严重级别:
NGX_LOG_EMERG
,NGX_LOG_ALERT
, …,NGX_LOG_DEBUG
- 调试掩码:
NGX_LOG_DEBUG_CORE
,NGX_LOG_DEBUG_ALLOC
, … - 宏:
ngx_log_error
,ngx_log_debug0~8
9. Nginx 周期与多进程模型
ngx_cycle_t
存储运行时上下文- 进程类型:Master / Worker / Single / Helper
- 信号:QUIT/SIGTERM/SIGWINCH/SIGHUP/SIGUSR1/SIGUSR2
- Master 进程通过 socketpair 下发信号给子进程
10. 事件驱动与网络 I/O
事件对象 (ngx_event_t)
字段:data
, handler
, write
, active
, ready
, timer
, timedout
, posted
…
I/O 事件处理
ngx_get_connection
->c->read
,c->write
- Edge-Triggered 模式统一
- 需调用:
ngx_handle_read_event
,ngx_handle_write_event
定时器事件
ngx_add_timer(ev, msec)
,ngx_del_timer(ev)
- 全局红黑树:
ngx_event_timer_rbtree
发布事件
ngx_post_event(ev, q)
,ngx_delete_posted_event
->ngx_event_process_posted
事件循环
ngx_event_find_timer
- I/O 等待与处理
- 过期定时器处理
- 发布事件处理
11. 进程与信号
- Master/Worker/Helper
- 通过 ngx_process 记录类型
- 各类信号及处理流程
12. 异步线程池
ngx_thread_mutex_t
,ngx_thread_cond_t
- 线程池:
ngx_thread_pool_t
- 任务:
ngx_thread_task_t
,ngx_thread_task_post
13. 模块开发框架
目录与配置文件
- 每个模块自成目录,需
config
脚本和源码 config
设置变量:ngx_module_type
,ngx_module_name
,ngx_module_srcs
, …--add-module
/--add-dynamic-module
ngx_module_t 与生命周期
struct ngx_module_s {
void *ctx;
ngx_command_t *commands;
ngx_uint_t type;
ngx_int_t (*init_master)(ngx_log_t*);
ngx_int_t (*init_module)(ngx_cycle_t*);
ngx_int_t (*init_process)(ngx_cycle_t*);
// ... exit thread/process/master
};
配置指令 ngx_command_t
struct ngx_command_s {
ngx_str_t name;
ngx_uint_t type;
char *(*set)(ngx_conf_t*, ngx_command_t*, void*);
ngx_uint_t conf;
ngx_uint_t offset;
void *post;
};
- 支持
NGX_CONF_TAKE1..7
,NGX_CONF_BLOCK
,NGX_CONF_FLAG
, context 标志等 - 常用 handler:
ngx_conf_set_flag_slot
,_set_str_slot
,_set_num_slot
,_set_size_slot
,_set_keyval_slot
,_set_enum_slot
,_set_bitmask_slot
…
14. HTTP 核心流程
连接 & 请求处理
ngx_event_accept
->ngx_http_init_connection
ngx_http_wait_request_handler
ngx_http_process_request_line
(解析请求行)ngx_http_process_request_headers
ngx_http_core_run_phases
ngx_http_finalize_request
ngx_http_finalize_connection
请求对象 ngx_http_request_t
字段:connection
, ctx
, main_conf
, srv_conf
, loc_conf
, pool
, headers_in/out
, uri
, args
, method
, http_version
, phase_handler
, subrequests
, count
, …
相位处理链
POST_READ -> SERVER_REWRITE -> FIND_CONFIG -> REWRITE -> POST_REWRITE -> PREACCESS -> ACCESS -> POST_ACCESS -> PRECONTENT -> CONTENT -> LOG
- Handler 返回:
NGX_OK
,NGX_DECLINED
,NGX_AGAIN
,NGX_DONE
, 或 HTTP 状态码
变量与复杂值
ngx_http_variable_value_t
表示变量值- 获取:
ngx_http_get_indexed_variable
,_get_flushed_variable
,_get_variable
- 添加:
ngx_http_add_variable
- 复杂值编译:
ngx_http_compile_complex_value
,运行时:ngx_http_complex_value
重定向与子请求
- 内部重定向:
ngx_http_internal_redirect
- 命名位置:
ngx_http_named_location
- 子请求:
ngx_http_subrequest
,post_subrequest
回调
请求体处理
- 读取/丢弃:
ngx_http_read_client_request_body
,ngx_http_discard_request_body
- 无缓冲:
ngx_http_read_unbuffered_request_body
- 过滤链:
ngx_http_top_request_body_filter
响应头 & 体
- 发送头:
ngx_http_send_header
->ngx_http_top_header_filter
- Body 输出:
ngx_http_output_filter
->ngx_http_top_body_filter
15. 负载均衡与上游模块
ngx_http_upstream_module
提供通用上游支持ngx_http_upstream_srv_conf_t
配置上下文- 算法钩子:
init_upstream
,init_peer
->get
,free
,notify
,set_session
,save_session
16. 代码风格与常见陷阱
-
风格:80 列、4 空格缩进、无制表符与行尾空格、对齐声明、结构清晰、函数原型、注释风格、宏命名等。
-
陷阱:
- 尽量避免全局变量
- 使用内存池而非 malloc/free
- 模块要尽量小
- 异步与非阻塞
- HTTP 调用请使用子请求或内置客户端,不要引入 libcurl 等阻塞库