Redis 是一款開源的,基於 BSD 許可的,高級鍵值緩存和存儲系統。Redis 的鍵包括 string,hash,list,set,sorted set,bitmap 和 hyperloglog。你能夠在這些類型上面運行原子操做,例如,追加字符串,增長哈希中的值,加入一個元素到列表,計算集合的交集、並集和差集,或者是從有序集合中獲取最高排名的元素。node
要在 Egg.js 中使用 redis,只須要安裝 npm i redis 便可git
經過一個例子來驗證一下,建立一個能夠返回開源倉庫在 Github 上的 star 數量的數據接口,來測試使用 Redis 後帶來的提高github
代碼地址: github.com/xrr2016/egg…redis
原文連接: coldstone.fun/post/2019/0…npm
首先使用 Egg.js 建立一個項目json
mkdir egg-redis-test && cd egg-redis-test
npm init egg --type=simple
npm i
複製代碼
安裝 redisapi
npm i redis
複製代碼
啓動項目緩存
npm run dev
open http://localhost:7001
複製代碼
先建立 controller 和 service 目錄,用來放處理請求和返回數據的方法,完成後的項目目錄爲bash
修改 router.js 文件,添加路由,而後在 controller/home.js 文件實現 stars 方法app
'use strict'
module.exports = app => {
const { router, controller } = app
router.get('/', controller.home.index)
router.get('/stars', controller.home.stars)
}
複製代碼
修改 controller/home.js 文件,接收請求傳過來的 query 參數向下傳給 stars service 返回結果
'use strict'
const Controller = require('egg').Controller
class HomeController extends Controller {
async stars() {
const { ctx, service } = this
const { owner, name } = ctx.query
ctx.body = await service.home.stars(owner, name)
}
}
module.exports = HomeController
複製代碼
在 service/home.js 裏實現 stars 方法,須要作的就是經過 controller 傳過來的 owner, name 參數,請求 Github 的接口,返回數據。
須要注意的是,這裏請求的是 Github 的 graphql 接口,因此首先須要在 Github 上新建一個 token,token 不能直接寫在代碼裏面,須要將 token 放在環境變量裏,不然代碼提交到 Github 後會失效。
建立 token 後使用 dotenv 保存環境變量,先安裝而後在項目目錄建立一個 .env 文件
npm i dotenv
複製代碼
而後就可使用 egg.js 自帶的 crul 方法向 Github 接口發送 post 請求,代碼以下
'use strict'
require('dotenv').config()
const Service = require('egg').Service
class HomeService extends Service {
async stars(owner, name) {
function setResponse(name, stars) {
return { msg: `${name} has ${stars} stars.` }
}
const query = ` query { repository(owner: ${owner}, name: ${name}) { stargazers { totalCount } } } `
const result = await this.ctx.curl('https://api.github.com/graphql', {
method: 'POST',
dataType: 'json',
headers: {
Authorization: `token ${process.env.TOKEN}`
},
data: JSON.stringify({ query }),
timeout: 10000
})
const data = result.data.data
return setResponse(name, data.repository.stargazers.totalCount)
}
}
module.exports = HomeService
複製代碼
使用 postman 測試一下接口
耗時平均 1 秒左右,接下來就是使用 Redis 添加緩存,首先須要在本地安裝 Redis,參考 Redis download,Mac 能夠直接使用 homebrew 安裝
安裝
brew install redis
複製代碼
啓動
redis-server /usr/local/etc/redis.conf
複製代碼
進入 redis 命令行
redis-cli
複製代碼
緩存的主要邏輯就是,第一次請求完獲得 Github 的數據將數據放到緩存中,再次請求的時候直接使用緩存中的數據,也須要給緩存設置一個過時時間。 請求時須要從環境變量中拿到 token,請求的數據要用 JSON.stringify 方法傳給 Github 接口,不然會出現解析錯誤
代碼以下
'use strict'
require('dotenv').config()
const redis = require('redis')
const { promisify } = require('util')
const Service = require('egg').Service
const REDIS_PORT = process.env.PORT || 6379
const client = redis.createClient(REDIS_PORT)
const getAsync = promisify(client.get).bind(client)
const setexAsync = promisify(client.setex).bind(client)
class HomeService extends Service {
async stars(owner, name) {
const key = `${owner}/${name}`
const stars = await getAsync(key)
function setResponse(name, stars) {
return { msg: `${name} has ${stars} stars.` }
}
if (stars !== null) {
return setResponse(name, stars)
}
const query = ` query { repository(owner: ${owner}, name: ${name}) { stargazers { totalCount } } } `
const result = await this.ctx.curl('https://api.github.com/graphql', {
method: 'POST',
dataType: 'json',
headers: {
Authorization: `token ${process.env.TOKEN}`
},
data: JSON.stringify({ query }),
timeout: 10000
})
const data = result.data.data
await setexAsync(key, 10, data.repository.stargazers.totalCount)
return setResponse(name, data.repository.stargazers.totalCount)
}
}
module.exports = HomeService
複製代碼
再次測試,首先把 Redis 裏面的緩存清空,使用 Redis 的命令行運行
FLUSHALL
複製代碼
發送請求,第一次的耗時仍是一秒多,而後在失效時間內請求,能夠看到使用緩存的數據後,請求耗時大大減小了,性能提高效果顯著,實際項目能夠設置一個較長的緩存失效時間
固然緩存過時後又要從新向 Github 發送請求了,由於 Redis 已經把數據刪除了