nginx共享内存需为特定功能显式声明命名、定大小的内存区域,并配合对应模块使用;常见于限流、连接限制、缓存元数据及ssl会话复用,须合理设大小、确保原子操作与锁机制,并通过ipcs或stub_status验证生效。

配置 Nginx 共享内存的核心不是“开启开关”,而是为特定功能显式声明一块命名、定大小、可复用的内存区域,并确保模块能安全读写其中的数据。它不自动生效,必须配合对应模块(如限流、缓存、状态统计)使用。
明确用途,选择对应指令
共享内存本身无通用接口,必须通过具体功能模块的 zone 指令来创建。常见场景与配置示例如下:
-
限流(IP 级请求频率控制):
limit_req_zone $binary_remote_addr zone=ip_limit:10m rate=10r/s;
→ 创建名为ip_limit、大小 10MB 的共享内存区,存储令牌桶状态 -
连接限制(单 IP 并发连接数):
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
→ 名为conn_limit的共享区,记录各 IP 当前活跃连接数 -
代理缓存元数据(Key 索引与过期时间):
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=cache_one:50m max_size=1g inactive=60m;
→keys_zone=cache_one:50m即定义共享内存区,50MB 专存缓存 key 和元信息 -
SSL 会话复用缓存:
ssl_session_cache shared:SSL:10m;
→ 创建名为SSL、10MB 的共享区,供所有 worker 复用 session ticket
合理设置大小,避免频繁淘汰或浪费
大小配置直接影响性能与稳定性。太小会导致哈希冲突高、条目被强制淘汰;太大则占用无谓资源。参考原则:
- 限流/连接限制:每个键(如一个 IP)约占用 64–128 字节。若预计支持 10 万个唯一客户端,建议至少
zone=xxx:12m - 缓存 keys_zone:每 1MB 可存储约 8000–12000 个 key(取决于 key 长度)。实际值可通过
nginx -V 2>&1 | grep -o 'configure arguments.*'查看是否启用--with-http_ssl_module等影响内存布局的选项 - 避免动态扩容:Nginx 共享内存不可运行时扩大,配置中必须一步到位。上线前可用压测工具模拟真实 key 分布做预估
确保 worker 进程能协同访问
共享内存由 master 进程创建并初始化,所有 fork 出的 worker 自动继承映射。但需注意:
- 所有读写操作必须在模块逻辑内完成,不能在 handler 中 malloc 新结构体写入共享内存——所有数据必须基于
shm.addr偏移布局,或使用ngx_slab_pool_t分配器 - 多 worker 同时修改同一字段时,必须加锁或用原子操作:
• 计数类(如失败次数)优先用ngx_atomic_fetch_add()
• 复合更新(如累加响应时间)需包裹ngx_shmtx_lock/unlock() - 不要在信号处理函数中直接操作共享内存内容,应在 event loop 安全上下文中读取标志后执行
验证与监控配置是否生效
配置完成后,需确认共享内存已正确挂载并被使用:
- 检查系统级共享内存段:
ipcs -m | grep nginx→ 应看到名称匹配(如ip_limit)、大小一致的段 - 查看 Nginx 内部状态:
启用stub_status模块后访问/nginx_status,其中Active connections等统计即来自共享内存中的原子变量 - 日志排查:
若 worker 启动时报shared memory zone "xxx" is unknown,说明对应模块未启用或指令位置错误(必须在 http 块顶层)











