Apache APISIX 源码阅读指南

Categories: APISIX

Read in English

Apache APISIX 源码阅读指南

前言

Apache APISIX 是一个基于 OpenResty(Nginx + LuaJIT)构建的动态、高性能 API 网关。本文档旨在帮助开发者快速建立对 APISIX 源码结构的整体认知,并按合理的顺序深入阅读关键模块。

前置知识建议:

  • 熟悉 Nginx/OpenResty 的请求处理阶段(rewrite → access → content → header_filter → body_filter → log)
  • 了解 Lua 的基本语法和模块系统
  • 了解 etcd 的基本概念(etcd 是 APISIX 的默认配置中心)

一、项目顶层结构总览

apisix/
├── apisix/                 # Lua 核心源码(项目的心脏)
│   ├── core/               # 基础库(日志、JSON、配置、请求/响应、缓存等)
│   ├── admin/              # Admin API 实现(CRUD 操作)
│   ├── plugins/            # HTTP 插件(90+ 插件)
│   ├── http/               # HTTP 子模块(路由匹配器等)
│   ├── stream/             # 四层代理(TCP/UDP)
│   ├── control/            # Control API(内部管理接口)
│   ├── discovery/          # 服务发现(Consul、Nacos、Eureka 等)
│   ├── balancer/           # 负载均衡算法
│   ├── secret/             # 密钥管理后端
│   ├── utils/              # 工具模块
│   ├── cli/                # 命令行工具(启停、配置生成)
│   └── init.lua            # 主入口,定义所有 OpenResty 阶段钩子
├── bin/apisix              # Shell 启动脚本
├── conf/                   # 运行时配置
│   ├── config.yaml         # 用户配置
│   ├── config-default.yaml # 默认配置
│   └── ...
├── t/                      # Perl 测试套件(Test::Nginx)
│   ├── admin/              # Admin API 测试
│   ├── plugin/             # 各插件测试(250+ 文件)
│   ├── core/               # 核心模块测试
│   ├── lib/                # 测试辅助库
│   └── ...
├── docs/                   # 文档(en + zh)
└── Makefile                # 构建/部署/测试命令

二、启动流程(建议从这里开始阅读)

这是理解整个系统的切入点,沿着启动链路从头读到尾,可以建立对系统骨架的整体认知。

2.1 Shell 入口 → Lua CLI

bin/apisix  ──→  apisix/cli/apisix.lua  ──→  apisix/cli/ops.lua
  • bin/apisix(Shell 脚本,约 50 行):定位 OpenResty 和 apisix/cli/apisix.lua,然后执行 luajit <apisix.lua> <命令参数>
  • apisix/cli/apisix.lua:设置 Lua 模块搜索路径,然后委托给 apisix.cli.ops 执行
  • apisix/cli/ops.lua:实现 init / start / stop / restart / reload 等命令

2.2 nginx.conf 生成

当执行 apisix start 时,ops.luainit() 函数会:

  1. 读取 YAML 配置 → 用 apisix/cli/schema.lua 做 schema 校验
  2. 通过 apisix/cli/ngx_tpl.lua(nginx 配置模板引擎)生成 conf/nginx.conf

2.3 Worker 初始化

生成的 nginx.conf 中指定了 Lua 入口为 apisix/init.lua,该文件定义了完整的请求处理生命周期:

-- init.lua 中定义的关键函数
http_init(args)          -- 全局初始化(只执行一次)
http_init_worker()       -- 每个 worker 进程的初始化
http_access_phase()      -- 请求接入阶段(路由匹配、插件执行的核心)
http_header_filter_phase()
http_body_filter_phase()
http_log_phase()         -- 日志/上报阶段

http_init_worker() 中的初始化顺序(值得关注):

  1. 随机种子、LRU 缓存、DNS 解析器
  2. discovery.init_worker() — 服务发现
  3. balancer.init_worker() — 负载均衡器
  4. admin.init_worker() — Admin API
  5. plugin.load() — 加载所有插件(按优先级排序)
  6. router.http_init_worker() — HTTP 路由表初始化
  7. require("apisix.http.service").init_worker() — Service 对象初始化
  8. 监听配置变更(etcd watch),实现热更新

三、核心模块体系(apisix/core/

apisix/core.lua 是一个外观模块(Facade),将所有核心子模块聚合到一个 core 表中:

模块 文件 职责
core.log core/log.lua 日志输出(warn/error/info/debug)
core.json core/json.lua JSON 编解码,支持延迟编码优化
core.table core/table.lua 表工具函数(deepcopy、merge 等)
core.request core/request.lua 请求头部/Body 读写
core.response core/response.lua 响应头部设置、退出、CORS
core.schema core/schema.lua JSON Schema 校验器封装
core.config core/config_etcd.lua / core/config_yaml.lua 配置提供者(etcd / 本地 YAML / xDS)
core.lrucache core/lrucache.lua LRU 缓存,支持 TTL
core.ctx core/ctx.lua 请求上下文管理(tablepool 复用)
core.etcd core/etcd.lua etcd 客户端封装
core.string core/string.lua 字符串工具函数
core.id core/id.lua ID 生成器(支持雪花 ID)
core.dns.client core/dns/ DNS 客户端
core.pubsub core/pubsub.lua 发布/订阅抽象
core.event core/event.lua Worker 间事件系统

关键设计模式: 所有模块通过 require("apisix.core") 获取统一的 core 引用,避免散乱的依赖关系。


四、请求处理流程(最核心的链路)

当用户请求到达 APISIX 后,经过如下阶段(都在 apisix/init.lua 中定义):

第一阶段:http_access_phase() — 接入与路由匹配

1. HTTPS 客户端证书校验
2. Debug 动态调试检查
3. URI 规范化(尾部斜杠处理、servlet 路径处理)
4. X-Forwarded-* 请求头处理
5. Router 匹配 → 找到匹配的 Route
6. 无匹配 Route → 执行 Global Rules → 返回 404
7. 合并配置:
   plugin_config_id → service_id → consumer → consumer_group
8. 执行 Global Rules
9. 有 script → 执行 script 脚本
10. 否则 → 过滤插件 → 依次执行 rewrite 阶段插件 → access 阶段插件
11. handle_upstream():
    - 通过 upstream_id 或内联 upstream 获取上游配置
    - 负载均衡器选择后端节点
    - 执行 before_proxy 阶段
    - 代理请求到上游

第二/三阶段:Header/Body 过滤

header_filter → 设置 Server 头、上游状态头 → 执行 header_filter 插件
body_filter   → 执行 body_filter 插件 & delayed_body_filter 插件

第四阶段:http_log_phase() — 日志上报

完成 Tracing span → 执行 log 阶段插件 → 被动健康检查 → 释放 api_ctx

关键数据结构:api_ctx

每个请求会从 tablepool 分配一个 api_ctx 表,携带:

  • matched_route — 匹配到的路由
  • upstream_conf — 上游配置
  • plugins — 要执行的插件列表
  • consumer — 消费者信息
  • var — Nginx 变量快照

该表贯穿所有阶段,在 log 阶段结束时释放回 tablepool。


五、插件系统(apisix/plugin.lua + apisix/plugins/

5.1 插件加载机制

apisix/plugin.lua 是插件引擎,核心函数:

  • load():读取配置的插件列表 → 逐个调用 load_plugin() → 按优先级降序排序
  • load_plugin(name):require 插件模块 → 校验 priority/version/schema → 调用 plugin.init() → 注入 _meta 字段
  • run_plugin(phase, ...):按阶段执行插件链
  • filter_plugins(user_plugins, conf_version):根据 Route 配置筛选要执行的插件

5.2 插件接口规范

每个插件模块导出以下字段(以 apisix/plugins/example-plugin.lua 为参考):

local plugin_name = "example-plugin"

local _M = {
    version = 0.1,          -- 插件版本号(必填)
    priority = 0,            -- 执行优先级(必填,数字越大越先执行)
    name = plugin_name,      -- 插件名称
    schema = {},             -- JSON Schema 定义(必填)
    type = 'auth',           -- 插件类型(选填,auth 类型有特殊处理)
}

生命周期钩子(均可选):

  • init() / destroy() — 加载/卸载时调用
  • check_schema(conf, schema_type) — 自定义 schema 校验
  • rewrite(conf, ctx) / access(conf, ctx) — 请求处理
  • header_filter(conf, ctx) / body_filter(conf, ctx) — 响应处理
  • delayed_body_filter(conf, ctx) — 延迟 body 过滤
  • log(conf, ctx) — 日志上报
  • api() / control_api() — 注册额外的 Admin/Control API

5.3 插件优先级体系

插件按 priority 降序执行,部分关键插件的优先级参考:

优先级范围 典型插件 说明
4000+ ip-restriction, referer-restriction 安全拦截类
3000-3999 cors, csrf, fault-injection 安全/测试类
2500-2999 key-auth, jwt-auth, basic-auth 认证类
1000-1999 limit-count, limit-conn, limit-req 限流类
500-999 proxy-rewrite, response-rewrite 重写类
1-499 日志插件, prometheus 可观测类

5.4 插件分类速览

类别 代表插件
认证 key-auth, jwt-auth, basic-auth, hmac-auth, openid-connect, forward-auth
安全 ip-restriction, ua-restriction, cors, csrf, uri-blocker, api-breaker
限流 limit-count, limit-conn, limit-req, traffic-split
重写 proxy-rewrite, redirect, response-rewrite, proxy-mirror
Serverless serverless-pre-function, serverless-post-function
AI ai-proxy, ai-prompt-decorator, ai-prompt-guard, ai-rag, ai-rate-limiting
日志 kafka-logger, http-logger, syslog, elasticsearch-logger, loki-logger 等
可观测 prometheus, zipkin, skywalking, opentelemetry, datadog
集成 aws-lambda, azure-functions, grpc-transcode, grpc-web, dubbo-proxy

六、Admin API 与 CRUD 体系(apisix/admin/

6.1 架构

HTTP 请求 → admin/init.lua(Token 认证 + 路由分发)→ resource.lua(通用 CRUD)→ etcd

apisix/admin/init.lua 中定义了资源到处理模块的映射:

资源 处理模块 对应用途
routes admin/routes.lua 路由管理
services admin/services.lua 服务管理
upstreams admin/upstreams.lua 上游管理
consumers admin/consumers.lua 消费者管理
ssls admin/ssl.lua SSL 证书管理
global_rules admin/global_rules.lua 全局规则
plugin_configs admin/plugin_config.lua 插件配置复用
stream_routes admin/stream_routes.lua 四层路由
secrets admin/secrets.lua 密钥管理

6.2 通用 CRUD 模式(admin/resource.lua

这是一个经典的模板方法模式。每个资源模块通过 resource.new({...}) 创建,自动获得 GET/PUT/POST/DELETE/PATCH 的标准实现。具体每个资源的差异通过 schemavalidatorid_schema 等配置项注入。


七、路由系统(apisix/router.lua + apisix/http/router/

7.1 路由实现

APISIX 支持 3 种 HTTP 路由实现(基于 lua-resty-radixtree):

实现 匹配依据 文件
radixtree_uri 仅 URI http/router/radixtree_uri.lua
radixtree_host_uri Host + URI http/router/radixtree_host_uri.lua
radixtree_uri_with_parameter URI + 参数 http/router/radixtree_uri_with_parameter.lua

此外还有:

  • SSL 路由:ssl/router/radixtree_sni.lua(基于 SNI 匹配)
  • Stream 路由:基于 IP:Port 匹配

7.2 Route → Service → Upstream 的层级关系

Route ──可选引用──→ Service ──可选引用──→ Upstream
  │                    │                      │
  └── 定义 URI/Host    └── 共享公共配置      └── 后端节点池
      匹配规则              (plugins等)            (负载均衡配置)

配置合并顺序:plugin_config → consumer → consumer_group → route → service


八、负载均衡(apisix/balancer.lua + apisix/balancer/

balancer.lua 是负载均衡的调度中心,负责在请求处理时创建 balancer 对象并选择合适的后端节点。

支持的算法(apisix/balancer/):

  • roundrobin.lua — 加权轮询
  • chash.lua — 一致性哈希
  • ewma.lua — 指数加权移动平均(最小延迟算法)
  • least_conn.lua — 最小连接数
  • priority.lua — 优先级

九、配置管理与热更新

9.1 配置提供者抽象

APISIX 支持三种配置来源,通过 config.yaml 中的 config_provider 切换:

  • etcdcore/config_etcd.lua):默认模式,通过 etcd watch 实现实时热更新
  • yamlcore/config_yaml.lua):独立模式,从本地 YAML/JSON 文件读取
  • xDScore/config_xds.lua):对接 Envoy xDS 控制面

三种提供者实现同一接口:

init()  init_worker()  values(key)  conf_version()

9.2 etcd 热更新流程

etcd PUT /routes/xxx → core/config_etcd.lua watch 回调
  → 路由表重建 → 新请求使用新路由(无需 reload Nginx)

同理适用于 Service、Upstream、Plugin、SSL 证书等所有配置。


十、测试体系(t/

APISIX 使用 Perl 版 Test::Nginx::Socket::Lua 作为测试框架。

启动文件:

  • t/APISIX.pm — 测试基础配置和辅助函数
  • t/lib/ — 测试辅助库

目录结构:

  • t/admin/ — Admin API CRUD 测试(60+ 文件)
  • t/plugin/ — 插件测试(250+ 文件)
  • t/core/ — 核心模块测试(35+ 文件)
  • t/cli/ — CLI 测试
  • t/stream-node/, t/stream-plugin/ — 四层代理测试

测试用例结构示例:

use t::APISIX;
use Test::Nginx::Socket::Lua;

run_tests();

__DATA__
=== TEST 1: 测试描述
--- config
    location /t {
        content_by_lua_block {
            -- 测试逻辑
        }
    }
--- response_body
期望的输出
--- no_error_log
[error]

十一、建议的阅读顺序

按照以下顺序阅读,可以逐步建立起对整个系统的完整认知:

第一阶段:骨架(建立全局观)

  1. bin/apisix — 启动脚本,了解如何拉起 OpenResty
  2. apisix/cli/apisix.lua + apisix/cli/ops.lua — CLI 命令处理,了解 init/start 等命令的实现
  3. apisix/init.lua — 主入口文件,重点关注 http_init_worker() 的初始化顺序和 http_access_phase() 的请求处理流程

第二阶段:核心模块(理解基础设施)

  1. apisix/core.lua — 核心模块聚合入口,了解有哪些核心能力
  2. apisix/core/ctx.lua — 请求上下文,理解 api_ctx 的创建/释放机制
  3. apisix/core/config_etcd.lua — etcd 配置提供者,理解配置如何读取和热更新
  4. apisix/core/lrucache.lua — 缓存机制
  5. apisix/core/request.lua + apisix/core/response.lua — 请求/响应操作封装

第三阶段:核心引擎(理解关键链路)

  1. apisix/router.lua + apisix/http/router/radixtree_uri.lua — 路由匹配机制
  2. apisix/plugin.lua — 插件引擎,理解插件加载、过滤、执行的生命周期
  3. apisix/upstream.lua + apisix/balancer.lua — 上游管理和负载均衡
  4. apisix/http/service.lua — Route → Service 的配置继承逻辑

第四阶段:Admin API(理解控制面)

  1. apisix/admin/init.lua — Admin API 路由分发
  2. apisix/admin/resource.lua — 通用 CRUD 基类
  3. apisix/admin/routes.lua — 以 Route CRUD 为例,理解具体资源的实现方式

第五阶段:深入插件(实践出真知)

  1. apisix/plugins/example-plugin.lua — 插件开发模板
  2. 选择一个你感兴趣的简单插件深入阅读(推荐从 key-auth.lualimit-count.lua 开始)
  3. 阅读 apisix/plugins/ai-proxy.lua — 了解复杂插件的结构和 AI 网关能力

第六阶段:扩展话题

  1. apisix/stream/ — 四层代理子系统
  2. apisix/discovery/ — 服务发现(consul/nacos/eureka 等)
  3. apisix/secret/ — 密钥管理
  4. t/ — 测试编写,通过测试反向理解功能

十二、关键设计模式总结

模式 体现位置 说明
外观模式 apisix/core.lua 聚合所有核心子模块,统一访问入口
模板方法 apisix/admin/resource.lua 通用 CRUD 基类,子模块注入差异化配置
策略模式 apisix/router.lua / apisix/balancer.lua 可插拔的路由/负载均衡实现
插件生命周期 apisix/plugin.lua + apisix/plugins/*.lua 按优先级排序,分阶段执行
观察者模式 apisix/core/config_etcd.lua 中的 etcd watch 配置变更自动触发热更新
对象池模式 tablepool + apisix/core/ctx.lua 复用 api_ctx 表,减少 GC 压力
提供者抽象 core/config_etcd.lua / core/config_yaml.lua / core/config_xds.lua 统一的配置接口,可切换后端

十三、开发环境搭建(速查)

# 安装依赖
make deps

# 启动 APISIX
make run

# 停止
make stop

# 运行测试
make test

# 运行特定测试
prove -I t/ t/plugin/key-auth.t

# 代码风格检查
make lint

建议配合 Apache APISIX 官方文档 和源码中的注释一起阅读。遇到问题时,t/ 目录下的测试用例是理解各项功能的最佳参考资料。

Read More

Nginx 源码阅读指南

【2026-07-23】Nginx 源码阅读指南 - 从环境搭建、核心数据结构、进程模型到 HTTP 请求处理全链路的系统化阅读路线