在Express中缓存响应

6
我在使用Express框架进行响应缓存时遇到了麻烦... 我有一个端点会收到很多请求(约5k rpm),这个端点从mongodb取回数据,为了加快速度,我想将完整的JSON响应缓存1秒钟,以便每秒只有第一个请求访问数据库,其他请求都从缓存中获取。
当我抽象出问题的数据库部分,我的解决方案如下:我检查Redis中是否有缓存响应。如果找到了,则返回它。如果没有,则生成响应,并设置缓存。超时是为了模拟数据库操作。
app.get('/cachedTimeout', function(req,res,next) {
  redis.get(req.originalUrl, function(err, value) {
    if (err) return next(err);
    if (value) {
      res.set('Content-Type', 'text/plain');
      res.send(value.toString());
    } else {
      setTimeout(function() {
        res.send('OK');
        redis.set(req.originalUrl, 'OK');
        redis.expire(req.originalUrl, 1);
      }, 100);
    }
  });
});

问题在于这不仅会使第一次请求每秒命中数据库。而且,在我们有时间设置缓存之前(100毫秒之前)到达的所有请求都将命中数据库。当加入真正的负载时,响应时间会因许多请求落后而大幅增加,最高可达60秒。
我知道这可以通过像Varnish这样的反向代理解决,但目前我们正在Heroku上托管,这会使这种设置变得更加复杂。
我想做的是在Express内部进行某种形式的反向代理缓存。我希望在生成缓存的初始请求之后,所有接收到的请求都等待缓存生成完成,然后再使用相同的响应。
这可能吗?
2个回答

3

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接