njs无法直接遍历shared memory zone,需通过约定键结构(如user:1001:session)或外部索引实现前缀批量删除;示例采用固定后缀集硬编码拼接键名并调用shm.delete()清理,配合白名单校验、日志与限流保障安全。

使用 NJS(NGINX JavaScript)编写自定义集群清理逻辑,实现对特定前缀的批量擦除,核心在于:利用 NJS 访问共享内存(shared memory zone),遍历键名匹配前缀,并调用 shm.delete() 删除。但需注意——NJS 原生不支持直接遍历 shared memory zone 中的所有 key,因此需配合外部记录或约定式键结构来实现“伪遍历”。
依赖前提:正确配置 shared memory zone 与 NJS 模块
确保 NGINX 已启用 ngx_http_js_module,并在配置中声明带名字的 shared memory zone(例如 my_cache),且大小足够容纳预期键值:
js_import cleanup.js;
js_set $cleanup_result cleanup.clearByPrefix;
<p>proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=30m use_temp_path=off;</p><h1>在 server 或 location 中启用 JS 处理</h1><p>location /api/cleanup {
add_header Content-Type "application/json";
return 200 '{"status":"ok","deleted": $cleanup_result}';
}</p>约定键结构:让前缀可识别、可筛选
NJS 无法枚举 shm 区域内所有 key,所以推荐采用“显式前缀 + 分隔符 + 唯一标识”的键命名方式(如 user:1001:session、user:1001:profile)。这样只需知道前缀(如 user:1001:),就能构造出待删键列表。
实际清理时,可结合以下策略之一:
-
维护索引键:每次写入主键时,同步写入一个索引键(如
index:user:1001),其 value 是 JSON 数组记录所有子键;清理时读取该索引,逐个删除再删索引本身。 -
固定子键集:若业务已知子键类型(如
session、token、config),直接硬编码拼接删除(shm.delete("user:1001:session")等)。 -
借助外部协调服务:将 key 列表存于 Redis 或数据库,NJS 调用
fetch()获取后批量删 shm —— 此法绕过 shm 局限,但引入外部依赖。
在 cleanup.js 中实现前缀清理函数
以下为基于“固定子键集”方式的简洁示例(无外部依赖,适合可控场景):
DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
// cleanup.js
const shm = ngx.shared.my_cache;
<p>function clearByPrefix(prefix) {
const suffixes = ['session', 'token', 'config', 'meta'];
let count = 0;</p><pre class="brush:php;toolbar:false;">for (let i = 0; i <p>}</p><p>export default { clearByPrefix };</p>调用时传入前缀如 "user:1001:",即可批量清除对应键。注意:shm.delete() 返回 true 表示删除成功(key 存在并被删),false 表示 key 不存在或删除失败。
安全与可观测性建议
生产环境不建议暴露无鉴权的清理接口。应增加:
-
简单校验:检查
prefix是否符合白名单正则(如^user:\d+:$),拒绝非法字符串。 -
速率限制:用
limit_req控制清理接口调用频次。 -
日志记录:在 NJS 中用
ngx.log(ngx.INFO, `Cleared ${count} keys for ${prefix}`)记录操作。 -
幂等设计:重复调用同一前缀不会报错,
delete对不存在 key 无副作用。
不复杂但容易忽略:shared memory zone 的生命周期独立于 worker 进程,删除操作是即时生效且跨 worker 可见的;但 NJS 脚本本身不能触发 zone 扫描,一切键操作必须基于已知 key 名。所以“批量擦除”的本质,是把“发现 key”这件事前置到业务逻辑或外部系统中完成。










