在高性能 Web 服务器领域, NGINX是一个受欢迎的选择,因为其轻量级、高效的架构使其能够处理大量流量。 随着NGINX JavaScript 模块(njs)中共享字典功能的引入,NGINX 的性能能力达到了一个新的水平。
在这篇博文中,我们探讨了 njs 共享字典的功能和优势,并展示了如何设置 NGINX 开源,而无需在轮换 SSL/TLS 证书时重新启动。
新的js_shared_dict_zone
指令允许 NGINX 开源用户启用共享内存区域,以便在工作进程之间实现高效的数据交换。 这些共享内存区域充当键值字典,存储可实时访问和修改的动态配置设置。
共享词典的主要优点包括:
evict
参数删除最旧的键值对,为新条目腾出空间。共享字典最有影响力的用例之一是 SSL/TLS 轮换。 使用js_shared_dict_zone
时,如果发生 SSL/TLS 证书或密钥更新,则无需重新启动 NGINX。 此外,它还为您提供了类似 REST 的 API 来管理 NGINX 上的证书。
下面是 NGINX 配置文件的示例,它使用js_set
和ssl_certificate
指令设置 HTTPS 服务器。 JavaScript 处理程序使用js_set
从文件中读取 SSL/TLS 证书或密钥。
此配置片段使用共享字典将证书和密钥存储在共享内存中作为缓存。 如果密钥不存在,那么它会从磁盘读取证书或密钥并将其放入缓存中。
您还可以显示清除缓存的位置。 一旦磁盘上的文件更新(例如,证书和密钥被更新),共享字典就会强制从磁盘读取。 此调整允许轮换证书/密钥,而无需重新启动 NGINX 进程。
http {...js_shared_dict_zone区域=kv:1m;
服务器 {...# 为变量设置一个 njs 函数。 返回 cert/key 的值 js_set $dynamic_ssl_cert main.js_cert; js_set $dynamic_ssl_key main.js_key;
# 使用变量的数据 ssl_certificate 数据:$dynamic_ssl_cert; ssl_certificate_key 数据:$dynamic_ssl_key;
# 清除缓存的位置 location = /clear { js_content main.clear_cache; # 允许 127.0.0.1; # 全部拒绝; }
... }
以下是使用js_shared_dict_zone
轮换 SSL/TLS 证书和密钥的 JavaScript 实现:
function js_cert(r) { if (r.variables['ssl_server_name']) { return read_cert_or_key(r, '.cert.pem'); } else { return ''; } } function js_key(r) { if (r.variables['ssl_server_name']) { return read_cert_or_key(r, '.key.pem'); } else { return ''; } } /** * 从共享内存中检索密钥/证书值或回退到磁盘 */ function read_cert_or_key(r, fileExtension) { let data = ''; let path = ''; const zone = 'kv'; let certName = r.variables.ssl_server_name; let prefix = '/etc/nginx/certs/'; path = prefix + certName + fileExtension; r.log('Resolving${path} '); const key = ['certs', path].join(':'); const cache = zone && ngx.shared && ngx.shared[zone];
if (cache) { data = cache.get(key) || ''; if (data) { r.log(`读取${key}从缓存中读取'); 返回数据; } } try { data = fs.readFileSync(path, 'utf8'); r.log('从缓存中读取'); } catch (e) { data = ''; r.log(`从文件读取时出错:${path} 。 错误=${e} `); } if (cache && data) { try { cache.set(key, data); r.log('持久存储在缓存中'); } catch (e) { const errMsg = `写入共享字典区域时出错:${zone} 。 错误=${e} `; r.log(errMsg); } } 返回数据 }
通过发送/clear
请求,缓存将失效,并且 NGINX 将在下一次 SSL/TLS 握手时从磁盘加载 SSL/TLS 证书或密钥。 此外,您可以实现一个js_content
,它从请求中获取 SSL/TLS 证书或密钥,同时持久保存并更新缓存。
此示例的完整代码可以在njs GitHub repo中找到。
共享字典功能是您的应用程序可编程性的强大工具,在精简和可扩展性方面带来了显著的优势。 通过利用js_shared_dict_zone
的功能,您可以释放新的增长机会并有效处理不断增长的流量需求。
准备好使用js_shared_dict_zone
增强你的 NGINX 部署了吗? 您可以使用js_shared_dict_zone
升级您的 NGINX 部署以解锁新的用例,并在我们的文档中了解有关此功能的更多信息。 此外,您还可以在最近推出的njs-acme 项目中看到共享字典功能的完整示例,这使得 njs 模块运行时能够与 ACME 提供程序一起工作。
如果您有兴趣开始使用 NGINX 开源并且有疑问,请加入 NGINX 社区 Slack – 介绍自己并了解这个 NGINX 用户社区!
“这篇博文可能引用了不再可用和/或不再支持的产品。 有关 F5 NGINX 产品和解决方案的最新信息,请探索我们的NGINX 产品系列。 NGINX 现在是 F5 的一部分。 所有之前的 NGINX.com 链接都将重定向至 F5.com 上的类似 NGINX 内容。”