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}`))
重启程序,再次请求,请求时间如图:
效果立竿见影