栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

connect-redis-如何防止会话对象出现竞争状况

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

connect-redis-如何防止会话对象出现竞争状况

嗯,实现自己的存储可能是您的选择。该文件显示,所有你需要做的是实现三个方法:

.get
.set
.destroy
(参见最后一段)。就像这样(使用node-
redis库
并修改原始的connect-
redis存储
有点):

var redis = require("redis"),    redis_client = redis.createClient(),    session_prefix = 'session::',    lock_suffix = '::lock',    threshold = 5000,    wait_time = 250,    oneDay = 86400;function CustomSessionStore(opts) {    opts = opts || {};    var self = this;    self.ttl = opts.ttl; // <---- used for setting timeout on session    self.lock = function(sid, callback) {        callback = callback || function(){};        var key = session_prefix + sid + lock_suffix;        // try setting the lock with current Date        redis_client.setnx(key, Date.now( ), function(err, res) { // some error handling? if (res) {     // Everything's fine, call callback.     callback();     return; } // setnx failed, look at timeout redis_client.get(key, function(err, res) {     // some error handling?     if (parseInt(res) + threshold > Date.now( )) {         // timeout, release the old lock and lock it         redis_client.getset(key, Date.now( ), function(err, date) {  if (parseInt(date) + threshold > Date.now()) {      // ups, some one else was faster in acquiring lock      setTimeout(function() {          self.lock(sid, callback);      }, wait_time);      return;  }  callback();         });         return;     }     // it is not time yet, wait and try again later     setTimeout(function() {         self.lock(sid, callback);     }, wait_time); });        });    };    self.unlock = function(sid, callback) {        callback = callback || function(){};        var key = session_prefix + sid + lock_suffix;        redis_client.del(key, function(err) { // some error handling? callback();        });    };    self.get = function(sid, callback) {        callback = callback || function(){};        var key = session_prefix + sid;        // lock the session        self.lock(sid, function() { redis_client.get(key, function(err, data) {     if (err) {         callback(err);         return;     }     try {         callback(null, JSON.parse(data));     } catch(e) {         callback(e);     } });        });    };    self.set = function(sid, data, callback) {        callback = callback || function(){};        try { // ttl used for expiration of session var maxAge = sess.cookie.maxAge   , ttl = self.ttl   , sess = JSON.stringify(sess); ttl = ttl || ('number' == typeof maxAge       ? maxAge / 1000 | 0       : oneDay);        } catch(e) { callback(e); return;        }        var key = session_prefix + sid;        redis_client.setex(key, ttl, data, function(err) { // unlock the session self.unlock(sid, function(_err) {     callback(err || _err); });        });    };    self.destroy = function(sid, callback) {        var key = session_prefix + sid;        redis_client.del(key, function(err) { redis_client.unlock(sid, function(_err) {     callback(err || _err); });        });    };}

旁注
:我没有为

.lock
和实现错误处理
.unlock
。我把这个留给你!:)可能会有一些小错误(目前我没有NodeJS,我正在从我的记忆中写它:D),但是您应该理解这个想法。这是包含有关如何用于锁定/解锁Redis
的讨论的链接
setnx

另一个注意事项
:您可能想对路由进行一些自定义错误处理,因为如果任何路由引发异常,则Redis会话将不会被解锁。该

.set
方法始终被称为路线中的最后一件事-与
.get
Express
在路线的最开始处调用的方法相反(这就是为什么我在处锁定
.get
并在处解锁
.set
)。仍然您只会被锁定5秒钟,因此虽然不必担心。请记住,它调整到您的需求(尤其是
threshold
wait_time
变量)。

最后说明 :使用这种机制,您的请求处理程序将仅对每个用户一个接一个地触发。这意味着您将 无法为
每个用户运行并发处理程序。这可能是一个问题,因此另一个想法是将数据保留在会话外部并手动处理锁定/解锁。毕竟,有些事情必须手动处理。

希望对您有所帮助!祝好运!



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/403640.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号