面向前端工程师的Nodejs入门手册(三)

前面两篇从前端入门的视角去学习认识了Nodejs,接下来将真正从实战角度来看看Nodejs能作什么,如何从零到一的去完成你的全栈项目。
javascript

在平时,咱们所接触到的一个完备的Web系统中,通常都会接触到一个点,那就是缓存。而Nodejs能不能操做缓存系统呢?如何操做的呢?接下来进入新的知识点,Nodejs与缓存系统。前端

Nodejs与缓存系统

若是要从前端工程师进阶全栈,则必需要了解一下缓存系统,这里介绍的缓存系统以Redis做为示例,来看看Nodejs是如何操做Redis缓存系统的,再经过缓存系统的使用场景,来看看它能干什么。java

认识一下Redis

Redis本质上是一种键值内存数据库,但它在保持键值数据库简单快捷特色的同时,又吸取了部分关系数据库的优势,从而使它的位置处于关系数据库和键值数据库之间。node

Redis被不少系统所使用它是由如下几个缘由的。mysql

1.读写很是快。Redis每秒可执行大约110000次的设置(SET)操做,每秒大约可执行81000次的读取/获取(GET)操做,这是很是大的亮点。2.能够支持存储多种数据结构。Redis支持存储不少种数据类型,像列表,集合,排序集和散列等等。咱们可使用redis像使用内存同样,很方便的用来存在各种数据。3.操做具备原子性。全部Redis操做都是原子操做,这确保若是两个客户端并发访问,Redis服务器能接收更新的值。4.丰富的特性。redis能干不少事,可是咱们这里只介绍缓存,它还能够用来作消息中间件用来发布订阅消息,或者将其使用在保持用户状态这类地方。git

从它的优势也能猜出用来干什么了。像底层的数据库要具有高精准的要求,则注定它的效率会差一点,因此当请求很大时,通常不会直接将请求进入到底层数据库去,而是先经过高效的redis,从它的缓存中去看看有没有请求想要的结果,若是没有再去底层数据库里操做,因此redis最广泛的做用就是帮数据库来“分忧”。github

安装Redis

首先要安装redis,你能够在本机或者你的服务器上安装都可。不过这里再次推荐一下docker,以前我推荐你们用docker装mysql,这里我简单介绍一下为何用docker。redis

平时在学习的时候总要装各类各样的软件,可是找安装包老是让人头疼,就算找到了安装包安好了,此次学习完后发现以后很久也不用,就一直在桌面上放着,放久了最后仍是卸载了,卸载完发现存留了一些垃圾文件或者环境参数让人不悦。sql

这时候若是使用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



如上内容均为本身总结,不免会有错误或者认识误差,若有问题,但愿你们留言指正,以避免误人,如有什么问题请留言,会尽力回答之。若是对你有帮助不要忘了分享给你的朋友或者点击右下方的“在看”哦!也能够关注做者,查看历史文章而且关注最新动态,助你早日成为一名全栈工程师!


相关文章
相关标签/搜索