Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js Redis没有缓存,而是每次都转到MongoDB_Node.js_Mongodb_Mongoose_Redis - Fatal编程技术网

Node.js Redis没有缓存,而是每次都转到MongoDB

Node.js Redis没有缓存,而是每次都转到MongoDB,node.js,mongodb,mongoose,redis,Node.js,Mongodb,Mongoose,Redis,我正在尝试让Redis启动并运行,我让服务器正常工作。然而,当我运行负载测试时,我看到每个查询仍然会转到我的mongoDB,而不是首先查看Redis。我的Redis服务器终端是: 41136:M 22 Sep 2020 14:00:00.641 * Background saving terminated with success 41136:M 22 Sep 2020 14:01:01.074 * 10000 changes in 60 seconds. Saving... 41136:M 2

我正在尝试让Redis启动并运行,我让服务器正常工作。然而,当我运行负载测试时,我看到每个查询仍然会转到我的mongoDB,而不是首先查看Redis。我的Redis服务器终端是:

41136:M 22 Sep 2020 14:00:00.641 * Background saving terminated with success
41136:M 22 Sep 2020 14:01:01.074 * 10000 changes in 60 seconds. Saving...
41136:M 22 Sep 2020 14:01:01.076 * Background saving started by pid 42406
42406:C 22 Sep 2020 14:01:05.256 * DB saved on disk
41136:M 22 Sep 2020 14:01:05.305 * Background saving terminated with success
41136:M 22 Sep 2020 14:02:06.043 * 10000 changes in 60 seconds. Saving...
41136:M 22 Sep 2020 14:02:06.052 * Background saving started by pid 42439
42439:C 22 Sep 2020 14:02:10.719 * DB saved on disk
41136:M 22 Sep 2020 14:02:10.784 * Background saving terminated with success
41136:M 22 Sep 2020 14:03:11.030 * 10000 changes in 60 seconds. Saving...
41136:M 22 Sep 2020 14:03:11.033 * Background saving started by pid 42480
42480:C 22 Sep 2020 14:03:17.592 * DB saved on disk
41136:M 22 Sep 2020 14:03:17.690 * Background saving terminated with success
然而,当我查看New Relic仪表板时,我发现响应时间非常慢(至少10000毫秒),这都是来自MongoDB的。Redis仅占用约15-16ms,其余10000 ms为MongoDB

但是,我的MongoDB索引正确,因为那里的查询只需要1毫秒。我还在database.js文件中使用了.lean()方法

我在用火炮进行负载测试

以下是我的服务器的index.js文件供参考:

require('newrelic');
const express = require('express');
const bodyParser = require('body-parser');
const Images = require('../database-mongo/index.js');
const cors = require('cors');
const redis = require('redis');
const client = redis.createClient();
const RedisServer = require('redis-server');

const server = new RedisServer(6379);
const PORT = 3003;

const app = express();
app.use(cors());

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

app.use(express.static(__dirname + '/../react-client/dist'));

server.open((err) => {
  if (err === null) {
    console.log('redis server working')
  }
})

let redisMiddleware = (req, res, next) => {
  let key = "__expIress__" + req.originalUrl || req.url;
  client.get(key, function (err, reply) {
    if (reply) {
      res.send(reply);
    } else {
      res.sendResponse = res.send;
      res.send = (body) => {
        client.set(key, JSON.stringify(body));
        res.sendResponse(body);
      }
      next();
    }
  });
};


app.get('/images/urls/:itemId', redisMiddleware, (req, res) => {
  Images.fetchItemImages(Number(req.params.itemId))
    .then((data) => {
      if (data) {
        res.status(200).send({ data });
      } else {
        res.sendStatus(404);
      }
    })
    .catch((err) => {
      console.log('error with app.get: ', err);
      res.status(500).send(err);
    })
})

app.listen(PORT, () => {
  console.log(`listening on port ${PORT}`);
});

module.exports = app
以下是我的数据库的index.js文件:

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/images', { useNewUrlParser: true, useUnifiedTopology: true });

var db = mongoose.connection;

db.on('error', function (err) {
  console.log('mongoose connection error: ', err);
});

db.once('open', function () {
  console.log('mongoose connected successfully');
});

const imageSchema = new mongoose.Schema({
  itemId: Number,
  pic1Small: String,
  pic1Med: String,
  pic1Large: String,
  pic2Small: String,
  pic2Med: String,
  pic2Large: String
});

const Image = mongoose.model('url', imageSchema);


function fetchItemImages(itemId) {
  // console.log('fetchImages invoked')
  return Image.find({ 'itemId': Number(itemId) }).lean()
}

module.exports = Image;
module.exports.fetchItemImages = fetchItemImages;

我找到了解决办法。缺少两部分。首先,Redis中间件需要有一行代码,在返回JSON时解析JSON,因此它应该如下所示:

let redisMiddleware = (req, res, next) => {
  let key = "__expIress__" + req.originalUrl || req.url;
  client.get(key, function (err, reply) {
    if (reply) {
      res.send(JSON.parse(reply));
    } else {
      res.sendResponse = res.send;
      res.send = (body) => {
        client.set(key, JSON.stringify(body));
        res.sendResponse(body);
      }
      next();
    }
  });
};
其次,GET请求需要有.set方法,假设Redis数据库中有数据

app.get('/images/urls/:itemId', redisMiddleware, (req, res) => {
  db.fetchItemImages(req.params.itemId)
    .then((data) => {
      if (data) {
        client.set(req.params.itemId, JSON.stringify({ data }))
        res.status(200).send({ data });
      } else {
        res.sendStatus(404);
      }
    })
    .catch((err) => {
      console.log('error with app.get: ', err);
      res.status(500).send(err);
    })
})
发生的事情是,没有任何东西被保存到Redis,因此,当Redis在火炮测试中的每一次测试中都被检查时,没有任何东西被输入Redis