在高性能Web服务器领域,NGINX凭借轻量、高效的架构,能够处理大流量负载,因此广受青睐。随着共享字典功能作为NGINX JavaScript模块(njs)的一部分推出,NGINX的性能得到进一步提升。
本文将介绍njs共享字典的功能和优势,并说明如何配置NGINX Open Source,以便在轮换SSL/TLS证书时无需重启。
共享字典的基础知识与优势
新的js_shared_dict_zone指令允许NGINX Open Source用户启用共享内存区域,以便在工作进程之间高效交换数据。这些共享内存区域充当键值字典,用于存储可实时访问和修改的动态配置设置。
共享字典的主要优势包括:
- 开销极低且易于使用:直接内置于njs,凭借直观的API和简单的实现方式,可轻松配置和使用。它还有助于简化工作进程之间的数据管理与共享流程。
- 轻量高效:与NGINX无缝集成,充分利用其事件驱动的非阻塞I/O模型。这种方式可减少内存占用并提升并发能力,使NGINX能够高效处理大量并发连接。
- 可扩展性:利用NGINX跨多个工作进程横向扩展的能力,可在这些进程之间共享和同步数据,无需复杂的进程间通信机制。生存时间(TTL)设置可用于管理共享字典条目中的记录,将因不活跃而过期的记录从区域中移除。
evict参数会移除最早的键值对,为新条目腾出空间。
使用共享字典轮换SSL证书
共享字典的一项重要用例是SSL/TLS轮换。使用js_shared_dict_zone时,更新SSL/TLS证书或密钥无需重启NGINX。此外,它还提供类似REST的API,用于管理NGINX上的证书。
以下NGINX配置文件示例使用js_set和ssl_certificate指令设置HTTPS服务器。JavaScript处理程序使用js_set从文件中读取SSL/TLS证书或密钥。
此配置片段使用共享字典,将证书和密钥存储在共享内存中作为缓存。如果缓存中不存在相应的键,则从磁盘读取证书或密钥并将其放入缓存。
还可以公开一个用于清除缓存的location。磁盘上的文件更新后(例如证书和密钥续期后),共享字典会强制从磁盘读取文件。这样无需重启NGINX进程即可轮换证书和密钥。
http { ...
js_shared_dict_zone zone=kv:1m;
server {
…
# Sets an njs function for the variable. Returns a value of cert/key
js_set $dynamic_ssl_cert main.js_cert;
js_set $dynamic_ssl_key main.js_key;
# use variable's data
ssl_certificate data:$dynamic_ssl_cert;
ssl_certificate_key data:$dynamic_ssl_key;
# a location to clear cache
location = /clear {
js_content main.clear_cache;
# allow 127.0.0.1;
# deny all;
}
...
}以下是使用“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 '';
}
}
/**
* Retrieves the key/cert value from Shared memory or fallback to disk
*/
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(`Read ${key} from cache`);
return data;
}
}
try {
data = fs.readFileSync(path, 'utf8');
r.log('Read from cache');
} catch (e) {
data = '';
r.log(`Error reading from file:${path}. Error=${e}`);
}
if (cache && data) {
try {
cache.set(key, data);
r.log('Persisted in cache');
} catch (e) {
const errMsg = `Error writing to shared dict zone: ${zone}. Error=${e}`;
r.log(errMsg);
}
}
return data
}
发送/clear请求后,缓存将失效,NGINX会在下一次SSL/TLS握手时从磁盘加载SSL/TLS证书或密钥。此外,还可以实现一个js_content,从请求中获取SSL/TLS证书或密钥,同时持久化并更新缓存。
此示例的完整代码可在njs GitHub 仓库中找到。
立即开始
共享字典功能是增强应用可编程性的强大工具,在简化流程和提升可扩展性方面具有显著优势。利用js_shared_dict_zone的功能,可以开拓新的增长空间,并高效应对不断增长的流量需求。
准备好使用js_shared_dict_zone增强NGINX部署了吗?借助js_shared_dict_zone升级NGINX部署,即可解锁新的用例。有关此功能的更多信息,请参阅我们的文档。此外,还可在近期推出的njs-acme项目中查看共享字典功能的完整示例。该项目支持njs模块运行时与ACME提供商协同工作。
如果您有兴趣开始使用NGINX Open Source并有任何疑问,加入NGINX Community Slack,介绍一下自己,并认识这个NGINX用户社区的成员!
相关博客文章
NGINX Plus R26 正式发布
NGINX Plus R26通过缓存JSON Web密钥集加快JWT验证,并强化TLS握手,从而提升安全性。NGINX JavaScript的新功能包括增强对异步函数的支持,以及实现WebCrypto API。
使用NGINX App Protect DoS保护gRPC应用,抵御严重的DoS攻击
gRPC具备开发人员设计和部署现代应用所需的速度与灵活性,但其开放性也使其极易受到第7层DoS攻击。NGINX App Protect DoS可保护gRPC应用免受此类破坏性攻击。
Ingress Controller 选型指南(第 2 部分):风险与面向未来的规划
了解选择错误的Ingress控制器可能带来的风险,以及如何从关键方面着手,让您的选择更好地适应未来需求。
NGINX Plus R19 正式发布
NGINX Plus R19扩展了监控功能,不仅提供更多指标,还新增了指标分析方式;增加试运行模式,用于测试限速效果;增强键值存储,以支持IP地址范围;并使限速更加动态。
NGINX现已正式加入F5
NGINX现已正式成为F5的一部分。Gus Robertson现任F5 NGINX业务部门负责人。他阐述了两家公司在人才、文化和愿景方面融合的价值,以及双方将如何携手增强NGINX的开源产品和商业产品。
