<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>wy471x</title>
  <link href="https://wy471x.github.io/feed.xml" rel="self"/>
  <link href="https://wy471x.github.io"/>
  <updated>2026-07-24T00:13:25+08:00</updated>
  <id>https://wy471x.github.io</id>
  <author>
    <name>wy471x</name>
    <email>wy471x@gmail.com</email>
  </author>
  
  <entry>
    <title>Nginx 源码阅读指南</title>
    <link href="https://wy471x.github.io/2026-07-23/nginx-source-code-guide.html"/>
    <updated>2026-07-23T23:45:00+08:00</updated>
    <id>https://wy471x.github.io/2026-07-23/nginx-source-code-guide.html</id>
    <content type="html">&lt;h1 id=&quot;nginx-源码阅读指南&quot;&gt;Nginx 源码阅读指南&lt;/h1&gt;

&lt;h2 id=&quot;一读前准备&quot;&gt;一、读前准备&lt;/h2&gt;

&lt;h3 id=&quot;11-必备知识&quot;&gt;1.1 必备知识&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;C 语言&lt;/strong&gt;：熟悉指针、函数指针、宏、位运算、结构体内存布局（&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;offsetof&lt;/code&gt;）、变长参数&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;网络编程&lt;/strong&gt;：TCP/IP、HTTP/1.1 协议、socket API（&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;accept&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;recv&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;send&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setsockopt&lt;/code&gt;）、非阻塞 I/O&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;操作系统&lt;/strong&gt;：进程模型（fork）、信号（signal）、共享内存、epoll/kqueue 等多路复用机制&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;编译工具&lt;/strong&gt;：能读懂 shell 脚本和 Makefile&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;12-环境搭建&quot;&gt;1.2 环境搭建&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# 编译带调试信息的 nginx&lt;/span&gt;
./auto/configure &lt;span class=&quot;nt&quot;&gt;--with-debug&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--prefix&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;pwd&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;/build
make &lt;span class=&quot;nt&quot;&gt;-j&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;nproc&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# 用 GDB 调试&lt;/span&gt;
gdb ./objs/nginx
&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;gdb&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; b ngx_process_events_and_timers
&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;gdb&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; r
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;13-关键宏与惯例速查&quot;&gt;1.3 关键宏与惯例速查&lt;/h3&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;宏/模式&lt;/th&gt;
      &lt;th&gt;含义&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NGX_OK&lt;/code&gt; / &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NGX_ERROR&lt;/code&gt; / &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NGX_AGAIN&lt;/code&gt; / &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NGX_DECLINED&lt;/code&gt; / &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NGX_DONE&lt;/code&gt; / &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NGX_BUSY&lt;/code&gt; / &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NGX_ABORT&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;标准返回值，分别对应 0/-1/-2/-5/-4/-3/-6&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_string(&quot;foo&quot;)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;编译期从字面量构造 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_str_t&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_queue_data(q, type, link)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;从侵入式队列节点反查包含它的结构体&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_rbtree_data(node, type, link)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;同上，针对红黑树节点&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_log_debug&lt;/code&gt; / &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_log_error&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;分级日志宏，带 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--with-debug&lt;/code&gt; 才会输出 debug 级别&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;offsetof(type, member)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;计算成员在结构体中的偏移量，侵入式数据结构的基石&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;二推荐阅读路线&quot;&gt;二、推荐阅读路线&lt;/h2&gt;

&lt;h3 id=&quot;第-0-步理解构建系统30-分钟&quot;&gt;第 0 步：理解构建系统（30 分钟）&lt;/h3&gt;

&lt;p&gt;从 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto/&lt;/code&gt; 目录开始，不必细读每个脚本，重点是理解流程：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto/configure&lt;/code&gt;&lt;/strong&gt; — 入口，顺序调用 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto/options&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto/init&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto/cc/*&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto/os/*&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto/feature&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto/modules&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto/sources&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto/make&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto/modules&lt;/code&gt;&lt;/strong&gt; — 最关键的文件之一。它决定哪些模块被编译进 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_modules[]&lt;/code&gt; 数组，&lt;strong&gt;模块的排列顺序决定了初始化顺序和处理优先级，不可随意改动&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto/sources&lt;/code&gt;&lt;/strong&gt; — 定义了所有源文件列表的 shell 变量（&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CORE_SRCS&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HTTP_SRCS&lt;/code&gt; 等），最终输出到 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;objs/Makefile&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;构建产物：&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;objs/ngx_auto_config.h&lt;/code&gt; — 所有 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#define&lt;/code&gt; 宏（编译特性开关）&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;objs/ngx_modules.c&lt;/code&gt; — 自动生成的 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_modules[]&lt;/code&gt; 和 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_module_names[]&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;第-1-步核心数据结构2-3-小时&quot;&gt;第 1 步：核心数据结构（2-3 小时）&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;这是最重要的基础，务必吃透。&lt;/strong&gt; 按依赖关系建议顺序：&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ngx_str_t  →  ngx_pool_t  →  ngx_array_t  →  ngx_list_t  →  ngx_queue_t  →  ngx_buf_t / ngx_chain_t  →  ngx_rbtree_t
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;逐个阅读文件：&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;阅读文件&lt;/th&gt;
      &lt;th&gt;重点理解&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_string.h&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_str_t&lt;/code&gt; 不是 C 字符串，&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;len&lt;/code&gt; + &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data&lt;/code&gt; 二元组；&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_vslprintf&lt;/code&gt; 等格式化函数&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_palloc.h&lt;/code&gt; + &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_palloc.c&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;池分配器：小块从池中切，大块走 malloc；&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_palloc&lt;/code&gt; vs &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_pnalloc&lt;/code&gt;（对齐 vs 不对齐）；cleanup 回调机制&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_array.h&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;动态数组，元素连续存储，&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_array_push&lt;/code&gt; 返回新元素的指针&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_list.h&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;链表+数组的混合体，每个 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;part&lt;/code&gt; 存放 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nalloc&lt;/code&gt; 个元素&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_queue.h&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;纯粹的宏&lt;/strong&gt;，侵入式双向循环链表，核心宏 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_queue_data&lt;/code&gt; 用 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;offsetof&lt;/code&gt; 反查容器&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_buf.h&lt;/code&gt; + &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_buf.c&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_buf_t&lt;/code&gt; 统一了内存数据和文件数据；&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_chain_t&lt;/code&gt; 构成数据流水线&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_rbtree.h&lt;/code&gt; + &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_rbtree.c&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;红黑树，哨兵节点代替 NULL，自定义插入函数，&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_rbtree_data&lt;/code&gt; 反查容器&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h3 id=&quot;第-2-步进程模型与事件循环2-3-小时&quot;&gt;第 2 步：进程模型与事件循环（2-3 小时）&lt;/h3&gt;

&lt;p&gt;这是理解 nginx 运行时行为的核心。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;阅读顺序&lt;/strong&gt;：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/os/unix/ngx_process_cycle.c&lt;/code&gt;&lt;/strong&gt; — &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main()&lt;/code&gt; 之后的真正入口
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_master_process_cycle()&lt;/code&gt; — master 进程循环（信号处理、worker 管理）&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_single_process_cycle()&lt;/code&gt; — 单进程模式（调试用）&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_worker_process_cycle()&lt;/code&gt; — &lt;strong&gt;worker 进程的主循环&lt;/strong&gt;（最关键的阅读目标）&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_start_worker_processes()&lt;/code&gt; — 如何 fork worker&lt;/li&gt;
      &lt;li&gt;重点关注：热更新（HUP 信号）时新旧 worker 的切换逻辑&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/event/ngx_event.c&lt;/code&gt;&lt;/strong&gt; — 事件子系统核心
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_event_process_init()&lt;/code&gt; — worker 启动时的事件初始化（创建连接池、事件池）&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_process_events_and_timers()&lt;/code&gt;&lt;/strong&gt; — 事件循环的心脏，每次循环执行四个步骤：
        &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;① ngx_event_find_timer()       -- 从红黑树找出最近到期的定时器
② ngx_process_events()         -- 调用 epoll_wait / kqueue 等
③ ngx_event_expire_timers()    -- 处理到期定时器
④ ngx_event_process_posted()   -- 处理延迟执行的 posted 事件
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;        &lt;/div&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/event/ngx_event_timer.h&lt;/code&gt;&lt;/strong&gt; — 定时器管理
    &lt;ul&gt;
      &lt;li&gt;全局红黑树 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_event_timer_rbtree&lt;/code&gt;，键值为 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;到期时间 = ngx_current_msec + delay&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;惰性延迟优化：阈值 300ms，避免频繁更新红黑树&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/event/ngx_event_posted.h&lt;/code&gt;&lt;/strong&gt; — 延迟事件机制
    &lt;ul&gt;
      &lt;li&gt;三个全局队列：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_posted_accept_events&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_posted_events&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_posted_next_events&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;用于避免重入和批量化处理&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;第-3-步连接管理1-2-小时&quot;&gt;第 3 步：连接管理（1-2 小时）&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_connection.h&lt;/code&gt;&lt;/strong&gt; — 两个核心结构体
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_connection_t&lt;/code&gt;：每条连接一个实例，包含 fd、读写事件、I/O 函数指针（被 SSL/QUIC 替换）、状态位&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_listening_t&lt;/code&gt;：每个监听 socket 一个实例，包含接受回调、SSL/QUIC 标记&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_connection.c&lt;/code&gt;&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_open_listening_sockets()&lt;/code&gt; — 打开所有监听端口&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_get_connection()&lt;/code&gt; — 从预分配数组中取空闲连接&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_close_connection()&lt;/code&gt; — 归还连接到空闲列表&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/event/ngx_event_accept.c&lt;/code&gt;&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_event_accept()&lt;/code&gt; — accept 处理器，accept 互斥锁逻辑&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;关键设计：&lt;strong&gt;instance 位&lt;/strong&gt;解决 stale event 问题&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;每次连接复用时，instance 位翻转。
当 epoll/kqueue 返回一个过时的事件时，
通过比对 instance 位发现不匹配 → 丢弃该事件。
这避免了额外系统调用来验证事件有效性。
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;第-4-步配置系统2-小时&quot;&gt;第 4 步：配置系统（2 小时）&lt;/h3&gt;

&lt;p&gt;nginx 的配置解析器是一个&lt;strong&gt;递归下降解析器&lt;/strong&gt;，是整个模块系统运转的基础。&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_conf_file.h&lt;/code&gt;&lt;/strong&gt; — 核心类型
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_command_t&lt;/code&gt;：每个配置指令的定义（名称、参数规则、set 函数、偏移量）&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_conf_t&lt;/code&gt;：解析上下文&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_conf_file.c&lt;/code&gt;&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_conf_parse()&lt;/code&gt;&lt;/strong&gt; — 递归解析入口，遇到 block 指令会递归调用自身&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_conf_handler()&lt;/code&gt; — 分发到模块的 set 函数&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;参数类型标志速查&lt;/strong&gt;：
    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;NGX_CONF_NOARGS         -- 无参数（如 &quot;accept_mutex off;&quot; 中的 off 是 flag，不是参数）
NGX_CONF_TAKE1~7        -- 正好 N 个参数
NGX_CONF_TAKE12         -- 1 或 2 个参数
NGX_CONF_FLAG           -- 布尔值（on/off）
NGX_CONF_BLOCK          -- 后面跟着 {} 块
NGX_CONF_1MORE          -- 至少 1 个参数
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Setter 函数族&lt;/strong&gt;：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_conf_set_flag_slot&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_conf_set_str_slot&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_conf_set_num_slot&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_conf_set_size_slot&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_conf_set_msec_slot&lt;/code&gt; 等，这些是配置解析的基础组件。&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;配置合并宏&lt;/strong&gt;：
    &lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;ngx_conf_merge_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prev&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;// 数值：当前 → 父级 → 默认&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ngx_conf_merge_str_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prev&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ngx_conf_merge_msec_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prev&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
    &lt;p&gt;体现了 nginx 配置继承的三级 fallback 机制。&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;第-5-步模块系统1-2-小时&quot;&gt;第 5 步：模块系统（1-2 小时）&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_module.h&lt;/code&gt;&lt;/strong&gt; — &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_module_t&lt;/code&gt; 结构体
    &lt;ul&gt;
      &lt;li&gt;全局索引 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;index&lt;/code&gt; 和类型内索引 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ctx_index&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;类型特定的 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ctx&lt;/code&gt; 指针&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;commands&lt;/code&gt; 数组（配置指令定义）&lt;/li&gt;
      &lt;li&gt;生命周期钩子：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;init_master&lt;/code&gt; → &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;init_module&lt;/code&gt; → &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;init_process&lt;/code&gt; → &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;exit_process&lt;/code&gt; → &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;exit_master&lt;/code&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;模块类型&lt;/strong&gt;：
    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;NGX_CORE_MODULE    -- 核心模块（如 ngx_core_module、ngx_events_module、ngx_http_module）
NGX_EVENT_MODULE   -- 事件模块（如 ngx_epoll_module、ngx_kqueue_module）
NGX_HTTP_MODULE    -- HTTP 模块
NGX_MAIL_MODULE    -- Mail 模块
NGX_STREAM_MODULE  -- Stream 模块
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_module.c&lt;/code&gt;&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_cycle_modules()&lt;/code&gt; — 复制模块数组到 cycle&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_init_modules()&lt;/code&gt; — 调用每个模块的 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;init_module&lt;/code&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;HTTP 模块的特殊上下文&lt;/strong&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_http_module_t&lt;/code&gt;：
    &lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ngx_int_t&lt;/span&gt;   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;preconfiguration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ngx_conf_t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ngx_int_t&lt;/span&gt;   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;postconfiguration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ngx_conf_t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;       &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;create_main_conf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ngx_conf_t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;       &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;init_main_conf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ngx_conf_t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;       &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;create_srv_conf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ngx_conf_t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;       &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;merge_srv_conf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ngx_conf_t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prev&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;       &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;create_loc_conf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ngx_conf_t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;       &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;merge_loc_conf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ngx_conf_t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prev&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ngx_http_module_t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
    &lt;p&gt;&lt;strong&gt;这是理解 HTTP 模块如何工作的关键&lt;/strong&gt;：main → srv → loc 三级配置的创建和合并都在这里。&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;第-6-步http-请求处理全链路4-5-小时-核心&quot;&gt;第 6 步：HTTP 请求处理全链路（4-5 小时）⭐ 核心&lt;/h3&gt;

&lt;p&gt;这是 nginx 源码中最重要、最复杂的部分，建议反复阅读。&lt;/p&gt;

&lt;h4 id=&quot;61-http-框架初始化&quot;&gt;6.1 HTTP 框架初始化&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/ngx_http.c&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_http_block()&lt;/code&gt; — &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http {}&lt;/code&gt; 块的解析函数
    &lt;ul&gt;
      &lt;li&gt;创建 main/srv/loc 三级配置&lt;/li&gt;
      &lt;li&gt;初始化 phase engine（阶段引擎）&lt;/li&gt;
      &lt;li&gt;调用各模块的 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;postconfiguration&lt;/code&gt;（此时注册 handler、filter）&lt;/li&gt;
      &lt;li&gt;初始化请求头解析表、变量系统&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;62-11-个处理阶段&quot;&gt;6.2 11 个处理阶段&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/ngx_http_core_module.h&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;NGX_HTTP_POST_READ_PHASE       -- 读完请求头之后（realip 模块在此）
NGX_HTTP_SERVER_REWRITE_PHASE  -- server 级别的 rewrite
NGX_HTTP_FIND_CONFIG_PHASE     -- 匹配 location
NGX_HTTP_REWRITE_PHASE         -- location 级别的 rewrite
NGX_HTTP_POST_REWRITE_PHASE    -- rewrite 之后（检查重定向循环）
NGX_HTTP_PREACCESS_PHASE       -- 访问限制（limit_conn、limit_req）
NGX_HTTP_ACCESS_PHASE          -- 权限检查（allow/deny、auth_basic、auth_request）
NGX_HTTP_POST_ACCESS_PHASE     -- access 之后（处理 satisfy all/any）
NGX_HTTP_PRECONTENT_PHASE      -- 内容产生之前（mirror、try_files）
NGX_HTTP_CONTENT_PHASE         -- 产生响应内容（proxy_pass、fastcgi_pass、static）
NGX_HTTP_LOG_PHASE             -- 记录日志（请求处理完成之后）
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;每个阶段由 &lt;strong&gt;checker 函数&lt;/strong&gt; 驱动，依次调用注册到该阶段的 handler。关键 checker：&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Checker&lt;/th&gt;
      &lt;th&gt;阶段&lt;/th&gt;
      &lt;th&gt;行为&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_http_core_generic_phase&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;rewrite 等&lt;/td&gt;
      &lt;td&gt;顺序执行，DECLINED 则下一个&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_http_core_find_config_phase&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;find_config&lt;/td&gt;
      &lt;td&gt;匹配 location，只执行一次&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_http_core_access_phase&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;access&lt;/td&gt;
      &lt;td&gt;支持 satisfy all/any&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_http_core_content_phase&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;content&lt;/td&gt;
      &lt;td&gt;找到第一个返回 OK 的 handler&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;阅读入口：&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_http_core_run_phases()&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h4 id=&quot;63-请求生命周期&quot;&gt;6.3 请求生命周期&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/ngx_http_request.h&lt;/code&gt;&lt;/strong&gt; — &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_http_request_t&lt;/code&gt; 结构体（很大，约 60+ 字段）&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/ngx_http_request.c&lt;/code&gt;&lt;/strong&gt; — 按顺序阅读以下函数：&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;新连接到达：
  ngx_http_init_connection()
    → ngx_http_wait_request_handler()      -- 等待完整的请求头到达

请求头解析完成：
  ngx_http_process_request_line()
    → ngx_http_process_request_headers()
      → ngx_http_process_request()
        → ngx_http_process_request_headers()  -- 解析 Host、Content-Length 等
        → ngx_http_handler()                  -- 设置 r-&amp;gt;phase_handler = 0
          → ngx_http_core_run_phases(r)       -- 驱动阶段引擎

响应发送：
  ngx_http_writer()                         -- 异步发送响应体

请求结束：
  ngx_http_finalize_request()
    → ngx_http_free_request()
      → ngx_destroy_pool(r-&amp;gt;pool)          -- 销毁请求内存池
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;64-过滤器链&quot;&gt;6.4 过滤器链&lt;/h4&gt;

&lt;p&gt;nginx 的输出不是由单个模块一次性完成的，而是通过&lt;strong&gt;过滤器链&lt;/strong&gt;（责任链模式）协作产生的。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;头过滤器链&lt;/strong&gt;：&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ngx_http_top_header_filter
  → ngx_http_not_modified_header_filter
  → ...
  → ngx_http_gzip_header_filter
  → ...
  → ngx_http_header_filter          -- 最终序列化 HTTP 头为字节流
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;体过滤器链&lt;/strong&gt;：&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ngx_http_top_body_filter
  → ngx_http_range_body_filter
  → ngx_http_copy_filter            -- 必要时将 in_file buf 复制到内存
  → ngx_http_gzip_body_filter
  → ngx_http_chunked_body_filter
  → ngx_http_write_filter           -- 最终调用 c-&amp;gt;send_chain() 发送
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;过滤器注册模式：&lt;/p&gt;
&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// 在 postconfiguration 中注册：&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ngx_int_t&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;ngx_http_my_init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ngx_conf_t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ngx_http_next_header_filter&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ngx_http_top_header_filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ngx_http_top_header_filter&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ngx_http_my_header_filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;ngx_http_next_body_filter&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ngx_http_top_body_filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ngx_http_top_body_filter&lt;/span&gt;     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ngx_http_my_body_filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NGX_OK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;注意：&lt;strong&gt;后注册的先执行&lt;/strong&gt;（因为每次插在链头）。&lt;/p&gt;

&lt;h4 id=&quot;65-location-匹配&quot;&gt;6.5 Location 匹配&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/ngx_http_core_module.c&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_http_core_find_config_phase()&lt;/code&gt; 中的匹配算法：&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;用 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_hash_lookup()&lt;/code&gt; 在 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;locations&lt;/code&gt; 哈希表中做&lt;strong&gt;前缀匹配&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;如果匹配到的 location 有嵌套，递归查找&lt;/li&gt;
  &lt;li&gt;最后用 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;regex_locations&lt;/code&gt; 队列做&lt;strong&gt;正则匹配&lt;/strong&gt;（优先级最高，使用 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=~&lt;/code&gt; 或 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~*&lt;/code&gt;）&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;配置合并的路径&lt;/strong&gt;：匹配到某个 location 后，其 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;loc_conf[module_index]&lt;/code&gt; 已在解析阶段通过 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;merge_loc_conf&lt;/code&gt; 正确地继承自 server 和 main 级别的配置。&lt;/p&gt;

&lt;h4 id=&quot;66-upstream-机制&quot;&gt;6.6 Upstream 机制&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/ngx_http_upstream.h&lt;/code&gt;&lt;/strong&gt; + &lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/ngx_http_upstream.c&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;upstream 的状态机：&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ngx_http_upstream_init()
  → ngx_http_upstream_connect()           -- 建立到后端的连接
    → ngx_http_upstream_send_request()    -- 发送请求体
      → ngx_http_upstream_process_header()  -- 解析响应头
        → ngx_http_upstream_process_body_in_memory() 或 sendfile/pipe -- 转发响应体
          → ngx_http_upstream_finalize_request()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;负载均衡是&lt;strong&gt;可插拔&lt;/strong&gt;的，通过 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_http_upstream_peer_t&lt;/code&gt; 接口：&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_http_upstream_round_robin.c&lt;/code&gt; — 加权轮询（默认）&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_http_upstream_hash_module.c&lt;/code&gt; — 一致性哈希&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_http_upstream_least_conn_module.c&lt;/code&gt; — 最小连接数&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_http_upstream_random_module.c&lt;/code&gt; — 随机选择&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;第-7-步补充阅读按需&quot;&gt;第 7 步：补充阅读（按需）&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;日志系统&lt;/strong&gt;：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_log.h&lt;/code&gt; + &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_log.c&lt;/code&gt; — &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_log_t&lt;/code&gt; 分级日志，链式日志对象&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;变量系统&lt;/strong&gt;：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/ngx_http_variables.c&lt;/code&gt; — &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$remote_addr&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$host&lt;/code&gt; 等变量如何注册和求值&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;正则引擎&lt;/strong&gt;：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_regex.c&lt;/code&gt; — 对 PCRE 的封装（nginx 自己不做正则引擎）&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;共享内存与 Slab 分配器&lt;/strong&gt;：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_slab.c&lt;/code&gt; — 用于多进程共享数据的 slab 分配器&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;SSL/TLS&lt;/strong&gt;：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/event/ngx_event_openssl.c&lt;/code&gt; — 如何通过替换 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;c-&amp;gt;recv/send&lt;/code&gt; 函数指针实现 SSL&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;HTTP/2&lt;/strong&gt;：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/v2/&lt;/code&gt; — HTTP/2 帧的解析和多路复用&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;QUIC/HTTP/3&lt;/strong&gt;：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/event/quic/&lt;/code&gt; + &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/v3/&lt;/code&gt; — QUIC 传输层和 HTTP/3 的实现&lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;三贯穿始终的设计模式与思维方式&quot;&gt;三、贯穿始终的设计模式与思维方式&lt;/h2&gt;

&lt;h3 id=&quot;31-侵入式数据结构&quot;&gt;3.1 侵入式数据结构&lt;/h3&gt;

&lt;p&gt;nginx 不单独分配链表节点或树节点，而是将 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_queue_t&lt;/code&gt; 和 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_rbtree_node_t&lt;/code&gt; &lt;strong&gt;直接嵌入&lt;/strong&gt;在使用它们的结构体中。零额外分配，极致效率。&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// 不是：list&amp;lt;Item*&amp;gt; items（每次插入要 malloc 一个节点）&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// 而是：Item 里包含 ngx_queue_t queue，直接链入&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;32-预分配--重用&quot;&gt;3.2 预分配 + 重用&lt;/h3&gt;

&lt;p&gt;连接、事件、内存池——在启动时预分配好，运行时不再 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;malloc&lt;/code&gt;。nginx 的哲学是：&lt;strong&gt;“我能在启动时算清楚的最大资源量，就预分配好”&lt;/strong&gt;。&lt;/p&gt;

&lt;h3 id=&quot;33-io-函数指针的多态&quot;&gt;3.3 I/O 函数指针的多态&lt;/h3&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;recv&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ngx_ssl_recv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;// SSL 模块偷偷换了&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;send&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ngx_ssl_send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;高层代码（HTTP 框架）完全不感知底层是 TCP 还是 SSL 还是 QUIC，这是 nginx 实现协议升级和 SSL 透明的关键手段。&lt;/p&gt;

&lt;h3 id=&quot;34-返回值驱动的控制流&quot;&gt;3.4 返回值驱动的控制流&lt;/h3&gt;

&lt;p&gt;nginx 不使用异常或 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;goto&lt;/code&gt;，而是通过返回值表达控制意图：&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;返回值&lt;/th&gt;
      &lt;th&gt;语义&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NGX_OK&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;完成，调用者继续&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NGX_ERROR&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;出错，终止&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NGX_AGAIN&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;资源不足（缓冲满了、数据未到），暂停等待下次事件触发&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NGX_DECLINED&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;我不处理，找下一个（handler 单链表遍历的核心）&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NGX_DONE&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;已处理，但请求未结束（异步操作 pending）&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NGX_BUSY&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;忙，稍后再试&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;理解 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NGX_AGAIN&lt;/code&gt; 和 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NGX_DECLINED&lt;/code&gt; 的区别特别重要——前者是”等一会儿我重试”，后者是”换下一个”。&lt;/p&gt;

&lt;h3 id=&quot;35-优雅的零停机&quot;&gt;3.5 优雅的零停机&lt;/h3&gt;

&lt;p&gt;配置重载（&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nginx -s reload&lt;/code&gt;）的核心逻辑：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Master 收到 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SIGHUP&lt;/code&gt; → 创建新 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_cycle_t&lt;/code&gt;，fork 新 worker&lt;/li&gt;
  &lt;li&gt;旧 worker 收到 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SIGQUIT&lt;/code&gt; → 优雅关闭（处理完现有连接再退出）&lt;/li&gt;
  &lt;li&gt;新旧 worker 短暂共存，旧 worker 关闭后新 cycle 接管&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;这依赖于 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cycle-&amp;gt;old_cycle&lt;/code&gt; 的设计：新 cycle 持有旧 cycle 引用，等旧 worker 退出后释放。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;四调试技巧&quot;&gt;四、调试技巧&lt;/h2&gt;

&lt;h3 id=&quot;41-debug-日志&quot;&gt;4.1 Debug 日志&lt;/h3&gt;

&lt;p&gt;编译时带 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--with-debug&lt;/code&gt;，然后在配置中设置：&lt;/p&gt;
&lt;div class=&quot;language-nginx highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;error_log&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;/var/log/nginx/debug.log&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;42-gdb-常用断点&quot;&gt;4.2 GDB 常用断点&lt;/h3&gt;

&lt;pre&gt;&lt;code class=&quot;language-gdb&quot;&gt;# 事件循环入口
b ngx_process_events_and_timers

# 请求处理入口
b ngx_http_process_request

# 阶段引擎
b ngx_http_core_run_phases

# 连接分配
b ngx_get_connection

# upstream 连接
b ngx_http_upstream_connect

# 一个连接上的所有 recv/send 调用
b ngx_unix_recv
b ngx_unix_send
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;43-打印-ngx_str_t&quot;&gt;4.3 打印 ngx_str_t&lt;/h3&gt;

&lt;pre&gt;&lt;code class=&quot;language-gdb&quot;&gt;# ngx_str_t 不是 C 字符串，在 GDB 中需要自定义打印
define print_ngx_str
  set $s = (ngx_str_t*)$arg0
  printf &quot;%.*s\n&quot;, $s-&amp;gt;len, $s-&amp;gt;data
end
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;44-追踪内存分配&quot;&gt;4.4 追踪内存分配&lt;/h3&gt;

&lt;p&gt;在 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_palloc.c&lt;/code&gt; 的关键函数打断点：&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_create_pool&lt;/code&gt; — 池创建&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_palloc&lt;/code&gt; — 小块分配&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_palloc_block&lt;/code&gt; — 分配新池块&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_pfree&lt;/code&gt; — 大块释放&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_destroy_pool&lt;/code&gt; — 池销毁&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;五建议的阅读实践&quot;&gt;五、建议的阅读实践&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;不要试图按文件序号从头读到尾&lt;/strong&gt;。nginx 的静态函数和全局变量很多，按头文件依赖关系去读。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;每次只追踪一个功能链路&lt;/strong&gt;。比如 “一个 HTTP GET 请求从接收到返回的完整路径”，只关注这条线上的函数，忽略旁路。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;画图&lt;/strong&gt;。nginx 源码中的结构体嵌套很深，手绘以下关系图会很有帮助：
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_cycle_t&lt;/code&gt; → &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conf_ctx&lt;/code&gt; → 各模块配置的索引关系&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_connection_t&lt;/code&gt; → &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;read&lt;/code&gt; / &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;write&lt;/code&gt; → &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_event_t&lt;/code&gt; → &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;handler&lt;/code&gt; 的调用链&lt;/li&gt;
      &lt;li&gt;HTTP 阶段引擎中 checker → handler → next 的跳转关系&lt;/li&gt;
      &lt;li&gt;过滤器链中 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_http_top_header_filter&lt;/code&gt; → &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;next&lt;/code&gt; → … 的顺序&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;从简单的第三方模块入手&lt;/strong&gt;。阅读 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/modules/ngx_http_echo_module.c&lt;/code&gt; 级别的简单模块，理解 handler 和 filter 怎么写。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;对比阅读&lt;/strong&gt;。在 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/modules/&lt;/code&gt; 下找两个类似功能的模块对比（如 proxy vs fastcgi），理解差异在哪里。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;重复读核心函数&lt;/strong&gt;。&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_process_events_and_timers()&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_http_core_run_phases()&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_conf_parse()&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_http_upstream_connect()&lt;/code&gt; 这几个函数值得反复读，每次都会发现新细节。&lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;六核心文件索引&quot;&gt;六、核心文件索引&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;文件&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;阅读优先级&lt;/th&gt;
      &lt;th&gt;核心内容&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/nginx.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★★&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main()&lt;/code&gt; 入口&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_cycle.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★★&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_init_cycle()&lt;/code&gt; 循环初始化&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_palloc.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★★&lt;/td&gt;
      &lt;td&gt;内存池实现&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_buf.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★★&lt;/td&gt;
      &lt;td&gt;buffer 和 chain 操作&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_connection.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★★&lt;/td&gt;
      &lt;td&gt;连接预分配和管理&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_conf_file.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★★&lt;/td&gt;
      &lt;td&gt;配置解析器&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_module.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★★&lt;/td&gt;
      &lt;td&gt;模块加载和初始化&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_string.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★☆&lt;/td&gt;
      &lt;td&gt;字符串工具函数集&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_array.h&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★★&lt;/td&gt;
      &lt;td&gt;动态数组&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_list.h&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★★&lt;/td&gt;
      &lt;td&gt;链表+数组混合&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_queue.h&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★★&lt;/td&gt;
      &lt;td&gt;侵入式双向链表&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_rbtree.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★☆&lt;/td&gt;
      &lt;td&gt;红黑树&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_hash.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★☆&lt;/td&gt;
      &lt;td&gt;静态哈希表&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_log.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★☆&lt;/td&gt;
      &lt;td&gt;日志系统&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/os/unix/ngx_process_cycle.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★★&lt;/td&gt;
      &lt;td&gt;master/worker 进程管理&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/event/ngx_event.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★★&lt;/td&gt;
      &lt;td&gt;事件循环核心&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/event/ngx_event_accept.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★☆&lt;/td&gt;
      &lt;td&gt;accept 与惊群处理&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/event/ngx_event_timer.h&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★☆&lt;/td&gt;
      &lt;td&gt;定时器管理&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/event/modules/ngx_epoll_module.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★☆&lt;/td&gt;
      &lt;td&gt;epoll 事件模块&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/ngx_http.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★★&lt;/td&gt;
      &lt;td&gt;HTTP 框架初始化&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/ngx_http_request.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★★&lt;/td&gt;
      &lt;td&gt;请求生命周期&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/ngx_http_core_module.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★★&lt;/td&gt;
      &lt;td&gt;核心指令、phase checker&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/ngx_http_upstream.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★★&lt;/td&gt;
      &lt;td&gt;upstream 代理机制&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/ngx_http_variables.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★☆&lt;/td&gt;
      &lt;td&gt;变量系统&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/ngx_http_header_filter.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★☆&lt;/td&gt;
      &lt;td&gt;响应头序列化&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/ngx_http_write_filter.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★☆&lt;/td&gt;
      &lt;td&gt;最终发送到 socket&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/modules/ngx_http_proxy_module.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★☆&lt;/td&gt;
      &lt;td&gt;典型 HTTP 代理模块&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/modules/ngx_http_static_module.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★☆☆&lt;/td&gt;
      &lt;td&gt;最简单的 content handler&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;hr /&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;最后建议&lt;/strong&gt;：读 nginx 源码是一场马拉松，不是短跑。核心代码大约 10 万行，但设计高度一致，一旦掌握了前 30% 的模式，剩下的 70% 会提速很快。祝阅读顺利。&lt;/p&gt;
&lt;/blockquote&gt;
</content>
    
    <category term="Nginx"/>
    
  </entry>
  
  <entry>
    <title>Nginx Source Code Reading Guide</title>
    <link href="https://wy471x.github.io/en/2026-07-23/nginx-source-code-guide.html"/>
    <updated>2026-07-23T23:45:00+08:00</updated>
    <id>https://wy471x.github.io/en/2026-07-23/nginx-source-code-guide.html</id>
    <content type="html">&lt;h1 id=&quot;nginx-source-code-reading-guide&quot;&gt;Nginx Source Code Reading Guide&lt;/h1&gt;

&lt;h2 id=&quot;1-preparation&quot;&gt;1. Preparation&lt;/h2&gt;

&lt;h3 id=&quot;11-prerequisites&quot;&gt;1.1 Prerequisites&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;C Language&lt;/strong&gt;: pointers, function pointers, macros, bitwise operations, struct memory layout (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;offsetof&lt;/code&gt;), variadic arguments&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Network Programming&lt;/strong&gt;: TCP/IP, HTTP/1.1 protocol, socket API (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;accept&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;recv&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;send&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setsockopt&lt;/code&gt;), non-blocking I/O&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Operating Systems&lt;/strong&gt;: process model (fork), signals, shared memory, epoll/kqueue multiplexing mechanisms&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Build Tools&lt;/strong&gt;: ability to read shell scripts and Makefiles&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;12-environment-setup&quot;&gt;1.2 Environment Setup&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Build nginx with debug info&lt;/span&gt;
./auto/configure &lt;span class=&quot;nt&quot;&gt;--with-debug&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--prefix&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;pwd&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;/build
make &lt;span class=&quot;nt&quot;&gt;-j&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;nproc&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Debug with GDB&lt;/span&gt;
gdb ./objs/nginx
&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;gdb&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; b ngx_process_events_and_timers
&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;gdb&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; r
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;13-key-macros-and-conventions-quick-reference&quot;&gt;1.3 Key Macros and Conventions Quick Reference&lt;/h3&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Macro/Pattern&lt;/th&gt;
      &lt;th&gt;Meaning&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NGX_OK&lt;/code&gt; / &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NGX_ERROR&lt;/code&gt; / &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NGX_AGAIN&lt;/code&gt; / &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NGX_DECLINED&lt;/code&gt; / &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NGX_DONE&lt;/code&gt; / &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NGX_BUSY&lt;/code&gt; / &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NGX_ABORT&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Standard return values: 0/-1/-2/-5/-4/-3/-6&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_string(&quot;foo&quot;)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Compile-time construction of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_str_t&lt;/code&gt; from a literal&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_queue_data(q, type, link)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Retrieve the containing struct from an intrusive queue node&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_rbtree_data(node, type, link)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Same as above, for rbtree nodes&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_log_debug&lt;/code&gt; / &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_log_error&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Leveled logging macros; debug level only output with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--with-debug&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;offsetof(type, member)&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Calculate the offset of a member within a struct — the cornerstone of intrusive data structures&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;2-recommended-reading-roadmap&quot;&gt;2. Recommended Reading Roadmap&lt;/h2&gt;

&lt;h3 id=&quot;step-0-understand-the-build-system-30-min&quot;&gt;Step 0: Understand the Build System (30 min)&lt;/h3&gt;

&lt;p&gt;Start from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto/&lt;/code&gt; directory. No need to read every script in detail — focus on understanding the flow:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto/configure&lt;/code&gt;&lt;/strong&gt; — Entry point, sequentially calls &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto/options&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto/init&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto/cc/*&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto/os/*&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto/feature&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto/modules&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto/sources&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto/make&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto/modules&lt;/code&gt;&lt;/strong&gt; — One of the most critical files. It determines which modules are compiled into the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_modules[]&lt;/code&gt; array. &lt;strong&gt;The ordering of modules determines initialization order and processing priority — never change it casually&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auto/sources&lt;/code&gt;&lt;/strong&gt; — Defines shell variables listing all source files (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CORE_SRCS&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HTTP_SRCS&lt;/code&gt;, etc.), ultimately output to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;objs/Makefile&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Build artifacts:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;objs/ngx_auto_config.h&lt;/code&gt; — All &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#define&lt;/code&gt; macros (compile-time feature switches)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;objs/ngx_modules.c&lt;/code&gt; — Auto-generated &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_modules[]&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_module_names[]&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;step-1-core-data-structures-2-3-hours&quot;&gt;Step 1: Core Data Structures (2-3 hours)&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;This is the most important foundation — master it thoroughly.&lt;/strong&gt; Suggested order by dependency:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ngx_str_t  →  ngx_pool_t  →  ngx_array_t  →  ngx_list_t  →  ngx_queue_t  →  ngx_buf_t / ngx_chain_t  →  ngx_rbtree_t
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Read file by file:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;File&lt;/th&gt;
      &lt;th&gt;Key Focus&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_string.h&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_str_t&lt;/code&gt; is not a C string — it’s a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;len&lt;/code&gt; + &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data&lt;/code&gt; pair; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_vslprintf&lt;/code&gt; and other formatting functions&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_palloc.h&lt;/code&gt; + &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_palloc.c&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Pool allocator: small blocks carved from pool, large blocks via malloc; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_palloc&lt;/code&gt; vs &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_pnalloc&lt;/code&gt; (aligned vs unaligned); cleanup callback mechanism&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_array.h&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Dynamic array, elements stored contiguously; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_array_push&lt;/code&gt; returns a pointer to the new element&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_list.h&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Hybrid of linked list + array; each &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;part&lt;/code&gt; holds &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nalloc&lt;/code&gt; elements&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_queue.h&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;Pure macros&lt;/strong&gt;, intrusive doubly-linked circular list; the core macro &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_queue_data&lt;/code&gt; uses &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;offsetof&lt;/code&gt; to retrieve the container&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_buf.h&lt;/code&gt; + &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_buf.c&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_buf_t&lt;/code&gt; unifies memory data and file data; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_chain_t&lt;/code&gt; forms a data pipeline&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_rbtree.h&lt;/code&gt; + &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_rbtree.c&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Red-black tree, sentinel node instead of NULL, custom insert function; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_rbtree_data&lt;/code&gt; retrieves the container&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h3 id=&quot;step-2-process-model-and-event-loop-2-3-hours&quot;&gt;Step 2: Process Model and Event Loop (2-3 hours)&lt;/h3&gt;

&lt;p&gt;This is the core of understanding nginx runtime behavior.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reading order&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/os/unix/ngx_process_cycle.c&lt;/code&gt;&lt;/strong&gt; — The real entry point after &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main()&lt;/code&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_master_process_cycle()&lt;/code&gt; — Master process loop (signal handling, worker management)&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_single_process_cycle()&lt;/code&gt; — Single process mode (for debugging)&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_worker_process_cycle()&lt;/code&gt; — &lt;strong&gt;The main loop of a worker process&lt;/strong&gt; (most critical reading target)&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_start_worker_processes()&lt;/code&gt; — How workers are forked&lt;/li&gt;
      &lt;li&gt;Key focus: the switching logic between old and new workers during hot reload (HUP signal)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/event/ngx_event.c&lt;/code&gt;&lt;/strong&gt; — Event subsystem core
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_event_process_init()&lt;/code&gt; — Event initialization when a worker starts (creates connection pool, event pool)&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_process_events_and_timers()&lt;/code&gt;&lt;/strong&gt; — The heart of the event loop, four steps per iteration:
        &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;① ngx_event_find_timer()       -- Find the soonest-expiring timer from the rbtree
② ngx_process_events()         -- Call epoll_wait / kqueue etc.
③ ngx_event_expire_timers()    -- Process expired timers
④ ngx_event_process_posted()   -- Process deferred posted events
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;        &lt;/div&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/event/ngx_event_timer.h&lt;/code&gt;&lt;/strong&gt; — Timer management
    &lt;ul&gt;
      &lt;li&gt;Global rbtree &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_event_timer_rbtree&lt;/code&gt;, keyed by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;expiry = ngx_current_msec + delay&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;Lazy delay optimization: 300ms threshold to avoid frequent rbtree updates&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/event/ngx_event_posted.h&lt;/code&gt;&lt;/strong&gt; — Deferred event mechanism
    &lt;ul&gt;
      &lt;li&gt;Three global queues: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_posted_accept_events&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_posted_events&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_posted_next_events&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;Used to avoid reentrancy and enable batch processing&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;step-3-connection-management-1-2-hours&quot;&gt;Step 3: Connection Management (1-2 hours)&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_connection.h&lt;/code&gt;&lt;/strong&gt; — Two core structs
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_connection_t&lt;/code&gt;: One instance per connection, contains fd, read/write events, I/O function pointers (swapped by SSL/QUIC), status bits&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_listening_t&lt;/code&gt;: One instance per listening socket, contains accept callback, SSL/QUIC flags&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_connection.c&lt;/code&gt;&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_open_listening_sockets()&lt;/code&gt; — Open all listening ports&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_get_connection()&lt;/code&gt; — Get a free connection from the pre-allocated array&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_close_connection()&lt;/code&gt; — Return a connection to the free list&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/event/ngx_event_accept.c&lt;/code&gt;&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_event_accept()&lt;/code&gt; — Accept handler, accept mutex logic&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Key design: &lt;strong&gt;instance bit&lt;/strong&gt; solves the stale event problem&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Every time a connection is reused, the instance bit flips.
When epoll/kqueue returns a stale event,
the instance bit mismatch is detected → the event is discarded.
This avoids extra syscalls to verify event validity.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;step-4-configuration-system-2-hours&quot;&gt;Step 4: Configuration System (2 hours)&lt;/h3&gt;

&lt;p&gt;nginx’s configuration parser is a &lt;strong&gt;recursive descent parser&lt;/strong&gt; — the foundation upon which the entire module system operates.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_conf_file.h&lt;/code&gt;&lt;/strong&gt; — Core types
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_command_t&lt;/code&gt;: Definition of each configuration directive (name, argument rules, set function, offset)&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_conf_t&lt;/code&gt;: Parse context&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_conf_file.c&lt;/code&gt;&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_conf_parse()&lt;/code&gt;&lt;/strong&gt; — Recursive parse entry point; calls itself recursively for block directives&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_conf_handler()&lt;/code&gt; — Dispatches to a module’s set function&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Argument type flags quick reference&lt;/strong&gt;:
    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;NGX_CONF_NOARGS         -- No arguments (e.g., &quot;off&quot; in &quot;accept_mutex off;&quot; is a flag, not an argument)
NGX_CONF_TAKE1~7        -- Exactly N arguments
NGX_CONF_TAKE12         -- 1 or 2 arguments
NGX_CONF_FLAG           -- Boolean (on/off)
NGX_CONF_BLOCK          -- Followed by a {} block
NGX_CONF_1MORE          -- At least 1 argument
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Setter function family&lt;/strong&gt;: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_conf_set_flag_slot&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_conf_set_str_slot&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_conf_set_num_slot&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_conf_set_size_slot&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_conf_set_msec_slot&lt;/code&gt;, etc. — the basic building blocks of configuration parsing.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Configuration merge macros&lt;/strong&gt;:
    &lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;ngx_conf_merge_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prev&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;// Numeric: current → parent → default&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ngx_conf_merge_str_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prev&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ngx_conf_merge_msec_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prev&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
    &lt;p&gt;These embody nginx’s three-level fallback mechanism for configuration inheritance.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;step-5-module-system-1-2-hours&quot;&gt;Step 5: Module System (1-2 hours)&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_module.h&lt;/code&gt;&lt;/strong&gt; — The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_module_t&lt;/code&gt; struct
    &lt;ul&gt;
      &lt;li&gt;Global index &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;index&lt;/code&gt; and type-specific index &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ctx_index&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;Type-specific &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ctx&lt;/code&gt; pointer&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;commands&lt;/code&gt; array (configuration directive definitions)&lt;/li&gt;
      &lt;li&gt;Lifecycle hooks: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;init_master&lt;/code&gt; → &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;init_module&lt;/code&gt; → &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;init_process&lt;/code&gt; → &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;exit_process&lt;/code&gt; → &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;exit_master&lt;/code&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Module types&lt;/strong&gt;:
    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;NGX_CORE_MODULE    -- Core modules (e.g., ngx_core_module, ngx_events_module, ngx_http_module)
NGX_EVENT_MODULE   -- Event modules (e.g., ngx_epoll_module, ngx_kqueue_module)
NGX_HTTP_MODULE    -- HTTP modules
NGX_MAIL_MODULE    -- Mail modules
NGX_STREAM_MODULE  -- Stream modules
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_module.c&lt;/code&gt;&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_cycle_modules()&lt;/code&gt; — Copy the module array into the cycle&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_init_modules()&lt;/code&gt; — Call each module’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;init_module&lt;/code&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;HTTP module-specific context&lt;/strong&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_http_module_t&lt;/code&gt;:
    &lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ngx_int_t&lt;/span&gt;   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;preconfiguration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ngx_conf_t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ngx_int_t&lt;/span&gt;   &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;postconfiguration&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ngx_conf_t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;       &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;create_main_conf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ngx_conf_t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;       &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;init_main_conf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ngx_conf_t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;       &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;create_srv_conf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ngx_conf_t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;       &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;merge_srv_conf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ngx_conf_t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prev&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;       &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;create_loc_conf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ngx_conf_t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;       &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;merge_loc_conf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ngx_conf_t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prev&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ngx_http_module_t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
    &lt;p&gt;&lt;strong&gt;This is key to understanding how HTTP modules work&lt;/strong&gt;: the creation and merging of main → srv → loc three-level configurations all happen here.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;step-6-http-request-processing-pipeline-4-5-hours--core&quot;&gt;Step 6: HTTP Request Processing Pipeline (4-5 hours) ⭐ Core&lt;/h3&gt;

&lt;p&gt;This is the most important and complex part of the nginx source code — read it repeatedly.&lt;/p&gt;

&lt;h4 id=&quot;61-http-framework-initialization&quot;&gt;6.1 HTTP Framework Initialization&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/ngx_http.c&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_http_block()&lt;/code&gt; — The parse function for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http {}&lt;/code&gt; block
    &lt;ul&gt;
      &lt;li&gt;Creates main/srv/loc three-level configurations&lt;/li&gt;
      &lt;li&gt;Initializes the phase engine&lt;/li&gt;
      &lt;li&gt;Calls each module’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;postconfiguration&lt;/code&gt; (handlers and filters are registered here)&lt;/li&gt;
      &lt;li&gt;Initializes request header parsing tables and the variable system&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;62-the-11-processing-phases&quot;&gt;6.2 The 11 Processing Phases&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/ngx_http_core_module.h&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;NGX_HTTP_POST_READ_PHASE       -- After reading request headers (realip module lives here)
NGX_HTTP_SERVER_REWRITE_PHASE  -- Server-level rewrite
NGX_HTTP_FIND_CONFIG_PHASE     -- Location matching
NGX_HTTP_REWRITE_PHASE         -- Location-level rewrite
NGX_HTTP_POST_REWRITE_PHASE    -- After rewrite (checks for redirect loops)
NGX_HTTP_PREACCESS_PHASE       -- Access limits (limit_conn, limit_req)
NGX_HTTP_ACCESS_PHASE          -- Authorization checks (allow/deny, auth_basic, auth_request)
NGX_HTTP_POST_ACCESS_PHASE     -- After access (handles satisfy all/any)
NGX_HTTP_PRECONTENT_PHASE      -- Before content generation (mirror, try_files)
NGX_HTTP_CONTENT_PHASE         -- Generate response content (proxy_pass, fastcgi_pass, static)
NGX_HTTP_LOG_PHASE             -- Logging (after request processing is complete)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Each phase is driven by a &lt;strong&gt;checker function&lt;/strong&gt; that sequentially invokes the handlers registered for that phase. Key checkers:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Checker&lt;/th&gt;
      &lt;th&gt;Phase&lt;/th&gt;
      &lt;th&gt;Behavior&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_http_core_generic_phase&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;rewrite, etc.&lt;/td&gt;
      &lt;td&gt;Sequential execution, DECLINED → next handler&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_http_core_find_config_phase&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;find_config&lt;/td&gt;
      &lt;td&gt;Match location, executes only once&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_http_core_access_phase&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;access&lt;/td&gt;
      &lt;td&gt;Supports satisfy all/any&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_http_core_content_phase&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;content&lt;/td&gt;
      &lt;td&gt;Finds the first handler that returns OK&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Reading entry point: &lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_http_core_run_phases()&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h4 id=&quot;63-request-lifecycle&quot;&gt;6.3 Request Lifecycle&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/ngx_http_request.h&lt;/code&gt;&lt;/strong&gt; — &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_http_request_t&lt;/code&gt; struct (very large, ~60+ fields)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/ngx_http_request.c&lt;/code&gt;&lt;/strong&gt; — Read the following functions in order:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;New connection arrives:
  ngx_http_init_connection()
    → ngx_http_wait_request_handler()      -- Wait for the complete request header to arrive

Request header parsed:
  ngx_http_process_request_line()
    → ngx_http_process_request_headers()
      → ngx_http_process_request()
        → ngx_http_process_request_headers()  -- Parse Host, Content-Length, etc.
        → ngx_http_handler()                  -- Set r-&amp;gt;phase_handler = 0
          → ngx_http_core_run_phases(r)       -- Drive the phase engine

Response sending:
  ngx_http_writer()                         -- Asynchronously send the response body

Request finished:
  ngx_http_finalize_request()
    → ngx_http_free_request()
      → ngx_destroy_pool(r-&amp;gt;pool)          -- Destroy the request memory pool
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;64-filter-chain&quot;&gt;6.4 Filter Chain&lt;/h4&gt;

&lt;p&gt;nginx output is not produced by a single module in one shot — it is collaboratively generated through a &lt;strong&gt;filter chain&lt;/strong&gt; (Chain of Responsibility pattern).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Header filter chain&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ngx_http_top_header_filter
  → ngx_http_not_modified_header_filter
  → ...
  → ngx_http_gzip_header_filter
  → ...
  → ngx_http_header_filter          -- Ultimately serializes HTTP headers into a byte stream
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Body filter chain&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ngx_http_top_body_filter
  → ngx_http_range_body_filter
  → ngx_http_copy_filter            -- Copies in_file bufs to memory when necessary
  → ngx_http_gzip_body_filter
  → ngx_http_chunked_body_filter
  → ngx_http_write_filter           -- Ultimately calls c-&amp;gt;send_chain() to send
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Filter registration pattern:&lt;/p&gt;
&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Register in postconfiguration:&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ngx_int_t&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;ngx_http_my_init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ngx_conf_t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ngx_http_next_header_filter&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ngx_http_top_header_filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ngx_http_top_header_filter&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ngx_http_my_header_filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;ngx_http_next_body_filter&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ngx_http_top_body_filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ngx_http_top_body_filter&lt;/span&gt;     &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ngx_http_my_body_filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NGX_OK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Note: &lt;strong&gt;the last registered executes first&lt;/strong&gt; (because each is inserted at the head of the chain).&lt;/p&gt;

&lt;h4 id=&quot;65-location-matching&quot;&gt;6.5 Location Matching&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/ngx_http_core_module.c&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The matching algorithm in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_http_core_find_config_phase()&lt;/code&gt;:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_hash_lookup()&lt;/code&gt; on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;locations&lt;/code&gt; hash table for &lt;strong&gt;prefix matching&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;If the matched location has nested locations, search recursively&lt;/li&gt;
  &lt;li&gt;Finally, use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;regex_locations&lt;/code&gt; queue for &lt;strong&gt;regex matching&lt;/strong&gt; (highest priority, using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=~&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~*&lt;/code&gt;)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Configuration merge path&lt;/strong&gt;: after matching a location, its &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;loc_conf[module_index]&lt;/code&gt; has already correctly inherited from server and main level configurations via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;merge_loc_conf&lt;/code&gt; during the parsing phase.&lt;/p&gt;

&lt;h4 id=&quot;66-upstream-mechanism&quot;&gt;6.6 Upstream Mechanism&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/ngx_http_upstream.h&lt;/code&gt;&lt;/strong&gt; + &lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/ngx_http_upstream.c&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The upstream state machine:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ngx_http_upstream_init()
  → ngx_http_upstream_connect()           -- Establish connection to backend
    → ngx_http_upstream_send_request()    -- Send request body
      → ngx_http_upstream_process_header()  -- Parse response header
        → ngx_http_upstream_process_body_in_memory() or sendfile/pipe -- Forward response body
          → ngx_http_upstream_finalize_request()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Load balancing is &lt;strong&gt;pluggable&lt;/strong&gt; via the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_http_upstream_peer_t&lt;/code&gt; interface:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_http_upstream_round_robin.c&lt;/code&gt; — Weighted round-robin (default)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_http_upstream_hash_module.c&lt;/code&gt; — Consistent hashing&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_http_upstream_least_conn_module.c&lt;/code&gt; — Least connections&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_http_upstream_random_module.c&lt;/code&gt; — Random selection&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;step-7-supplementary-reading-as-needed&quot;&gt;Step 7: Supplementary Reading (as needed)&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Logging System&lt;/strong&gt;: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_log.h&lt;/code&gt; + &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_log.c&lt;/code&gt; — &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_log_t&lt;/code&gt; leveled logging, chained log objects&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Variable System&lt;/strong&gt;: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/ngx_http_variables.c&lt;/code&gt; — How variables like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$remote_addr&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$host&lt;/code&gt; are registered and evaluated&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Regex Engine&lt;/strong&gt;: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_regex.c&lt;/code&gt; — Wrapper around PCRE (nginx does not implement its own regex engine)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Shared Memory &amp;amp; Slab Allocator&lt;/strong&gt;: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_slab.c&lt;/code&gt; — Slab allocator for multi-process shared data&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;SSL/TLS&lt;/strong&gt;: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/event/ngx_event_openssl.c&lt;/code&gt; — How SSL is implemented by swapping &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;c-&amp;gt;recv/send&lt;/code&gt; function pointers&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;HTTP/2&lt;/strong&gt;: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/v2/&lt;/code&gt; — HTTP/2 frame parsing and multiplexing&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;QUIC/HTTP/3&lt;/strong&gt;: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/event/quic/&lt;/code&gt; + &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/v3/&lt;/code&gt; — QUIC transport layer and HTTP/3 implementation&lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;3-design-patterns-and-mindset-throughout&quot;&gt;3. Design Patterns and Mindset Throughout&lt;/h2&gt;

&lt;h3 id=&quot;31-intrusive-data-structures&quot;&gt;3.1 Intrusive Data Structures&lt;/h3&gt;

&lt;p&gt;nginx does not separately allocate list nodes or tree nodes. Instead, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_queue_t&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_rbtree_node_t&lt;/code&gt; are &lt;strong&gt;directly embedded&lt;/strong&gt; in the structs that use them. Zero extra allocation, extreme efficiency.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// Not: list&amp;lt;Item*&amp;gt; items (malloc a node for every insertion)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Instead: Item contains ngx_queue_t queue, linked in directly&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;32-pre-allocation--reuse&quot;&gt;3.2 Pre-allocation + Reuse&lt;/h3&gt;

&lt;p&gt;Connections, events, memory pools — all pre-allocated at startup, no &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;malloc&lt;/code&gt; at runtime. nginx’s philosophy: &lt;strong&gt;“Whatever maximum resources I can calculate at startup, I pre-allocate.”&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;33-io-function-pointer-polymorphism&quot;&gt;3.3 I/O Function Pointer Polymorphism&lt;/h3&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;recv&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ngx_ssl_recv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;// SSL module silently swaps these&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;send&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ngx_ssl_send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Higher-level code (the HTTP framework) is completely unaware whether the underlying transport is TCP, SSL, or QUIC. This is nginx’s key technique for protocol upgrades and SSL transparency.&lt;/p&gt;

&lt;h3 id=&quot;34-return-value-driven-control-flow&quot;&gt;3.4 Return-Value-Driven Control Flow&lt;/h3&gt;

&lt;p&gt;nginx does not use exceptions or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;goto&lt;/code&gt;. Instead, control intent is expressed through return values:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Return Value&lt;/th&gt;
      &lt;th&gt;Semantics&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NGX_OK&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Done, caller continues&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NGX_ERROR&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Error, abort&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NGX_AGAIN&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Insufficient resources (buffer full, data not arrived yet), pause and wait for the next event trigger&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NGX_DECLINED&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;I won’t handle this, try the next one (core of handler singly-linked list traversal)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NGX_DONE&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Handled, but the request is not finished (async operation pending)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NGX_BUSY&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Busy, retry later&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Understanding the difference between &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NGX_AGAIN&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NGX_DECLINED&lt;/code&gt; is particularly important — the former means “wait a bit and I’ll retry”, the latter means “move on to the next one.”&lt;/p&gt;

&lt;h3 id=&quot;35-graceful-zero-downtime&quot;&gt;3.5 Graceful Zero-Downtime&lt;/h3&gt;

&lt;p&gt;The core logic of configuration reload (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nginx -s reload&lt;/code&gt;):&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Master receives &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SIGHUP&lt;/code&gt; → creates a new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_cycle_t&lt;/code&gt;, forks new workers&lt;/li&gt;
  &lt;li&gt;Old workers receive &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SIGQUIT&lt;/code&gt; → graceful shutdown (finish existing connections before exiting)&lt;/li&gt;
  &lt;li&gt;Old and new workers briefly coexist; once old workers exit, the new cycle takes over&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This relies on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cycle-&amp;gt;old_cycle&lt;/code&gt; design: the new cycle holds a reference to the old cycle, releasing it after old workers exit.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;4-debugging-tips&quot;&gt;4. Debugging Tips&lt;/h2&gt;

&lt;h3 id=&quot;41-debug-logging&quot;&gt;4.1 Debug Logging&lt;/h3&gt;

&lt;p&gt;Build with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--with-debug&lt;/code&gt;, then set in the configuration:&lt;/p&gt;
&lt;div class=&quot;language-nginx highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;error_log&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;/var/log/nginx/debug.log&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;42-common-gdb-breakpoints&quot;&gt;4.2 Common GDB Breakpoints&lt;/h3&gt;

&lt;pre&gt;&lt;code class=&quot;language-gdb&quot;&gt;# Event loop entry
b ngx_process_events_and_timers

# Request processing entry
b ngx_http_process_request

# Phase engine
b ngx_http_core_run_phases

# Connection allocation
b ngx_get_connection

# Upstream connection
b ngx_http_upstream_connect

# All recv/send calls on a connection
b ngx_unix_recv
b ngx_unix_send
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;43-printing-ngx_str_t&quot;&gt;4.3 Printing ngx_str_t&lt;/h3&gt;

&lt;pre&gt;&lt;code class=&quot;language-gdb&quot;&gt;# ngx_str_t is not a C string — needs custom printing in GDB
define print_ngx_str
  set $s = (ngx_str_t*)$arg0
  printf &quot;%.*s\n&quot;, $s-&amp;gt;len, $s-&amp;gt;data
end
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;44-tracing-memory-allocation&quot;&gt;4.4 Tracing Memory Allocation&lt;/h3&gt;

&lt;p&gt;Set breakpoints at key functions in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_palloc.c&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_create_pool&lt;/code&gt; — Pool creation&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_palloc&lt;/code&gt; — Small block allocation&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_palloc_block&lt;/code&gt; — Allocate new pool block&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_pfree&lt;/code&gt; — Large block free&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_destroy_pool&lt;/code&gt; — Pool destruction&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;5-recommended-reading-practices&quot;&gt;5. Recommended Reading Practices&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Don’t try to read sequentially by file number&lt;/strong&gt;. nginx has many static functions and global variables. Read by header file dependency relationships.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Trace one functional path at a time&lt;/strong&gt;. For example, “the complete path of an HTTP GET request from reception to response” — only focus on functions on this path, ignore side branches.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Draw diagrams&lt;/strong&gt;. Struct nesting in nginx source code is very deep. Hand-drawing the following relationship diagrams will be very helpful:
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_cycle_t&lt;/code&gt; → &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conf_ctx&lt;/code&gt; → indexing relationships of each module’s configuration&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_connection_t&lt;/code&gt; → &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;read&lt;/code&gt; / &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;write&lt;/code&gt; → &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_event_t&lt;/code&gt; → &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;handler&lt;/code&gt; call chain&lt;/li&gt;
      &lt;li&gt;The checker → handler → next jump relationships in the HTTP phase engine&lt;/li&gt;
      &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_http_top_header_filter&lt;/code&gt; → &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;next&lt;/code&gt; → … order in the filter chain&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Start from simple third-party modules&lt;/strong&gt;. Read simple modules at the level of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/modules/ngx_http_echo_module.c&lt;/code&gt; to understand how handlers and filters are written.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Comparative reading&lt;/strong&gt;. Find two modules with similar functionality under &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/modules/&lt;/code&gt; (e.g., proxy vs fastcgi) and understand where they differ.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Re-read core functions&lt;/strong&gt;. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_process_events_and_timers()&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_http_core_run_phases()&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_conf_parse()&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_http_upstream_connect()&lt;/code&gt; — these functions are worth reading repeatedly; you’ll discover new details each time.&lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;6-core-file-index&quot;&gt;6. Core File Index&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;File&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;Priority&lt;/th&gt;
      &lt;th&gt;Core Content&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/nginx.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★★&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main()&lt;/code&gt; entry point&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_cycle.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★★&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ngx_init_cycle()&lt;/code&gt; cycle initialization&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_palloc.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★★&lt;/td&gt;
      &lt;td&gt;Memory pool implementation&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_buf.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★★&lt;/td&gt;
      &lt;td&gt;Buffer and chain operations&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_connection.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★★&lt;/td&gt;
      &lt;td&gt;Connection pre-allocation and management&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_conf_file.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★★&lt;/td&gt;
      &lt;td&gt;Configuration parser&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_module.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★★&lt;/td&gt;
      &lt;td&gt;Module loading and initialization&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_string.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★☆&lt;/td&gt;
      &lt;td&gt;String utility function collection&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_array.h&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★★&lt;/td&gt;
      &lt;td&gt;Dynamic array&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_list.h&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★★&lt;/td&gt;
      &lt;td&gt;Linked list + array hybrid&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_queue.h&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★★&lt;/td&gt;
      &lt;td&gt;Intrusive doubly-linked list&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_rbtree.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★☆&lt;/td&gt;
      &lt;td&gt;Red-black tree&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_hash.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★☆&lt;/td&gt;
      &lt;td&gt;Static hash table&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/core/ngx_log.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★☆&lt;/td&gt;
      &lt;td&gt;Logging system&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/os/unix/ngx_process_cycle.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★★&lt;/td&gt;
      &lt;td&gt;Master/worker process management&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/event/ngx_event.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★★&lt;/td&gt;
      &lt;td&gt;Event loop core&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/event/ngx_event_accept.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★☆&lt;/td&gt;
      &lt;td&gt;Accept and thundering herd handling&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/event/ngx_event_timer.h&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★☆&lt;/td&gt;
      &lt;td&gt;Timer management&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/event/modules/ngx_epoll_module.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★☆&lt;/td&gt;
      &lt;td&gt;epoll event module&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/ngx_http.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★★&lt;/td&gt;
      &lt;td&gt;HTTP framework initialization&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/ngx_http_request.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★★&lt;/td&gt;
      &lt;td&gt;Request lifecycle&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/ngx_http_core_module.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★★&lt;/td&gt;
      &lt;td&gt;Core directives, phase checkers&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/ngx_http_upstream.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★★&lt;/td&gt;
      &lt;td&gt;Upstream proxy mechanism&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/ngx_http_variables.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★☆&lt;/td&gt;
      &lt;td&gt;Variable system&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/ngx_http_header_filter.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★☆&lt;/td&gt;
      &lt;td&gt;Response header serialization&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/ngx_http_write_filter.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★☆&lt;/td&gt;
      &lt;td&gt;Final send to socket&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/modules/ngx_http_proxy_module.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★★☆&lt;/td&gt;
      &lt;td&gt;Typical HTTP proxy module&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/http/modules/ngx_http_static_module.c&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;★☆☆&lt;/td&gt;
      &lt;td&gt;Simplest content handler&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;hr /&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Final advice&lt;/strong&gt;: Reading the nginx source code is a marathon, not a sprint. The core code is about 100K lines, but the design is highly consistent. Once you master the patterns in the first 30%, the remaining 70% will go much faster. Happy reading!&lt;/p&gt;
&lt;/blockquote&gt;
</content>
    
    <category term="Nginx"/>
    
  </entry>
  
  <entry>
    <title>Problem 177: 第N高的薪水</title>
    <link href="https://wy471x.github.io/2021-02-23/problem-177-nth-highest-salary.html"/>
    <updated>2021-02-23T08:05:02+08:00</updated>
    <id>https://wy471x.github.io/2021-02-23/problem-177-nth-highest-salary.html</id>
    <content type="html">&lt;h2 id=&quot;177-第n高的薪水&quot;&gt;&lt;a href=&quot;https://leetcode-cn.com/problems/nth-highest-salary/&quot;&gt;177. 第N高的薪水&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;编写一个 SQL 查询，获取 Employee 表中第 n 高的薪水（Salary）。&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Id&lt;/th&gt;
      &lt;th&gt;Salary&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;100&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2&lt;/td&gt;
      &lt;td&gt;200&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;3&lt;/td&gt;
      &lt;td&gt;300&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;例如上述 Employee 表，n = 2 时，应返回第二高的薪水 200。如果不存在第 n 高的薪水，那么查询应返回 null。&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;getNthHighestSalary(2)&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;200&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;sql脚本：&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;Create&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;table&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;If&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Not&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Exists&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Employee&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Salary&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;Truncate&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;table&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Employee&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;insert&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;into&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Employee&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Salary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;insert&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;into&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Employee&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Salary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;insert&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;into&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Employee&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Salary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;解答&quot;&gt;解答&lt;/h2&gt;

&lt;p&gt;解法一：&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FUNCTION&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getNthHighestSalary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;N&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;INT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;RETURNS&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;INT&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;BEGIN&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;N&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;N&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;RETURN&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;#&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Write&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;your&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MySQL&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;query&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;statement&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;below&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;DISTINCT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Salary&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Employee&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;ORDER&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;BY&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Salary&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;DESC&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;LIMIT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;END&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;MySQL直接执行会遇到报错信息，解决方案请参考：&lt;a href=&quot;https://stackoverflow.com/questions/26015160/deterministic-no-sql-or-reads-sql-data-in-its-declaration-and-binary-logging-i&quot;&gt;DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled&lt;/a&gt;&lt;/p&gt;
</content>
    
    <category term="LeetCode-DataBase"/>
    
  </entry>
  
  <entry>
    <title>Problem 177: Nth Highest Salary</title>
    <link href="https://wy471x.github.io/en/2021-02-23/nth-highest-salary.html"/>
    <updated>2021-02-23T08:05:02+08:00</updated>
    <id>https://wy471x.github.io/en/2021-02-23/nth-highest-salary.html</id>
    <content type="html">&lt;h2 id=&quot;177-nth-highest-salary&quot;&gt;&lt;a href=&quot;https://leetcode.com/problems/nth-highest-salary/&quot;&gt;177. Nth Highest Salary&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Write a SQL query to get the nth highest salary from the Employee table.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Id&lt;/th&gt;
      &lt;th&gt;Salary&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;100&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2&lt;/td&gt;
      &lt;td&gt;200&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;3&lt;/td&gt;
      &lt;td&gt;300&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;For example, given the above Employee table, the nth highest salary where n = 2 is 200. If there is no nth highest salary, the query should return null.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;getNthHighestSalary(2)&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;200&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;SQL script:&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;Create&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;table&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;If&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Not&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Exists&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Employee&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Salary&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;Truncate&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;table&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Employee&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;insert&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;into&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Employee&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Salary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;insert&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;into&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Employee&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Salary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;insert&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;into&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Employee&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Salary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;solution&quot;&gt;Solution&lt;/h2&gt;

&lt;p&gt;Solution 1:&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FUNCTION&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getNthHighestSalary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;N&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;INT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;RETURNS&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;INT&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;BEGIN&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;N&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;N&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;RETURN&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;#&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;Write&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;your&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MySQL&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;query&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;statement&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;below&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;DISTINCT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Salary&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Employee&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;ORDER&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;BY&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Salary&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;DESC&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;LIMIT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;END&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you encounter errors running this directly in MySQL, refer to: &lt;a href=&quot;https://stackoverflow.com/questions/26015160/deterministic-no-sql-or-reads-sql-data-in-its-declaration-and-binary-logging-i&quot;&gt;DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled&lt;/a&gt;&lt;/p&gt;
</content>
    
    <category term="LeetCode-DataBase"/>
    
  </entry>
  
  <entry>
    <title>Git简易教程</title>
    <link href="https://wy471x.github.io/2021-02-21/git-tutorial.html"/>
    <updated>2021-02-21T21:51:18+08:00</updated>
    <id>https://wy471x.github.io/2021-02-21/git-tutorial.html</id>
    <content type="html">&lt;blockquote&gt;
  &lt;p&gt;将暂存区中文件恢复为和HEAD一样&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git reset HEAD&lt;/code&gt; 将暂存区中所有文件恢复为和HEAD一样&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git reset HEAD -- [filename]&lt;/code&gt; 将暂存区中名字为filename的文件恢复为和HEAD一样&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;比较暂存区和HEAD所含文件差异&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git diff --cached&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;比较工作区和暂存区所含文件差异&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git diff&lt;/code&gt; 默认比较暂存区和工作区的文件的区别&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git diff -- [filename]&lt;/code&gt; 比较工作区和暂存区中名字为filename的文件的内容的区别&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;将工作区中文件内容恢复为和暂存区中一样&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git checkout -- [filename]&lt;/code&gt; 将工作区中的名字为filename的文件恢复为和暂存区中一样&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;将暂存区和工作区的内容恢复至某次commit&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git reset --hard [commit code]&lt;/code&gt; 将工作区和暂存区中的内容恢复至与某次commit一样【慎用】&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;查看不同commit的指定文件的差异&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git diff [commit code 1] [commit code 2] -- [filename]&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;删除暂存区和工作区指定文件&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git rm [filename]&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;将变更进行存入临时栈空间&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git stash&lt;/code&gt; 将变更存入栈空间&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git stash apply&lt;/code&gt; 栈空间中的内容仍存在&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git stash pop&lt;/code&gt; 栈空间中的内容被移除&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;git仓库备份&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git clone --bare [remote git repository] [local git repository]&lt;/code&gt; 哑协议方式&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git clone --bare [file:///&amp;lt;remote git repository&amp;gt;] [local git repository]&lt;/code&gt; 智能协议方式&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git remote add [remote repository name] [file:///&amp;lt;remote git repository&amp;gt;]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git push --set-upstream [remote repository name] [branch name]&lt;/code&gt; 将本地分支推送至远程仓库&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git push [remote repository name] [branch name]&lt;/code&gt; 将本地分支推送至远程仓库&lt;/p&gt;
</content>
    
    <category term="Git教程"/>
    
  </entry>
  
  <entry>
    <title>Git Tutorial</title>
    <link href="https://wy471x.github.io/en/2021-02-21/git-tutorial.html"/>
    <updated>2021-02-21T21:51:18+08:00</updated>
    <id>https://wy471x.github.io/en/2021-02-21/git-tutorial.html</id>
    <content type="html">&lt;blockquote&gt;
  &lt;p&gt;Restore files in staging area to match HEAD&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git reset HEAD&lt;/code&gt; restores all files in staging area to match HEAD&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git reset HEAD -- [filename]&lt;/code&gt; restores the specified file in staging area to match HEAD&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Compare differences between staging area and HEAD&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git diff --cached&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Compare differences between working directory and staging area&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git diff&lt;/code&gt; compares differences between staging area and working directory&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git diff -- [filename]&lt;/code&gt; compares differences for the specified file&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Restore working directory files to match staging area&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git checkout -- [filename]&lt;/code&gt; restores the specified file in working directory to match staging area&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Restore both staging area and working directory to a specific commit&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git reset --hard [commit code]&lt;/code&gt; restores both staging area and working directory to match a specific commit [use with caution]&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Compare differences for a specified file between different commits&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git diff [commit code 1] [commit code 2] -- [filename]&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Remove a file from both staging area and working directory&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git rm [filename]&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Stash changes to a temporary stack&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git stash&lt;/code&gt; saves changes to the stack&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git stash apply&lt;/code&gt; applies changes while keeping them in the stack&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git stash pop&lt;/code&gt; applies changes and removes them from the stack&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Git repository backup&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git clone --bare [remote git repository] [local git repository]&lt;/code&gt; using dumb protocol&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git clone --bare [file:///&amp;lt;remote git repository&amp;gt;] [local git repository]&lt;/code&gt; using smart protocol&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git remote add [remote repository name] [file:///&amp;lt;remote git repository&amp;gt;]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git push --set-upstream [remote repository name] [branch name]&lt;/code&gt; push local branch to remote repository&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git push [remote repository name] [branch name]&lt;/code&gt; push local branch to remote repository&lt;/p&gt;
</content>
    
    <category term="Git-Tutorial"/>
    
  </entry>
  
  <entry>
    <title>Problem 175: 组合两个表</title>
    <link href="https://wy471x.github.io/2021-02-17/problem-175-combine-two-tables.html"/>
    <updated>2021-02-17T22:02:22+08:00</updated>
    <id>https://wy471x.github.io/2021-02-17/problem-175-combine-two-tables.html</id>
    <content type="html">&lt;h2 id=&quot;175-组合两个表&quot;&gt;&lt;a href=&quot;https://leetcode-cn.com/problems/combine-two-tables/&quot;&gt;175. 组合两个表&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;表1: Person&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;列名&lt;/th&gt;
      &lt;th&gt;类型&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;PersonId&lt;/td&gt;
      &lt;td&gt;int&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;FirstName&lt;/td&gt;
      &lt;td&gt;varchar&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;LastName&lt;/td&gt;
      &lt;td&gt;varchar&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PersonId&lt;/code&gt; 是上表主键&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;表2: Address&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;列名&lt;/th&gt;
      &lt;th&gt;类型&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;AddressId&lt;/td&gt;
      &lt;td&gt;int&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;PersonId&lt;/td&gt;
      &lt;td&gt;int&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;City&lt;/td&gt;
      &lt;td&gt;varchar&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;State&lt;/td&gt;
      &lt;td&gt;varchar&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AddressId&lt;/code&gt; 是上表主键&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;编写一个 SQL 查询，满足条件：无论 person 是否有地址信息，都需要基于上述两表提供 person 的以下信息：&lt;/p&gt;

&lt;p&gt;FirstName, LastName, City, State&lt;/p&gt;

&lt;p&gt;sql脚本：&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;Create&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;table&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PersonId&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FirstName&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;varchar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;255&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LastName&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;varchar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;255&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;Create&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;table&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Address&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AddressId&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PersonId&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;City&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;varchar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;255&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;State&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;varchar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;255&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;Truncate&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;table&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;insert&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;into&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PersonId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LastName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FirstName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;1&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Wang&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Allen&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;Truncate&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;table&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;insert&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;into&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Address&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AddressId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PersonId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;City&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;State&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;1&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;2&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;New York City&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;New York&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;解答&quot;&gt;解答&lt;/h2&gt;

&lt;p&gt;解法一：左联结（LEFT JOIN）&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;FirstName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;LastName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;City&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;State&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;Person&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;LEFT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;JOIN&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;Address&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;ON&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PersonId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PersonId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</content>
    
    <category term="LeetCode-Database"/>
    
  </entry>
  
  <entry>
    <title>Problem 175: Combine Two Tables</title>
    <link href="https://wy471x.github.io/en/2021-02-17/problem-175-combine-two-tables.html"/>
    <updated>2021-02-17T22:02:22+08:00</updated>
    <id>https://wy471x.github.io/en/2021-02-17/problem-175-combine-two-tables.html</id>
    <content type="html">&lt;h2 id=&quot;175-combine-two-tables&quot;&gt;&lt;a href=&quot;https://leetcode.com/problems/combine-two-tables/&quot;&gt;175. Combine Two Tables&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Table 1: Person&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Column Name&lt;/th&gt;
      &lt;th&gt;Type&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;PersonId&lt;/td&gt;
      &lt;td&gt;int&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;FirstName&lt;/td&gt;
      &lt;td&gt;varchar&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;LastName&lt;/td&gt;
      &lt;td&gt;varchar&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PersonId&lt;/code&gt; is the primary key for this table.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Table 2: Address&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Column Name&lt;/th&gt;
      &lt;th&gt;Type&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;AddressId&lt;/td&gt;
      &lt;td&gt;int&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;PersonId&lt;/td&gt;
      &lt;td&gt;int&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;City&lt;/td&gt;
      &lt;td&gt;varchar&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;State&lt;/td&gt;
      &lt;td&gt;varchar&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AddressId&lt;/code&gt; is the primary key for this table.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Write a SQL query that provides the following information for each person in the Person table, regardless of whether there is an address entry for that person:&lt;/p&gt;

&lt;p&gt;FirstName, LastName, City, State&lt;/p&gt;

&lt;p&gt;SQL script:&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;Create&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;table&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PersonId&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FirstName&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;varchar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;255&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LastName&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;varchar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;255&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;Create&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;table&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Address&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AddressId&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PersonId&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;City&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;varchar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;255&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;State&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;varchar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;255&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;Truncate&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;table&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;insert&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;into&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PersonId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LastName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FirstName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;1&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Wang&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Allen&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;Truncate&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;table&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;insert&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;into&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Address&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AddressId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PersonId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;City&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;State&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;1&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;2&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;New York City&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;New York&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;solution&quot;&gt;Solution&lt;/h2&gt;

&lt;p&gt;Solution 1: LEFT JOIN&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;FirstName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;LastName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;City&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;State&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Person&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;LEFT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;JOIN&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Address&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;ON&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PersonId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Address&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PersonId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</content>
    
    <category term="LeetCode-Database"/>
    
  </entry>
  
</feed>
