前面两篇从前端入门的视角去学习认识了Nodejs,接下来将真正从实战角度来看看Nodejs能做什么,如何从零到一的去完成你的全栈项目。
在平时,我们所接触到的一个完备的Web系统中,一般都会接触到一个点,那就是缓存。而Nodejs能不能操作缓存系统呢?如何操作的呢?接下来进入新的知识点,Nodejs与缓存系统。
Nodejs与缓存系统
如果要从前端工程师进阶全栈,则必须要了解一下缓存系统,这里介绍的缓存系统以Redis作为示例,来看看Nodejs是如何操作Redis缓存系统的,再通过缓存系统的使用场景,来看看它能干什么。
认识一下Redis
Redis本质上是一种键值内存数据库,但它在保持键值数据库简单快捷特点的同时,又吸收了部分关系数据库的优点,从而使它的位置处于关系数据库和键值数据库之间。
Redis被很多系统所使用它是由以下几个原因的。
1.读写非常快。Redis每秒可执行大约110000次的设置(SET)操作,每秒大约可执行81000次的读取/获取(GET)操作,这是非常大的亮点。2.可以支持存储多种数据结构。Redis支持存储很多种数据类型,像列表,集合,排序集和散列等等。我们可以使用redis像使用内存一样,很方便的用来存在各类数据。3.操作具有原子性。所有Redis操作都是原子操作,这确保如果两个客户端并发访问,Redis服务器能接收更新的值。4.丰富的特性。redis能干很多事,但是我们这里只介绍缓存,它还可以用来做消息中间件用来发布订阅消息,或者将其使用在保持用户状态这类地方。
从它的优点也能猜出用来干什么了。像底层的数据库要具备高精准的要求,则注定它的效率会差一点,所以当请求很大时,一般不会直接将请求进入到底层数据库去,而是先通过高效的redis,从它的缓存中去看看有没有请求想要的结果,如果没有再去底层数据库里操作,所以redis最普遍的作用就是帮数据库来“分忧”。
安装Redis
首先要安装redis,你可以在本机或者你的服务器上安装均可。不过这里再次推荐一下docker,之前我推荐大家用docker装mysql,这里我简单介绍一下为什么用docker。
平时在学习的时候总要装各种各样的软件,但是找安装包总是让人头疼,就算找到了安装包安好了,这次学习完后发现之后好久也不用,就一直在桌面上放着,放久了最后还是卸载了,卸载完发现存留了一些垃圾文件或者环境参数让人不悦。
这时候如果使用docker便会发现,安装包找起来一个命令搞定,安装你用的时候启动它就行了,不使用的时候用docker命令删除即可,非常方便。docker的安装各平台都不一样,可自行搜索一下安装,下面直接介绍使用。
# 查找redis 的镜像(安装包)
docker search redis
# 拉去最新版官方的镜像
docker pull redis
# 查看一下镜像
docker images
# 启动 暴露到本机的6379端口(-p 主机(宿主)端口:容器端口) 并且后台运行(-d)
docker run -p 6379:6379 -d redis redis-server
# 查看一下,出如下结果就算启动成功了
docker ps
使用Nodejs操作Redis
先来NPM官网查一下看看有哪些开源好用的redis工具包[1]。
看得出来使用最多的包就是redis包了,我们在本地进行安装。
npm i --save redis
接下来使用redis包暴露的createClient方法连接docker启动好的redis。
const redis = require('redis');
const host = '127.0.0.1';
const port = 6379;
// 连接成功 const client = redis.createClient(port, host);
module.export = client;
这里来一个hello world示例。
// hello.js const redis = require('./redis');
// 在redis设置一个key为hello,值为world的内容
redis.set('hello','world');
// 在redis设置key为hello的过期时间为6秒 redis.expire('hello', 6);
// 定时器每两秒读一次
setInterval(()=> {
redis.get('hello', function (err, value) {
if (err) console.error(err);
console.log('hello %s', value);
})
}, 2000)
使用node hello.js 启动这段代码看看,发现定时器读了3次后,value值自动过期获取不到了。
缓存的使用场景实例
接下来再看一点深度的例子,看看redis的在一些实际场景下的使用。
先提一个需求,需要给前端提供一个数据接口,但是由于数据内容相对固定,而查询的量又非常的大,所以需要引入缓存来快速的返回给用户结果,而且要保证隔一段时间还是要查询一次底层数据库获取最新的返回给用户。
首先给封装一下操作redis的API方便使用。
const redis = require('redis');
const host = '127.0.0.1';
const port = 6379;
const client = redis.createClient(port, host);
//将redis.get方法promise化
const pifyRdsGet = function (key) {
return new Promise((resolve, reject) => {
client.get(key, (err, data) => {
if(err) reject(err);
resolve(data);
})
})
}
module.exports = {
pifyRdsGet,
setValue: client.set.bind(client),
setExpire: client.expire.bind(client),
}
这里暴露了三个非常常用的redis接口提供使用,分别是get,set和expire。因为redis所提供的接口是回调函数类型的,这里将其promise化一下,方便后面使用。
const http = require('http');
const url = require('url');
const {
pifyRdsGet,
setExpire,
setValue
}= require('./redis');
// 模拟从底层关系型数据库获取数据
const mockFromDB = {
name: 'FantasyGao',
description: '这是一条模拟从数据库来的数据',
time: new Date(),
};
http.createServer(async (req, res) => {
res.setHeader('Content-Type', 'application/json;charset=utf-8');
const reqUrl = url.parse(req.url);
if (reqUrl.pathname === '/api/get/data') {
const REDIS_KEY = 'dataKey';
try {
// 请求过来时,先从redis中获取数据
const dataFromRedis = await pifyRdsGet(REDIS_KEY);
if (dataFromRedis) {
// 存在数据直接返回
const result = JSON.parse(dataFromRedis);
result.description = '这是一条从Redis缓存来的数据';
res.end(JSON.stringify(result));
} else {
// redis不存在数据,则需要从底层数据库读取数据
const dataFromDB = JSON.stringify(mockFromDB);
// 重新将新获取的数据插入redis
setValue(REDIS_KEY, dataFromDB);
// 设置过期时间
setExpire(REDIS_KEY, 5);
res.end(dataFromDB);
}
} catch (e) {
res.writeHead(500);
res.end('Server error');
}
} else {
res.writeHead(404);
res.end('NotFund');
}
}).listen(8000, ()=> {
console.log('listen on 8000!');
})
这里看看第一次请求的返回结果,数据是从数据库中获取而来。
在紧跟着访问一次接口,这时候发现数据则从redis里获取到,直接返回。
上面两个例子从Nodejs入门使用redis,再到缓存的一般使用场景来学习了一下Nodejs操作缓存系统的相关内容,接下来将介绍走进Nodejs与mysql的相关操作。
References
[1]
redis工具包: https://www.npmjs.com/search?q=redis
本文所用的的代码均可在下面找到,有兴趣的clone下来动手练习。
文章用到的代码均可在此获取:
https://github.com/FantasyGao/Practice-book/tree/master/nodejs/redis
如上内容均为自己总结,难免会有错误或者认识偏差,如有问题,希望大家留言指正,以免误人,若有什么问题请留言,会尽力回答之。如果对你有帮助不要忘了分享给你的朋友或者点击右下方的“在看”哦!也可以关注作者,查看历史文章并且关注最新动态,助你早日成为一名全栈工程师!