插件窝 干货文章 nginx中的共享内存如何使用

nginx中的共享内存如何使用

内存 共享 shared ngx 309    来源:    2025-04-25

Nginx 共享内存使用详解

Nginx 中的共享内存(shared memory)是多个 worker 进程间通信的重要机制,主要用于缓存、统计信息共享等场景。以下是关于 Nginx 共享内存的详细使用方法:

1. 共享内存的基本概念

Nginx 共享内存是通过 ngx_shared_memory_add 函数在配置解析阶段分配的,所有 worker 进程都能访问同一块内存区域。

2. 配置共享内存

在 nginx.conf 中通过 shared_memory 指令配置:

http {
    # 定义一个名为"one"的共享内存区,大小为10MB
    lua_shared_dict one 10m;

    # 定义另一个共享内存区
    lua_shared_dict two 5m;

    # 其他配置...
}

3. 在 Nginx 模块中使用共享内存

3.1 定义共享内存区

在模块中定义共享内存区:

typedef struct {
    ngx_str_t    name;
    size_t       size;
    void        *data;
} ngx_http_shared_memory_t;

static ngx_http_shared_memory_t  ngx_http_shared_memory[] = {
    { ngx_string("one"), 1024*1024*10, NULL },
    { ngx_string("two"), 1024*1024*5, NULL },
    { ngx_null_string, 0, NULL }
};

3.2 初始化共享内存

在模块的 postconfiguration 阶段初始化:

static ngx_int_t
ngx_http_shared_memory_init(ngx_conf_t *cf)
{
    ngx_http_shared_memory_t  *shm;

    for (shm = ngx_http_shared_memory; shm->name.len; shm++) {
        ngx_shm_zone_t *zone;

        zone = ngx_shared_memory_add(cf, &shm->name, shm->size, 
                                    &ngx_http_shared_memory_module);
        if (zone == NULL) {
            return NGX_ERROR;
        }

        zone->init = ngx_http_shared_memory_init_zone;
        zone->data = shm;
    }

    return NGX_OK;
}

3.3 实现初始化回调

static ngx_int_t
ngx_http_shared_memory_init_zone(ngx_shm_zone_t *zone, void *data)
{
    ngx_http_shared_memory_t *shm = data;

    if (zone->data) {
        shm->data = zone->data;
        return NGX_OK;
    }

    zone->data = ngx_slab_alloc(zone->shm.addr, sizeof(ngx_slab_pool_t));
    if (zone->data == NULL) {
        return NGX_ERROR;
    }

    ngx_slab_init(zone->data, zone->shm.addr, zone->shm.size);

    shm->data = zone->data;

    return NGX_OK;
}

4. 在 Lua 中使用共享内存

Nginx 通过 ngx.shared.DICT 接口提供 Lua 访问共享内存的能力:

local shared_data = ngx.shared.one

-- 设置值
local success, err, forcible = shared_data:set("key", "value")
if not success then
    ngx.say("set failed: ", err)
    return
end

-- 获取值
local value = shared_data:get("key")
ngx.say("value: ", value)

-- 原子递增
local newval, err = shared_data:incr("counter", 1)
if err then
    ngx.say("incr failed: ", err)
    return
end

-- 删除键
shared_data:delete("key")

5. 共享内存操作注意事项

  1. 原子性操作:Nginx 提供了原子性的 get/set/incr 等操作
  2. 内存管理:共享内存使用 slab 分配器管理内存
  3. 锁机制:Nginx 使用自旋锁保护共享内存访问
  4. 性能考虑:频繁的共享内存操作会影响性能

6. 共享内存应用场景

  1. 缓存共享(如 Lua 共享字典)
  2. 限流计数器
  3. 全局统计信息
  4. 进程间通信

7. 常见问题解决

问题1:共享内存分配失败 - 检查系统共享内存限制:sysctl -a | grep shm - 增加系统共享内存限制:sysctl -w kernel.shmmax=新值

问题2:共享内存碎片 - 定期清理不用的键 - 合理设置共享内存大小

问题3:性能问题 - 减少不必要的共享内存操作 - 使用批量操作替代多次单次操作

通过合理使用 Nginx 共享内存,可以实现高效的进程间通信和数据共享,显著提升应用性能。