- 運(yùn)行 Javascript
雖然讓 Javascript 運(yùn)行于服務(wù)器端不是 NodeJS 的獨(dú)特之處,但卻是其一強(qiáng)大功能。不得不承認(rèn),瀏覽器環(huán)境限制了我們選擇編程語言的自由。任何服務(wù)器與日益復(fù)雜的瀏覽器客戶端應(yīng)用程序間共享代碼的愿望只能通過 Javascript 來實(shí)現(xiàn)。雖然還存在其他一些支持 Javascript 在服務(wù)器端 運(yùn)行的平臺(tái),但因?yàn)樯鲜鎏匦,Node發(fā)展迅猛,成為事實(shí)上的平臺(tái)。
- 阿里云 OCS SDK for NodeJS
阿里云 OCS 服務(wù)采用的是基于 SASL 認(rèn)證的 Memcached 二進(jìn)制傳輸協(xié)議。實(shí)現(xiàn)該協(xié)議的 NodeJS 開源模塊很少,有一些模塊如 memjs 雖然實(shí)現(xiàn)了 SASL 認(rèn)證和 Memcached 二進(jìn)制傳輸協(xié)議,但是不支持命令隊(duì)列即在一個(gè)命令返回?cái)?shù)據(jù)之前無法執(zhí)行新的命令,這在實(shí)際項(xiàng)目開發(fā)中是無法接受的。因此,阿里云 OCS SDK for NodeJS 基于 memjs 增加了命令隊(duì)列,異常處理,自動(dòng)重新連接等功能,使 NodejS 開發(fā)者快速接入阿里云 OCS 服務(wù)成為可能。
該開源項(xiàng)目代碼托管在 https://github.com/aliyun-UED/node_memcached ,歡迎有興趣的同學(xué)貢獻(xiàn)代碼。
另外,一定會(huì)有人問到 Redis 的問題。Redis 是一種常用的開源內(nèi)存鍵值存儲(chǔ)系統(tǒng),可支持有序集合和列表等數(shù)據(jù)結(jié)構(gòu)。Redis 在 NodeJS 社區(qū)中比較常見,而且也有很多成熟的模塊支持。在阿里云 OCS 服務(wù)后續(xù)集成 Redis 后開發(fā)者可以自行選擇 Memcached 或者 Redis 作為存儲(chǔ)系統(tǒng),我們屆時(shí)也會(huì)將 Redis SDK 集成到阿里云 SDK for NodeJS 中。不過對(duì)于開發(fā)者來說在代碼開發(fā)方式上,Memcached 與 Redis 非常相似,只不過所需要調(diào)用的接口不同而已。
使用阿里云 OCS SDK 開發(fā) web 應(yīng)用
在文章開始我們介紹了 OCS SDK 的最基本用法,比如我們想記錄 web 應(yīng)用的總訪問量,可以在 OCS 中使用一個(gè) key 代表這個(gè)總訪問量,每當(dāng)產(chǎn)生用戶訪問的時(shí)候,可以從 OCS 中讀取 key 的值 value,將 value + 1 后再保存到 key。在這個(gè)場(chǎng)景中使用 OCS 在合適不過了,因?yàn)槲覀兛赡苡卸鄠(gè) ECS 實(shí)例作為 web server,它們可以向同一個(gè) OCS 做讀寫操作;另外也不用擔(dān)心 ECS 實(shí)例掛掉后總訪問量這個(gè)數(shù)據(jù)消失的問題;最后, OCS 的高性能也保證了我們的業(yè)務(wù)需求。
除此之外,使用 OCS 最合適的地方就是 session 存儲(chǔ)了。在 web 服務(wù)器上的 session 可以存儲(chǔ)在
- 內(nèi)存
- 磁盤文件系統(tǒng)
- 數(shù)據(jù)庫
Memcached 等緩存系統(tǒng)
從性能,可用性角度考慮,存儲(chǔ)在 Memcached 是最好的選擇。那么在 NodeJS 中該如何實(shí)現(xiàn)呢。
一般來說,開發(fā) NodeJS web 應(yīng)用需要選擇一個(gè)合適的 web 框架,我們以目前最流行的 web 框架 Express 舉例。
Express 框架內(nèi)建了對(duì) session 處理的支持,它默認(rèn)的 session 存儲(chǔ)機(jī)制是內(nèi)存存儲(chǔ),而將其他 session 存儲(chǔ)機(jī)制作為可擴(kuò)展選項(xiàng)。如下代碼所示:
// 創(chuàng)建一個(gè) express 實(shí)例
var app = require(“express”);
// 內(nèi)存存儲(chǔ) session
var session = require(‘express-session’)
// 使用 express 的 session 處理,并使用內(nèi)存存儲(chǔ)機(jī)制
app.use(session({ secret: ‘keyboard cat’, cookie: { maxAge: 60000 }}))
// 處理 HTTP 請(qǐng)求,req 代表請(qǐng)求對(duì)象,res 代表返回對(duì)象
app.use(function(req, res) {
// sess 即為該請(qǐng)求所對(duì)應(yīng)的用戶的 session,不用擔(dān)心,express 已經(jīng)幫你分析請(qǐng)求所帶的 cookie
// 并將該 cookie 所對(duì)應(yīng)的 session 從存儲(chǔ)中找到并提供給你
var sess = req.session
// 下面是對(duì) session 對(duì)象的處理
if (sess.views) {
sess.views++
res.setHeader(‘Content-Type’, ‘text/html’)
res.write(‘<p>views: ‘ + sess.views + ‘</p>’)
res.write(‘<p>expires in: ‘ + (sess.cookie.maxAge / 1000) + ‘s</p>’)
res.end()
} else {
// 更新后的 session 會(huì)在請(qǐng)求處理結(jié)束后自動(dòng)寫回到 session 的存儲(chǔ)中
sess.views = 1
res.end(‘welcome to the session demo. refresh!’)
}
})
從上面的代碼中可見,我們只需要實(shí)現(xiàn) session 的存儲(chǔ)機(jī)制,便能夠和 express 完美的結(jié)合了。