分享个人 Full-Stack JavaScript 项目开发经验
Redis 是一个高效的开源内存数据结构存储系统,非常适合于类似 Session 信息这样的高频读写和有时效性的键值对数据存储。本文将会介绍如果在 Koa2 应用中集成 Redis 客户端以连接 Redis 集群,其中还包括容器信号的处理方式等。
这里客户端采用的是 NodesRedis 的 npm 库,它是一个高性能的 Node.js Redis 客户端库。它的 API 全部是非堵塞异步的,并且实例方法跟 Redis 命令一致,参数传递方式非常友好。下面是 lib/redis/index.js 的一个例子:
const redis = require('redis');const config = require('../../config/index');const {host, port, no_ready_check, total_retry_time} = config.redis;const client = redis.createClient({host,port,no_ready_check,retry_strategy: function (options) {// 超出重连时间后,不再重连if (options.total_retry_time > total_retry_time) {// 当 redis 服务器响应为拒绝连接时,结束重连if (options.error && options.error.code === 'ECONNREFUSED') {return new Error("The Redis server refused the connection.");}return new Error("Redis retry time exhausted");} else {// 不超过 3000 毫秒重连一次return Math.min(options.attempt * 100, 3000);}}});client.on('error', function (error) {console.error(error);});client.on('connect', function () {console.log('Redis connected.')});client.on('reconnecting', function () {console.log('Redis reconnecting......')});client.on('ready', function () {process.send('ready');});module.exports = client;
从上面代码中可以看到,客户端的连接配置来自于一份应用程序的全局配置。它是一个 "唯一来源" 原则的良好实践,开发环境下大可以直接使用开发配置,甚至将配置提交到版本控制系统就可以了。其它开发成员直接从版本控制系统中得到开发配置。 当部署到生产环境时,运维人员直接将生产环境配置以 Secret 卷方式挂载到容器内即可。与环境变量相比,内存文件系统亦更为安全。
从上面代码中,我们还处理了如下事情:
接下来是将客户端实例添加到 app 上下文中:
/* ==========================================================================创建 Redis 实例于 app 上下文中========================================================================== */app.context.redis = require("./lib/redis");
/* ==========================================================================PM2 SIGINT 信号处理========================================================================== */process.on('SIGINT', function () {let flag = false;const callback = () => {flag ? process.exit(0) : flag = true;};app.context.mysql.destroy(callback);app.context.redis.quit(callback);});
Redis 是很好的 Session 外部存储解决方案,Session 以及请求序列号等键值对存储机制是防止如跨域请求伪造和重放攻击等的基础。以上就是 Koa2 集成 Redis 客户端的全部内容。