发布于 2016-04-06 22:43:29 | 228 次阅读 | 评论: 1 | 来源: 分享

这里有新鲜出炉的Redis教程,程序狗速度看过来!

Redis Key-Value数据库

Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。


背景知识

我们知道后端是通过session来维持用户的会话的,每当用户发起一个请求的时候,用户的浏览器就会将用户的一个sessionIDcookie的形式发送到后端,后端接收到这个sessionID后,就会看内存中有没有sessionID为此sessionIDsession,如果存在,则授权访问;否则重定向到授权页面或者返回错误码。

因为是NodeJS是单线程的,为了充分利用CPU的多核特性,采用了cluster模块,利用主从模式,生成与CPU核心数量相当的子进程,然后主进程用来捕获请求随机分配给子进程处理,并负责子进程的崩溃重启。但是,在引进了cluster模块之后,以前的session认证机制将完全不可用。原因如下:

我们知道进程与进程之间是不能共享数据的,所以进程1的内存数据无法被进程2读取到,所以如果用户A认证的过程是被进程1所处理的,那么维持会话的session将保存在进程1的内存数据中;如果此用户接下的请求被进程2所处理,因为进程2没有处理过用户A的认证,没有维持这个会话的session,所以进程2会判断用户A并没有授权。这样用户A需要多次重复认证访问才能继续下去…

解决方案

我们现在的问题是session无法共享,所以我们可以想办法让session共享。通过将session存在基于内存的数据库redis里面,即可完美的解决了session共享的问题。

现在以Express框架为例,说一下具体做法:

  1. 安装redis,安装过程参考 官方文档
  2. 安装connect-redis模块
    npm install -save connect-redis
  3. 配置Express
    // 仅列出核心代码
    var express = require("express");
    var session = require("express-session");
    var RedisStore = require('connect-redis')(session);
    var config = require("./config");
    var app = express();
    app.use(session({
    	saveUninitialized: true,
    	resave: true,
    	secret: config.sessionSecret,
    	store: new RedisStore() // 利用redis存储session
    }));

    后记

其实,我们也可以换一种思路来解决这个问题。既然多进程之间无法共享session,那就索性不共享呗!放弃cluster,利用系统脚本开启与CPU数量相当的NodeJS进程,并且每个进程监听不同的网络端口,利用Nginx负载均衡机制,设置均衡模式为ip_hash,这样对于同一个客户端的请求转发到同一个端口,避免了将请求转发到没有认证的端口,这样也可以解决此问题。

基本思想如下图所示:

                                                  +-------------------+
                                                  |                   |
                                            +----->  127.0.0.1:3000   |
                                            |     |                   |
                                            |     +-------------------+
                        +---------------+   |
+----------------+      |               +---+     +-------------------+
|                |      |               |         |                   |
|     user A     +------>               +--------->  127.0.0.1:3001   |
|                |      |               |         |                   |
+----------------+      |               |         +-------------------+
                        |    NGINX      |
+----------------+      |               |         +-------------------+
|                |      |               |         |                   |
|     user B     +------>               +--------->  127.0.0.1:3002   |
|                |      |               |         |                   |
+----------------+      |               +----+    +-------------------+
                        +---------------+    |
                                             |    +-------------------+
                                             |    |                   |
                                             +---->  127.0.0.1:3003   |
                                                  |                   |
                                                  +-------------------+


相关阅读 :
用 Redis 解决 NodeJS 多进程无法共享 session 的问题
Redis 2.8.18 安装报错 error: jemalloc/jemalloc.h: No such file or directory解决方法
安装redis make test时报错 undefined reference to `__sync_add_and_fetch_4'解决方法
redis错误:MISCONF Redis is configured to save RDB snapshots解决方法
Redis 出现错误1067的解决办法
最新网友评论  共有(1)条评论 发布评论 返回顶部
fhyeebn 发布于2016-10-06 11:23:05
沙发
支持(0)  反对(0)  回复

Copyright © 2007-2017 PHPERZ.COM All Rights Reserved   冀ICP备14009818号  版权声明  服务