Преглед изворни кода

增加内存存储兼容redis连接失败

zhusiqing пре 4 година
родитељ
комит
0c4c67aad6
4 измењених фајлова са 72 додато и 7 уклоњено
  1. 1 0
      package.json
  2. 1 1
      src/config.ts
  3. 58 6
      src/middlewares/redis.ts
  4. 12 0
      yarn.lock

+ 1 - 0
package.json

@@ -25,6 +25,7 @@
     "koa-session": "^6.0.0",
     "koa-static": "^5.0.0",
     "log4js": "^6.3.0",
+    "node-cache": "^5.1.2",
     "nodemon": "^2.0.4",
     "pm2": "^4.4.1",
     "redis": "^3.0.2"

+ 1 - 1
src/config.ts

@@ -13,7 +13,7 @@ export = {
     // 单位时间内,秒
     time: 60,
     // 请求次数
-    times: 3
+    times: 30
   },
   // logs
   logs: {

+ 58 - 6
src/middlewares/redis.ts

@@ -1,14 +1,41 @@
 import redis from 'redis';
+// 内存存储
+import nodeCache from 'node-cache';
 import util from 'util';
 import consola from 'consola/dist/consola';
 import config from '../config';
 
+// 是否使用redis
+let isUseRedis: boolean = true
+// 内存存储实例化
+const cache = new nodeCache()
+
 // 创建redis连接
 const client = redis.createClient({
   host: config.redis.host,
   port: config.redis.port,
   password: config.redis.password,
-  auth_pass: config.redis.password
+  auth_pass: config.redis.password,
+  retry_strategy: function(options) {
+    if (options.error && options.error.code === "ECONNREFUSED") {
+      // redis连接失败时使用内存存储
+      isUseRedis = false
+      // End reconnecting on a specific error and flush all commands with
+      // a individual error
+      return new Error("The server refused the connection");
+    }
+    if (options.total_retry_time > 1000 * 60 * 60) {
+      // End reconnecting after a specific timeout and flush all commands
+      // with a individual error
+      return new Error("Retry time exhausted");
+    }
+    if (options.attempt > 10) {
+      // End reconnecting with built in error
+      return undefined;
+    }
+    // reconnect after
+    return Math.min(options.attempt * 100, 3000);
+  }
 });
 
 client.on('error', err => {
@@ -19,6 +46,7 @@ client.on('ready', () => {
 });
 client.on('connect', () => {
   consola.success('redis is connecting');
+  isUseRedis = true
 });
 client.on('reconnecting', () => {
   consola.success('redis is reconnecting...');
@@ -26,9 +54,6 @@ client.on('reconnecting', () => {
 client.on('end', () => {
   consola.success('redis is closed');
 });
-client.on('end', () => {
-  consola.success('redis is closed');
-});
 
 // redis查询和设置await/async化
 const promisify = util.promisify
@@ -36,14 +61,41 @@ const getClient = promisify(client.get).bind(client);
 const setClient = promisify(client.set).bind(client);
 const setexClient = promisify(client.setex).bind(client);
 
+// 内存存储promise化,为了和redis使用方法保持一致
+const getCache = (key: string): Promise<string> => {
+  return new Promise(resolve => {
+    resolve(cache.get(key))
+  })
+}
+const setCache = (key: string, value: string, ttl: number = 0): Promise<boolean> => {
+  return new Promise((resolve, reject) => {
+    const success = cache.set(key, value, ttl)
+    if (success) {
+      resolve(success)
+    } else {
+      reject(success)
+    }
+  })
+}
+const setexCache = (key: string, ttl: number, value: string, ) => setCache(key, value, ttl)
+
 // 初始化测试
-client.setex('test', 30, '111111');
+// client.setex('test', 30, '111111');
 // send_sms_verify_code_sms_
 // 18339012129
 
 export = () => {
   return async (ctx, next) => {
-    ctx.$redis = { set: setClient, get: getClient, setex: setexClient };
+    console.log(isUseRedis);
+    if (isUseRedis) { // 如果redis连接失败,采用内存
+      ctx.$redis = { set: setClient, get: getClient, setex: setexClient };
+    } else {
+      ctx.$redis = {
+        set: setCache,
+        get: getCache,
+        setex: setexCache
+      }
+    }
     await next();
   };
 };

+ 12 - 0
yarn.lock

@@ -554,6 +554,11 @@ clone-response@^1.0.2:
   dependencies:
     mimic-response "^1.0.0"
 
+clone@2.x:
+  version "2.1.2"
+  resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f"
+  integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=
+
 co-body@^6.0.0:
   version "6.0.0"
   resolved "https://registry.yarnpkg.com/co-body/-/co-body-6.0.0.tgz#965b9337d7f5655480787471f4237664820827e3"
@@ -1730,6 +1735,13 @@ nocache@2.1.0:
   resolved "https://registry.yarnpkg.com/nocache/-/nocache-2.1.0.tgz#120c9ffec43b5729b1d5de88cd71aa75a0ba491f"
   integrity sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q==
 
+node-cache@^5.1.2:
+  version "5.1.2"
+  resolved "https://registry.yarnpkg.com/node-cache/-/node-cache-5.1.2.tgz#f264dc2ccad0a780e76253a694e9fd0ed19c398d"
+  integrity sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==
+  dependencies:
+    clone "2.x"
+
 nodemon@^2.0.4:
   version "2.0.4"
   resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.4.tgz#55b09319eb488d6394aa9818148c0c2d1c04c416"