一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

nodejs express 使用 redis 存儲 session 或 Session存放到MongoDB

 昵稱597197 2015-12-25

使用 redis 存儲 session 的好處在于: 
1.多進(jìn)程間 session 可以共存 
2.網(wǎng)站重啟用 session 依舊還在

var express = require('express');
var RedisStore = require('connect-redis')(express.session);
var app = express();

// 設(shè)置 Cookie
app.use(express.cookieParser('keyboard cat'));

// 設(shè)置 Session
app.use(express.session({
  store: new RedisStore({
    host: "192.168.108.46",
    port: 6379,
    db: "test_session"
  }),
  secret: 'keyboard cat'
}))


// monogdb連接
app.use(session({//session持久化配置
	secret: "kvkenssecret",
	key: "kvkenskey",
	cookie: {maxAge: 1000 * 60 * 60 * 24 * 30},//超時(shí)時(shí)間
	resave: false,
  	saveUninitialized: true,
	store: new MongoStore({
		db: "my_database",
		host: "localhost",
		port: 27017
	})
}));


app.get("/", function(req, res) {
  var session = req.session;
  session.count = session.count || 0;
  var n = session.count++;
  res.send('hello, session id:' + session.id + ' count:' + n);
});

app.listen(3002);

console.log('Web server has started on http://127.0.0.1:3002/');

客戶端與服務(wù)會(huì)使用一個(gè)Sessionid的Cookie值來進(jìn)行客戶端和服務(wù)器端會(huì)話的匹配,這個(gè)Cookie一般是服務(wù)器端讀/寫的,并在Http請求響應(yīng)的Header中的Set-Cookie屬性設(shè)置:

HTTP/1.1 200 OK
Server: nginx
Date: Wed, 14 Jan 2015 02:29:09 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Proxy-Connection: Keep-Alive
Connection: Keep-Alive
Content-Encoding: gzip
Set-Cookie: sessionid=i4w3axuzyj4nwwg75y6k5us2; path=/; domain=.; httponly

  • path=/             表示這個(gè)cookie是設(shè)置在根目錄的。
  • httponly           屬性禁止客戶端JavaScript的訪問,防止當(dāng)前會(huì)話(sessionid)被惡意的js腳本盜取
  • domain=.  表示將sessionid存放到主域名下,各個(gè)二級域名域名均使用此Cookie (sessionid)

注* 中間代理人攻擊,即是通過代理服務(wù)器(如無線路由)盜取你的會(huì)話Cookie(SessionID等),從而訪冒你的身份。因此Google建議網(wǎng)站全部采用HTTPS協(xié)議,加密傳輸內(nèi)容,并提高了純HTTPS網(wǎng)站的權(quán)重。

使用數(shù)據(jù)庫來集中管理session,存放Session內(nèi)容,并在各個(gè)子域名跨域共享Cookies (SessionID),即可實(shí)現(xiàn)為每一個(gè)子域分配一個(gè)獨(dú)立的node.js Web服務(wù)器,各個(gè)服務(wù)程序均可依據(jù)sessionid從數(shù)據(jù)庫中尋找到同一Session,從而實(shí)現(xiàn)不同Web Server中的會(huì)話同步,從而實(shí)現(xiàn)一定程度上的負(fù)載均衡。

要想實(shí)現(xiàn)完全意義的負(fù)載均衡還需要將Web服務(wù)做到完全狀態(tài)無關(guān),不僅僅是Session,所有的中間緩存數(shù)據(jù)都要轉(zhuǎn)移到與服務(wù)器無關(guān)的緩存層中,這正是Redis最善長的地方。

但是為什么存放在Redis中要比MongoDB中好呢?


將Session存放到MongoDB


在MongoDB中是這樣存放Session的, 使用 connect-mongo  即用來將Express中的Session持久化到Mongodb的一個(gè)中間件,它也可以在connect  上使用。

Express 4.x, 5.0 與 Connect 3.x配合使用:

var session = require('express-session');
var MongoStore = require('connect-mongo')(session);

app.use(session({
    secret: 'foo',
    store: new MongoStore(options)
}));

Express 2.x, 3.x 和 Connect 1.x, 2.x配合使用:

var MongoStore = require('connect-mongo')(express);

app.use(express.session({
    secret: 'foo',
    store: new MongoStore(options)
}));


對于 Connect 只需要將express替換成connect即可


MongoDB 是一個(gè)基于文檔的數(shù)據(jù)庫,所有數(shù)據(jù)是從磁盤上進(jìn)行讀寫的。MongoDB善長的是對無模式JSON數(shù)據(jù)的查詢。

而Redis是一個(gè)基于內(nèi)存的鍵值數(shù)據(jù)庫,它由C語言實(shí)現(xiàn)的,與Nginx/ NodeJS工作原理近似,同樣以單線程異步的方式工作,先讀寫內(nèi)存再異步同步到磁盤,讀寫速度上比MongoDB有巨大的提升。因此目前很多超高并發(fā)的網(wǎng)站/應(yīng)用都使用Redis做緩存層,普遍認(rèn)為其性能明顯好于MemoryCache。當(dāng)并發(fā)達(dá)到一定程度時(shí),即可考慮使用Redis來緩存數(shù)據(jù)和持久化Session。


在NodeJS中使用Redis緩存數(shù)據(jù)


Redis?。?/span>安裝方法 ) 數(shù)據(jù)庫采用極簡的設(shè)計(jì)思想,最新版的源碼包還不到2Mb。其在使用上也有別于一般的數(shù)據(jù)庫。


node_redis


redis驅(qū)動(dòng)程序多使用 node_redis 此模塊可搭載官方的 hiredis C 語言庫 - 同樣是非阻塞的,比使用JavaScript內(nèi)置的解釋器性能稍好??蛇x擇將hiredis 與 redis 一同安裝。

npm install hiredis redis

如果 hiredis 安裝成功, node_redis 會(huì)默認(rèn)使用 hiredis, 否則會(huì)使用JavaScript的解釋器。

Redis的一個(gè)Key不僅可以對應(yīng)一個(gè)String類型的值,還支持hashes, lists, sets, sorted sets, bitmaps等。

比如存/取一組Hash值,Redis中有兩個(gè)對應(yīng)的命令 

HMSET key field value [field value ...]、
為一個(gè)Key一次設(shè)置多個(gè)哈希鍵/值, 多用于JSON對象的寫入(序列化的SESSION)。

HGETALL key
讀取一個(gè)Key的所有 哈希鍵/值,多用于JSON對象讀取

這兩個(gè)命令即是在NodeJS中存取JSON對象的關(guān)鍵,

下面是node_reids中對應(yīng)的例子:

var redis = require("redis"),
    client = redis.createClient();

//寫入JavaScript(JSON)對象
client.hmset('sessionid', { username: 'kris', password: 'password' }, function(err) {
  console.log(err)
})

//讀取JavaScript(JSON)對象
client.hgetall('sessionid', function(err, object) {
  console.log(object)
})


Redis沒有嚴(yán)格意義上的表名和字段名,以 Key-Value 鍵值對的方式存儲,因此一般采用 schema:key 形式做為鍵值,其中

schema:  可理解為傳統(tǒng)數(shù)據(jù)庫中的表名
key:    可理解為表中的主鍵

因此使用redis存放你的session時(shí),需要一個(gè)schema前輟, 比如這個(gè)key: sessionid:i4w3axuzyj4nwwg75y6k5us2

Redis 也僅能對Key進(jìn)行檢索, 尚不支持對Key所存放的Hash Key的檢索。 如要檢索到所有session,只需匹配 sessionid:* 即可, 

client.keys('session:*', function (err, keys) {
  console.log(keys)
})

有些第三方庫會(huì)支持檢索值中的Hash Key,但這不是一個(gè)原子性操作,redis本身并不提供。 

因此在采用Redis緩存與檢索數(shù)據(jù)時(shí),要使用一些獨(dú)特的數(shù)據(jù)類型,如集合(Sets)

> sadd myset 1 2 3    //添加 1 2 3到集合myset
(integer) 3
> smembers myset      //列出集合的所有成員
1. 3
2. 1
3. 2
> sismember myset 30  //判斷30是否存在
(integer) 0           //不存在

Redis集合不允許添加相同成員。多次添加同一元素到集合中最終只會(huì)包含一個(gè)元素。多個(gè)集合之間可以進(jìn)行連接/交集這樣的操作。從而實(shí)現(xiàn)類似傳統(tǒng)數(shù)據(jù)庫中索引、條件和連接查詢的效果。

# 添加 3 個(gè)用戶和信息
hmset user:1 user_name lee age 21
hmset user:2 user_name david age 25
hmset user:3 user_name chris age 25

# 維護(hù)age索引
sadd age:21 1
sadd age:25 2 3

# 維護(hù)name索引
sadd name:lee 1
sadd name:david 2
sadd name:chris 3

# 查找  age = 25 和 name = lee 的用戶
sinter age:25 name:lee
  -> 會(huì)返回一個(gè)空集合


將Session存放到Redis中


connect-reids  是一個(gè) Redis 版的 session 存儲器,使用node_redis作為驅(qū)動(dòng)。借助它即可在Express中啟用Redis來持久化你的Session.


安裝


$ npm install connect-redis

在 Express 3.x 中還需要安裝express-session 

$ npm install express-session


參數(shù)


client 你可以復(fù)用現(xiàn)有的redis客戶端對象, 由 redis.createClient() 創(chuàng)建
host   Redis服務(wù)器名
port   Redis服務(wù)器端口
socket Redis服務(wù)器的unix_socket

可選參數(shù)


ttl        Redis session TTL 過期時(shí)間 (秒)
disableTTL 禁用設(shè)置的 TTL
db         使用第幾個(gè)數(shù)據(jù)庫
pass       Redis數(shù)據(jù)庫的密碼
prefix     數(shù)據(jù)表前輟即schema, 默認(rèn)為 "sess:"


使用


將express-session傳給connect-redis來啟用

var session = require('express-session');
var RedisStore = require('connect-redis')(session);

app.use(session({
    store: new RedisStore(options),
    secret: 'keyboard cat'
}));

檢驗(yàn)

app.use(function (req, res, next) {
  if (!req.session) {
    return next(new Error('oh no')) // handle error
  }
  next() // otherwise continue
})


這樣你的Session就轉(zhuǎn)移到了Redis數(shù)據(jù)庫,這樣做的一個(gè)額外好處是,當(dāng)你的Express服務(wù)器突然重啟后,用戶仍然可以使用當(dāng)前Cookie中的SessionID從數(shù)據(jù)庫中獲取到他的會(huì)話狀態(tài),做到會(huì)話不丟失,在一定程度上提高網(wǎng)站的鍵壯性。


如果你的NodeJS網(wǎng)站上的所有緩存數(shù)據(jù)都轉(zhuǎn)移到了Redis后,就可做到完全狀態(tài)無關(guān),按需擴(kuò)展網(wǎng)站的規(guī)模。








可水平擴(kuò)展的NodeJS網(wǎng)站服務(wù)器集群(非 cluster模塊  不同,它們是相互獨(dú)立的,可分布在不同的物理服務(wù)器上),這樣的架構(gòu),對于應(yīng)對超大規(guī)模并發(fā)也是有好處的。

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    日韩日韩欧美国产精品| 欧美激情一区=区三区| 国产传媒精品视频一区| 日本二区三区在线播放| 久久精品色妇熟妇丰满人妻91| 五月天丁香婷婷狠狠爱| 国产传媒高清视频在线| 久久大香蕉精品在线观看| 又大又紧又硬又湿又爽又猛| 蜜桃av人妻精品一区二区三区| 国产成人精品国内自产拍| 亚洲精品中文字幕在线视频| 成人免费高清在线一区二区| 人妻一区二区三区在线| 欧美韩国日本精品在线| 欧美亚洲国产日韩一区二区| 亚洲少妇人妻一区二区| 日韩丝袜诱惑一区二区| 久久精品国产亚洲av麻豆| 免费观看日韩一级黄色大片| 亚洲成人久久精品国产| 精品国产亚洲区久久露脸| 国产又色又爽又黄又免费| 亚洲一区二区久久观看| 欧洲自拍偷拍一区二区| 亚洲最大的中文字幕在线视频| 麻豆看片麻豆免费视频| 亚洲综合香蕉在线视频| av中文字幕一区二区三区在线| 韩国日本欧美国产三级 | 69精品一区二区蜜桃视频| 东京热男人的天堂一二三区| 91在线播放在线播放观看| 亚洲精品成人福利在线| 午夜福利视频日本一区| 日本午夜一本久久久综合| 中文字幕人妻一区二区免费 | 国产亚洲欧美另类久久久| 成人精品一级特黄大片| 欧美日韩校园春色激情偷拍| 欧美国产极品一区二区|