跳转至

link:NGINX 应用程序动态链接

需要 GetPageSpeed NGINX Extras 订阅的 Pro 计划(或更高版本)。

安装

您可以在任何基于 RHEL 的发行版中安装此模块,包括但不限于:

  • RedHat Enterprise Linux 7、8、9 和 10
  • CentOS 7、8、9
  • AlmaLinux 8、9
  • Rocky Linux 8、9
  • Amazon Linux 2 和 Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-link
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-link

通过在 /etc/nginx/nginx.conf 顶部添加以下内容来启用模块:

load_module modules/ngx_http_link_func_module.so;

本文档描述的是 nginx-module-link v3.2.6 发布于 2026 年 8 月 12 日。


NGINX 的原生 C/C++ 函数处理器 — 加载共享库并将请求直接路由到编译后的代码,零 IPC 开销。

概述

ngx_http_link_func 通过动态链接将 NGINX 与原生 C/C++ 应用程序桥接起来。共享库(.so 文件)在服务器启动时加载,HTTP 请求被直接分发到在 NGINX worker 进程内运行的导出 C 函数。

这意味着您的 C 代码可以直接访问 NGINX 内部结构 — 请求头、URI 参数、请求体、共享内存 — 并且无需序列化、套接字或上下文切换即可写入响应。

特性

  • 原生函数分发 — 将任何 location 路由到导出的 C 函数
  • 共享内存和缓存 — 基于 rbtree 的跨 worker 缓存,带互斥锁
  • 线程池卸载 — 支持 AIO 线程处理阻塞操作
  • 子请求集成 — 与 auth_request 链式配合实现认证流程
  • 远程库加载 — 启动时从 HTTP/HTTPS URL 获取 .so 文件
  • 生命周期钩子 — 用于资源管理的初始化和退出周期回调
  • 每服务器属性 — 将 nginx.conf 中的配置值传递给您的代码

快速开始

nginx.conf:

http {
    # 可选:用于跨 worker 缓存的共享内存
    ngx_link_func_shm_size 1m;

    server {
        listen 8080;

        # 加载您编译的应用程序
        ngx_link_func_lib "/opt/myapp/libhandlers.so";

        # 将配置值传递给您的应用程序
        ngx_link_func_add_prop "db_host" "localhost:5432";

        location /api/greeting {
            ngx_link_func_call "handle_greeting";
        }

        location /api/users {
            ngx_link_func_call "handle_users";
        }
    }
}

您的应用程序(handlers.c):

#include <ngx_link_func_module.h>

void ngx_link_func_init_cycle(ngx_link_func_cycle_t *cycle) {
    ngx_link_func_cyc_log(info, cycle, "%s", "Application started");
}

void handle_greeting(ngx_link_func_ctx_t *ctx) {
    ngx_link_func_write_resp(
        ctx, 200, "200 OK",
        ngx_link_func_content_type_json,
        "{\"message\":\"Hello from C\"}", 25
    );
}

void handle_users(ngx_link_func_ctx_t *ctx) {
    const char *token = ngx_link_func_get_query_param(ctx, "token");

    if (!token) {
        ngx_link_func_write_resp(
            ctx, 401, "401 Unauthorized",
            ngx_link_func_content_type_plaintext,
            "Missing token", 13
        );
        return;
    }

    // 处理已认证的请求...
    ngx_link_func_write_resp(
        ctx, 200, "200 OK",
        ngx_link_func_content_type_json,
        "{\"users\":[]}", 12
    );
}

void ngx_link_func_exit_cycle(ngx_link_func_cycle_t *cycle) {
    ngx_link_func_cyc_log(info, cycle, "%s", "Application shutting down");
}

构建和部署:

gcc -shared -o libhandlers.so -fPIC handlers.c
sudo cp libhandlers.so /opt/myapp/
sudo nginx -s reload

指令

上下文: main | 默认值:

设置用于跨 worker 缓存和数据共享的共享内存区域大小。

ngx_link_func_shm_size 10m;

上下文: server | 默认值:

为 server 块加载共享库。多个 server 块可以加载相同的库以共享内存。

ngx_link_func_lib "/opt/myapp/libhandlers.so";

上下文: location | 默认值:

按名称将请求路由到导出的 C 函数。

location /api/data {
    ngx_link_func_call "handle_data";
}

上下文: server | 默认值:

将键值属性传递给应用程序,可通过 ngx_link_func_get_prop() 访问。

ngx_link_func_add_prop "api_key" "secret123";

上下文: server | 默认值:

启动时从远程 URL 下载共享库。支持可选的 HTTP 头用于认证。

# 基本下载
ngx_link_func_download_link_lib "https://repo.example.com/libapp.so" "/opt/myapp/libapp.so";

# 带认证头
ngx_link_func_download_link_lib "https://repo.example.com/libapp.so"
    "Authorization:Bearer TOKEN\r\n"
    "/opt/myapp/libapp.so";

上下文: server | 默认值:

为 HTTPS 库下载设置 CA 证书。

ngx_link_func_ca_cert "/etc/ssl/certs/ca-certificates.crt";

上下文: location | 默认值:

添加请求头,通常用于将 NGINX 变量传递给子请求。

ngx_link_func_add_req_header "X-Real-IP" "$remote_addr";

上下文: location | 默认值:

配置子请求路由。需要 NGINX 使用 --with-http_auth_request_module 编译。

location /protected {
    ngx_link_func_subrequest "/auth";
}

应用程序 API

在您的应用程序中包含 <ngx_link_func_module.h>。该头文件提供了完整的 C API。

生命周期钩子

以下保留函数名由 NGINX 自动调用:

void ngx_link_func_init_cycle(ngx_link_func_cycle_t *cycle);  // 启动时
void ngx_link_func_exit_cycle(ngx_link_func_cycle_t *cycle);  // 关闭/重载时

请求上下文

每个处理器都会收到 ngx_link_func_ctx_t *ctx,包含:

字段 类型 描述
req_args char * 原始 URI 查询字符串
req_body u_char * 请求体
req_body_len size_t 请求体长度
shared_mem void * 共享内存指针

函数

函数 描述
响应
ngx_link_func_write_resp(ctx, status, status_line, content_type, body, len) 写入 HTTP 响应
ngx_link_func_write_resp_l(ctx, status, status_line, sl_len, ct, ct_len, body, len) 写入响应(显式长度)
请求数据
ngx_link_func_get_uri(ctx, &str) 获取请求 URI
ngx_link_func_get_remote_addr(ctx) 获取客户端远程地址
ngx_link_func_get_header(ctx, key, keylen) 按名称获取请求头
ngx_link_func_get_query_param(ctx, key) 按键获取查询参数
ngx_link_func_get_prop(ctx, key, keylen) 获取服务器属性
ngx_link_func_add_header_in(ctx, key, klen, val, vlen) 添加入站头
ngx_link_func_add_header_out(ctx, key, klen, val, vlen) 添加出站头
内存
ngx_link_func_palloc(ctx, size) 从 NGINX 池分配
ngx_link_func_pcalloc(ctx, size) 从 NGINX 池分配并清零
ngx_link_func_strdup(ctx, src) 从池中复制字符串
共享内存
ngx_link_func_shm_alloc(shm, size) 分配共享内存
ngx_link_func_shm_free(shm, ptr) 释放共享内存
ngx_link_func_shmtx_lock(shm) 获取互斥锁
ngx_link_func_shmtx_unlock(shm) 释放互斥锁
ngx_link_func_shmtx_trylock(shm) 尝试获取互斥锁
缓存
ngx_link_func_cache_get(shm, key) 获取缓存值
ngx_link_func_cache_put(shm, key, value) 存储缓存值
ngx_link_func_cache_new(shm, key, size) 分配并缓存
ngx_link_func_cache_remove(shm, key) 从缓存中移除
日志
ngx_link_func_log_debug/info/warn/err(ctx, msg) 记录日志消息
ngx_link_func_log(level, ctx, fmt, ...) 记录格式化消息

内容类型常量

ngx_link_func_content_type_plaintext  // "text/plain"
ngx_link_func_content_type_html       // "text/html; charset=utf-8"
ngx_link_func_content_type_json       // "application/json"
ngx_link_func_content_type_jsonp      // "application/javascript"
ngx_link_func_content_type_xformencoded // "application/x-www-form-urlencoded"

Linux

gcc -shared -o libmyapp.so -fPIC myapp.c

macOS

clang -dynamiclib -o libmyapp.dylib -fPIC myapp.c -Wl,-undefined,dynamic_lookup ```