简单地说,我们现在是Redis
会话状态是用来捕获用户与应用(如网站或游戏)交互的当前状态的数据。
只要用户登录,典型的web应用程序就会为每个连接的用户保持会话。会话状态是应用程序记忆用户身份、登录凭据、个性化信息、最近操作、购物车等等的方式。
在每次用户交互中读取和写入会话数据必须在不损害用户体验的情况下进行。在后台,会话状态是特定用户或应用程序的缓存数据,允许对用户操作进行快速响应。因此,当用户会话处于活动状态时,不需要往返中央数据库。
会话状态生命周期的最后一步发生在用户断开连接时。一些数据将被持久化到数据库中以备将来使用,但是在会话结束后可以丢弃瞬态信息。
理解会话状态最佳实践是评估和解决与会话相关的常见问题(如隔离、易变性和持久性)的关键。
当会话处于活动状态时,应用程序只对内存中的会话存储进行读写操作。这意味着更快的写入操作,但也不能容忍数据丢失。由于会话存储数据不是来自另一个数据库的简单快照,因此它必须是高度持久的和始终可用的。
会话状态类似于缓存,但它具有不同的读/写生命周期:缓存可以容忍数据丢失,可以在任何时候从主数据库恢复。写入缓存也需要写入底层数据库。相反,只能在用户会话开始时从主数据源恢复会话状态,并且只有在会话结束时才将会话状态持久化回源。
会话状态可以是不稳定的,也可以是永久的,这意味着当用户会话结束时,数据可以被丢弃或持久化到磁盘存储中。不稳定会话数据的一个例子可能是企业内部网中的页面导航历史记录——几乎不需要保留它。相比之下,电子商务应用程序中的耐用购物车对业务至关重要,必须保存在永久商店中。
会话状态存储为键-值将用户标识符作为密钥,将会话数据作为值。这确保了用户会话不会访问彼此的信息。
将会话状态存储在快速内存缓存中可以实现一些在线分析场景,否则会影响事务数据库。这些应用程序包括实时分析和仪表板、推荐引擎和欺诈检测。
考虑一个文本聊天应用程序,使用MySQL作为关系数据库,Node.js作为后端服务器技术,Redis Enterprise用于会话管理。万博体育彩前端由两个页面组成:用户登录的主页和用户输入并发送信息的聊天页面。
为了简单起见,我们在这里只显示服务器代码。它将解释如何在Node.js中实现会话状态生命周期。我们还省略了HTML视图页面和应用程序的其余部分。
首先,应用程序加载依赖项,包括会话、Redis对象和MySQL客户端:
Var express = require("express");Var session = require('express-session');Var mysql = require("mysql");Var redis = require("redis");var redisStore = require('connect-redis')(session);var redisClient = redis.createClient();//在这里加载更多的依赖项…
上面的声明创建了用于管理web路由、会话、数据库、缓存和会话Node.js库的对象。然后设置Redis作为会话存储:
App.use (session({secret: 'mysecret', //创建新的redis store。store: new redisStore({host: 'localhost', port: 6379, client: redisClient}), saveUninitialized: false, resave: false}));
接下来,为主页和聊天页面配置Node.js快速路由,并支持来自客户端的AJAX请求,包括登录、注销和发送评论。
当用户请求主页时,服务器将它们重定向到chat.html页面或显示登录页面。html,这取决于用户是否已登录。下面的代码片段显示了/get web路由的处理程序代码:
App.get ('/',function(req,res){//创建新的会话对象。If (req.session.key){//用户已经登录res.redirect('/chat');} else{//没有找到session,转到登录页面res.render("login.html");} });
当用户提交登录表单数据(使用电子邮件和密码)时,客户机JavaScript AJAX将表单数据发送到服务器。在本例中,它调用executeLoginDbCommand函数(这里没有显示),它对MySQL数据库执行SQL查询,并返回一个包含用户先前保存的会话数据的对象。
如果登录成功,来自MySQL的用户数据会被保存到Redis会话存储支持的web会话中,客户端JavaScript代码会将用户重定向到聊天页面:
app.post('/login',function(req, res){// SQL查询将比较登录和密码//从HTTP请求体到用户表数据电子邮件、req.body。// if(!dbResult) {res.json({"success": false,"message": "Login failed ! "请注册"});} else {req.session.key = dbResult;res.json({"success": true,"message": "Login success."});} });});
该应用程序的聊天页面允许用户阅读并向登录该应用程序的其他人发布消息。由于用户只能看到自己与他人的消息交互,因此服务器为聊天页面请求返回的数据在不同用户之间会发生变化。最重要的是,只有登录用户才能访问此页面。检查会话密钥可以显示用户是否登录:
App.get ('/chat',function(req,res){if(req.session.key){//用户已经登录,//让我们用用户email渲染聊天页面key["UserEmail"], name: request .session。关键(“用户名”)});} else{//没有找到session,转到登录页面res.redirect("/");} });
当用户从聊天页面提交新评论时,客户机JavaScript AJAX将表单数据发送到服务器。如果用户已经登录,那么注释将被插入到MySQL UserComments表中。我们通过调用executeSendCommmentDbCommand函数(此处未显示)。
app.post("/sendComment",function(req,res){//这个SQL命令将在// users表中插入一个新的注释电子邮件、req.body。接受者,req.body。Comment, function(dbResult){if(!dbResult) {res.json({"success": true, "message": "Comment已成功发送"});} else {res.json({"success": false, "message": "SendComment failed!"});} });} else {res.json({"success": false, "message": "Please login first."});} });
当用户注销时,会话对象将被销毁,用户将被重定向到登录页面。但首先,executePersistSessionDbCommand(这里没有显示)将内存中的用户会话保存到MySQL数据库:
App.get ('/logout',function(req,res){//用户已经登录了,所以让我们销毁session //并重定向到登录页面。如果(req.session.key) {executePersistSessionDbCommand(点播。session, function(dbResult){if(!dbResult) {request .session.destroy(function(){res.redirect('/');} else {res.json({"success": false, "message": "Session persistence failed!"});} });});} else {res.redirect('/');} });
这些代码片段仅仅触及了使用Redis作为会话存储的真实应用程序的表面。但它们说明了Redis如何结合像MySQL这样的永久数据库存储来管理内存中的会话状态生命周期。