在 Node.js 中使用 Redis 实现 session 共享

在实现 Web 应用程序时,通常需要为用户创建会话,以便在多个页面和请求之间保持状态。Session 可能包括用户身份验证信息、购物车、游戏进度等。对于大规模 Web 应用程序,可能需要将 session 数据存储在多台服务器上以实现负载均衡和高可用性。

Redis 是一个高性能的键值存储数据库,支持存储复杂的数据类型,如哈希表、列表、集合和有序集合。它还有许多功能,如发布/订阅、Lua 脚本、事务等。在 Node.js 中使用 Redis 可以轻松实现 session 共享。

安装 Redis

在 Ubuntu 上,可以使用以下命令安装 Redis:

然后可以使用以下命令启动 Redis:

连接 Redis

使用 redis 模块连接 Redis:

const redis = require('redis');
const client = redis.createClient();

如果 Redis 在服务器上运行,则需要指定 Redis 服务器的 IP 地址和端口:

const client = redis.createClient({
  host: 'redis-server',
  port: 6379,
});

可以使用以下命令检查 Redis 是否正常工作:

如果返回 PONG,则表示 Redis 正在运行。

实现 session 共享

在 Node.js 中,可以使用 express-session 模块实现 session 管理。默认情况下,session 数据存储在内存中,这意味着在多个服务器上运行应用程序时,session 数据将不同步,并可能导致错误。为了解决这个问题,可以将 session 数据存储在 Redis 中。可以使用 connect-redis 模块实现将 session 存储在 Redis 中。

首先,安装 express-sessionconnect-redis 模块:

然后,使用以下代码将 session 设置为使用 Redis 存储:

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

app.use(
  session({
    store: new RedisStore({
      host: 'redis-server',
      port: 6379,
    }),
    secret: 'my-secret',
    resave: false,
    saveUninitialized: true,
  })
);

在此示例中,将 Redis 作为存储 session 的 store。secret 选项指定用于签名 session ID 的字符串。resave 选项指定每次请求是否保存 session,即使没有更改 session 也会保存。saveUninitialized 选项指定是否保存未初始化的 session。您还可以指定其他选项,如超时时间,cookie 选项等。

示例代码

下面是一个完整的示例代码,我们将使用它来测试在 Node.js 中使用 Redis 实现 session 共享:

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

const client = redis.createClient({
  host: 'redis-server',
  port: 6379,
});

const app = express();

app.use(
  session({
    store: new RedisStore({ client }),
    secret: 'my-secret',
    resave: false,
    saveUninitialized: true,
  })
);

app.get('/', (req, res) => {
  const session = req.session;
  if (session.views) {
    session.views++;
    res.setHeader('Content-Type', 'text/html');
    res.write('<p>views: ' + session.views + '</p>');
    res.write('<p>expires in: ' + session.cookie.maxAge / 1000 + 's</p>');
    res.end();
  } else {
    session.views = 1;
    res.end('welcome to the session demo. refresh!');
  }
});

app.listen(3000, () => {
  console.log('Server started on port 3000');
});

在此示例中,如果已存在 views 变量,则增加其计数器。否则,将 views 变量的值设置为 1。

总结

使用 Redis 存储 session 可以实现跨多个服务器共享 session 数据。在 Node.js 中,可以使用 express-sessionconnect-redis 模块轻松实现此目的。该方案的实现是简单易懂的,并且能够提高 Web 应用程序的并发性和可靠性。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a10367add4f0e0ff92a91a


纠错反馈