Redis + Node.js: 请求缓存

reference to: https://community.risingstack.com/redis-node-js-introduction-to-caching/

请求第三方APIs

下面是一个简单的app,用来请求GitHub’s public API,得到某组织下的仓库。

const express = require('express')
const superagent = require('superagent')
const PORT = 3000

const app = express()

function getNumberOfRepos(req, res, next) {
    const org = req.query.org
    superagent.get(`https://api.github.com/orgs/${org}/repos`, (err, response) => {
        if (err) throw err

        var num = response.body.length
        res.send(`Organization "${org}" has ${num} public repositories.`)
    })
}

app.get('/repos', getNumberOfRepos)

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

运行程序,在浏览器中请求http://localhost:3000/repos?org=risingstack
然后发现下图
这里写图片描述
这么慢的请求肯定经不住大量请求。

如何优化呢。

可以考虑对请求结果进行缓存。也许你会问,返回缓存结果会不会导致返回不准确。
优化肯定是区分场景的,不同场景有不同优化方法。如果请求频繁,但是返回结果很少变化,那么这个时候就可以使用缓存进行优化了。

使用 redis 缓存

在nodejs中使用redis很简单。
首先安装redis client。(假设已经安装了redis server)

npm install redis
然后再nodejs中使用redis client.

const client = redis.createClient(REDIS_PORT);

redis 缓存数据

使用redis就像使用一般编程语言中的hash map一样简单。

  • 添加数据

    client.set(‘some key’, ‘some value’);

  • 设置过期时间

    client.setex(‘some key’, 3600, ‘some value’);

接上面的例子,将请求结果缓存到redis中:

var repoNumber = response.body.length;  
client.setex(org, 5, repoNumber);  
res.send(respond(org, repoNumber));  

读取缓存

当请求再次到达时,先从redis缓存中读取数据。
在nodejs中先弄个请求中间件来完成读取缓存:

app.get('/repos', cache, getNumberOfRepos);

function cache(req, res, next) {  
    const org = req.query.org;
    client.get(org, function (err, data) {
        if (err) throw err;

        if (data != null) {
            res.send(respond(org, data));
        } else {
            next();
        }
    });
}

完整程序如下:

const express = require('express')
const superagent = require('superagent')
const redis_client = require('redis').createClient(6379)
const PORT = 3000

const app = express()

function getNumberOfRepos(req, res) {
    const org = req.query.org
    superagent.get(`https://api.github.com/orgs/${org}/repos`, (err, response) => {
        if (err) throw err

        var num = response.body.length
        redis_client.setex(org, 10, num)
        res.send(`Organization "${org}" has ${num} public repositories.`)
    })
}

function cache(req, res, next) {
    const org = req.query.org
    redis_client.get(org, (err, data) => {
        if (err) throw err

        if (data != null) {
            res.send(`Organization "${org}" has ${data} public repositories.`)
        } else {
            next()
        }
    })
}

app.get('/repos', cache, getNumberOfRepos)

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

重启程序,再次请求,请求时间如图:
这里写图片描述

效果立竿见影

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值