几分钟搞定redis存储session共享——设计实现
前面我们写过C#在redis中存储常用的5种数据类型demo,没看过的可以点击电梯直达:https://www.geek-share.com/detail/2758456280.html
我们上一篇说到Windows7系统中使用nginx部署服务器集群:https://www.cnblogs.com/xiongze520/p/10308720.html
部署完成后我们对于session的共享没有完成,之前小编想做一个session服务器做共享,然后看到评论AjuPrince和三当家的方法,我决定使用第三方缓存(redis)
解决session共享问题。通过查询资料整理如下设计:
- Session的实现原理
- Session共享实现
- Redis存储session的需要考虑问题
- demo演示
Session的实现原理:
- 服务端首先查找对应的cookie的值(sessionid)。
- 根据sessionid,从服务器端session存储中获取对应id的session数据,进行返回。
- 如果找不到sessionid,服务器端就创建session,生成sessionid对应的cookie,写入到响应头中。
Session共享实现:
传统的session由服务器端生成并存储,当应用进行分布式集群部署的时候,如何保证不同服务器上session信息能够共享呢?
两种实现方式:
- session集中存储(redis,memcached,hbase等)。
- 不同服务器上session数据进行复制,两种方式的优缺点,大家应该一目了然。
基于session集中存储的实现方案:
- 新增Filter,拦截请求,包装HttpServletRequest
- 改写getSession方法,从session存储中获取session数据,返回自定义的HttpSession实现
- 在生成新Session后,写入sessionid到cookie中
Redis存储session的需要考虑问题:
- session数据如何在Redis中存储?
- session属性变更何时触发存储?
实现:
考虑到session中数据类似map的结构,采用redis中hash存储session数据比较合适,如果使用单个value存储session数据,不加锁的情况下,就会存在session覆盖的问题,因此使用hash存储session,每次只保存本次变更session属性的数据,避免了锁处理,性能更好。
如果每改一个session的属性就触发存储,在变更较多session属性时会触发多次redis写操作,对性能也会有影响,我们是在每次请求处理完后,做一次session的写入,并且之写入变更过的属性。
如果本次没有做session的更改, 是不会做redis写入的,仅当没有变更的session超过一个时间阀值(不变更session刷新过期时间的阀值),就会触发session保存,以便session能够延长有效期。
demo演示:
我们还是使用上传的demo进行稍加修改:
不用说,我们首先启动redis,不知道的可以点击电梯直达:https://www.geek-share.com/detail/2758456280.html
然后代码如下:
using ServiceStack.Redis; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace RedisApplication { class Program { static void Main(string[] args) { //建立Redis客户端类,构造函数(安装Redis服务器的服务器ip,端口号) RedisClient client = new RedisClient("192.168.0.43", 6379); //链接Redis服务器 client.FlushAll(); //命令用于清空整个Redis服务器的数据(删除所有数据库的所有密钥)。 //-----------------将数据存入Redis----------------- //SetEntryInHash(hashid,key,value) hashid是唯一标识符 client.SetEntryInHash("HashID", "Name", "张三"); client.SetEntryInHash("HashID", "Age", "24"); client.SetEntryInHash("HashID", "Sex", "男"); client.SetEntryInHash("HashID", "Address", "上海市XX号XX室"); client.SetEntryInHash("HashID2", "Name", "张三"); client.SetEntryInHash("HashID2", "Age", "24"); client.SetEntryInHash("HashID2", "Sex", "男"); client.SetEntryInHash("HashID2", "Address", "上海市XX号XX室"); //-----------------读取存入的数据----------------- List<string> HaskKey = client.GetHashKeys("HashID"); foreach (string key in HaskKey) { Console.WriteLine("HashID--Key:{0}", key); } List<string> HaskKey2 = client.GetHashKeys("HashID2"); foreach (string key in HaskKey2) { Console.WriteLine("HashID2--Key:{0}", key); } //-----------------删除对象----------------- //client.RemoveEntryFromHash("HashID", "Name"); } } }
我们获取指定的key,运行效果图如下:
这样就完成redis存储和session共享的问题了,避免iis的session不共享和覆盖问题。
有不同的解决方案可以在评论区套路套路。
- 用Redis存储Tomcat集群的Session实现session共享
- 图文并茂超详细搭建redis缓存服务器(nginx+tomcat+redis+mysql实现session会话共享)
- Nginx +redis 负载均衡 会话共享(二):redis的安装以及session共享的实现
- tomcat+nginx+redis实现均衡负载、session共享
- redis缓存服务器(Nginx+Tomcat+redis+MySQL实现session会话共享
- 利用tomcat redis 实现session共享
- 学习Spring-Session+Redis实现session共享
- session可以存储的方式有几种,如果程序采取分布式,怎么样实现session共享
- 分布式集群Session共享~多个tomcat7+redis的session共享实现
- tomcat+nginx+redis实现均衡负载、session共享
- springboot项目Nginx+Tomcat实现负载均衡结合Redis实现session共享问题
- 学习Spring-Session+Redis实现session共享
- 扩展:tomcat+redis实现session共享
- tomcat实现session集群及tomcat+memcached共享session存储(四)
- Nginx+Tomcat搭建集群,Spring Session+Redis实现Session共享
- zk+redis+tomcat 实现session共享遇到问题
- SpringBoot+Redis+Nginx实现负载均衡以及Session缓存共享
- Nginx+Tomcat+Redis实现应用服务器集群负载均衡和Session共享
- 利用redis同步登陆实现session共享
- redis缓存服务器(nginx+tomcat+redis+mysql实现session会话共享) 推荐