前面兩篇從前端入門的視角去學習認識了Nodejs,接下來將真正從實戰角度來看看Nodejs能作什麼,如何從零到一的去完成你的全棧項目。
javascript
在平時,咱們所接觸到的一個完備的Web系統中,通常都會接觸到一個點,那就是緩存。而Nodejs能不能操做緩存系統呢?如何操做的呢?接下來進入新的知識點,Nodejs與緩存系統。前端
若是要從前端工程師進階全棧,則必需要了解一下緩存系統,這裏介紹的緩存系統以Redis做爲示例,來看看Nodejs是如何操做Redis緩存系統的,再經過緩存系統的使用場景,來看看它能幹什麼。java
Redis本質上是一種鍵值內存數據庫,但它在保持鍵值數據庫簡單快捷特色的同時,又吸取了部分關係數據庫的優勢,從而使它的位置處於關係數據庫和鍵值數據庫之間。node
Redis被不少系統所使用它是由如下幾個緣由的。mysql
1.讀寫很是快。Redis每秒可執行大約110000次的設置(SET)操做,每秒大約可執行81000次的讀取/獲取(GET)操做,這是很是大的亮點。2.能夠支持存儲多種數據結構。Redis支持存儲不少種數據類型,像列表,集合,排序集和散列等等。咱們可使用redis像使用內存同樣,很方便的用來存在各種數據。3.操做具備原子性。全部Redis操做都是原子操做,這確保若是兩個客戶端併發訪問,Redis服務器能接收更新的值。4.豐富的特性。redis能幹不少事,可是咱們這裏只介紹緩存,它還能夠用來作消息中間件用來發布訂閱消息,或者將其使用在保持用戶狀態這類地方。git
從它的優勢也能猜出用來幹什麼了。像底層的數據庫要具有高精準的要求,則註定它的效率會差一點,因此當請求很大時,通常不會直接將請求進入到底層數據庫去,而是先經過高效的redis,從它的緩存中去看看有沒有請求想要的結果,若是沒有再去底層數據庫裏操做,因此redis最廣泛的做用就是幫數據庫來「分憂」。github
首先要安裝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工具包:
本文所用的的代碼都可在下面找到,有興趣的clone下來動手練習。
文章用到的代碼都可在此獲取:
https://github.com/FantasyGao/Practice-book/tree/master/nodejs/redis
如上內容均爲本身總結,不免會有錯誤或者認識誤差,若有問題,但願你們留言指正,以避免誤人,如有什麼問題請留言,會盡力回答之。若是對你有幫助不要忘了分享給你的朋友或者點擊右下方的「在看」哦!也能夠關注做者,查看歷史文章而且關注最新動態,助你早日成爲一名全棧工程師!