`
hongtoushizi
  • 浏览: 370543 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

用Redis实现Session功能

阅读更多

转载自: http://www.cnblogs.com/ddyq/p/3151284.html

用Redis实现Session功能

0.什么是Redis

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

---维基百科

1.与其他用户状态保存方案比较

一般开发中用户状态使用session或者cookie,两种方式各种利弊。

Session:在InProc模式下容易丢失,并且引起并发问题。如果使用SQLServer或者SQLServer模式又消耗了性能

Cookie则容易将一些用户信息暴露,加解密同样也消耗了性能。

Redis采用这样的方案解决了几个问题,

1.Redis存取速度快。

2.用户数据不容易丢失。

3.用户多的情况下容易支持集群。

4.能够查看在线用户。

5.能够实现用户一处登录。(通过代码实现,后续介绍)

6.支持持久化。(当然可能没什么用)

2.实现思路

1.我们知道session其实是在cookie中保存了一个sessionid,用户每次访问都将sessionid发给服务器,服务器通过ID查找用户对应的状态数据。

在这里我的处理方式也是在cookie中定义一个sessionid,程序需要取得用户状态时将sessionid做为key在Redis中查找。

2.同时session支持用户在一定时间不访问将session回收。

借用Redis中Keys支持过期时间的特性支持这个功能,但是在续期方面需要程序自行拦截请求调用这个方法(demo有例子)

下面开始代码说明

 

3.Redis调用接口

首先引用ServiceStack相关DLL。

在web.config添加配置,这个配置用来设置Redis调用地址每台服务用【,】隔开。主机写在第一位

 

复制代码
1 <appSettings>
2 
3     <!--每台Redis之间用,分割.第一个必须为主机-->
4     <add key="SessionRedis" value="127.0.0.1:6384,127.0.0.1:6384"/>
5 
6 </appSettings>
复制代码

初始化配置

复制代码
static Managers()
        {
            string sessionRedis= ConfigurationManager.AppSettings["SessionRedis"];
            string timeOut = ConfigurationManager.AppSettings["SessionRedisTimeOut"];

            if (string.IsNullOrEmpty(sessionRedis))
            {
                throw new Exception("web.config 缺少配置SessionRedis,每台Redis之间用,分割.第一个必须为主机");
            }

            if (string.IsNullOrEmpty(timeOut)==false)
            {
                TimeOut = Convert.ToInt32(timeOut);
            }

            var host = sessionRedis.Split(char.Parse(","));
            var writeHost = new string[] { host[0] };
            var readHosts = host.Skip(1).ToArray();

            ClientManagers = new PooledRedisClientManager(writeHost, readHosts, new RedisClientManagerConfig
            {
                MaxWritePoolSize = writeReadCount,//“写”链接池链接数
                MaxReadPoolSize = writeReadCount,//“读”链接池链接数
                AutoStart = true
            });
        }
复制代码

 

为了控制方便写了一个委托

复制代码
 /// <summary>
        /// 写入
        /// </summary>
        /// <typeparam name="F"></typeparam>
        /// <param name="doWrite"></param>
        /// <returns></returns>
        public F TryRedisWrite<F>(Func<IRedisClient, F> doWrite)
        {
            PooledRedisClientManager prcm = new Managers().GetClientManagers();
            IRedisClient client = null;
            try
            {
                using (client = prcm.GetClient())
                {
                    return doWrite(client);
                }
            }
            catch (RedisException)
            {
                throw new Exception("Redis写入异常.Host:" + client.Host + ",Port:" + client.Port);
            }
            finally
            {
                if (client != null)
                {
                    client.Dispose();
                }
            }
        }
复制代码

 一个调用的例子其他的具体看源码

复制代码
        /// <summary>
        /// 以Key/Value的形式存储对象到缓存中
        /// </summary>
        /// <typeparam name="T">对象类别</typeparam>
        /// <param name="value">要写入的集合</param>
        public void KSet(Dictionary<string, T> value)
        {
            Func<IRedisClient, bool> fun = (IRedisClient client) =>
            {
                client.SetAll<T>(value);
                return true;
            };

            TryRedisWrite(fun);
        }
复制代码

 

 

 

4.实现Session

按上面说的给cookie写一个sessionid

 

复制代码
    /// <summary>
    /// 用户状态管理
    /// </summary>
    public class Session
    {
        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="_context"></param>
        public Session(HttpContextBase _context)
        {
            var context = _context;
            var cookie = context.Request.Cookies.Get(SessionName);
            if (cookie == null || string.IsNullOrEmpty(cookie.Value))
            {
                SessionId = NewGuid();
                context.Response.Cookies.Add(new HttpCookie(SessionName, SessionId));
                context.Request.Cookies.Add(new HttpCookie(SessionName, SessionId));
            }
            else
            {
                SessionId = cookie.Value;
            }
        }

    }
复制代码

去存取用户的方法

复制代码
        /// <summary>
        /// 获取当前用户信息
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public object Get<T>() where T:class,new()
        {
            return new RedisClient<T>().KGet(SessionId);
        }

        /// <summary>
        /// 用户是否在线
        /// </summary>
        /// <returns></returns>
        public bool IsLogin()
        {
            return new RedisClient<object>().KIsExist(SessionId);
        }

        /// <summary>
        /// 登录
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        public void Login<T>(T obj) where T : class,new()
        {
            new RedisClient<T>().KSet(SessionId, obj, new TimeSpan(0, Managers.TimeOut, 0));
        }
复制代码

 

 

6.续期

默认用户没访问超过30分钟注销用户的登录状态,所以用户每次访问都要将用户的注销时间推迟30分钟

这需要调用Redis的续期方法

 

复制代码
        /// <summary>
        /// 延期
        /// </summary>
        /// <param name="key"></param>
        /// <param name="expiresTime"></param>
        public void KSetEntryIn(string key, TimeSpan expiresTime)
        {
            Func<IRedisClient, bool> fun = (IRedisClient client) =>
            {
                client.ExpireEntryIn(key, expiresTime);
                return false;
            };

            TryRedisWrite(fun);
        }

 
复制代码
封装以后
复制代码
/// <summary>
/// 续期
/// </summary>
public void Postpone()
{
new RedisClient<object>().KSetEntryIn(SessionId, new TimeSpan(0, Managers.TimeOut, 0));
}

 
复制代码

 

这里我利用了MVC3中的ActionFilter,拦截用户的所有请求

复制代码
namespace Test
{
    public class SessionFilterAttribute : ActionFilterAttribute
    {
        /// <summary>
        /// 每次请求都续期
        /// </summary>
        /// <param name="filterContext"></param>
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            new Session(filterContext.HttpContext).Postpone();
        }
    }
}
复制代码

 


在Global.asax中要注册一下

复制代码
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new SessionFilterAttribute());
        }

        protected void Application_Start()
        {
            RegisterGlobalFilters(GlobalFilters.Filters);
        }
复制代码

 

 

5.调用方式

为了方便调用借用4.0中的新特性,把Controller添加一个扩展属性

 

public static class ExtSessions
{public static Session SessionExt(this Controller controller)
    {
        return new Session(controller.HttpContext);
    }
}

 

调用方法

复制代码
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            this.SessionExt().IsLogin();
            return View();
        }
    }
复制代码

 

6.代码下载

点击下载

 

 

分享到:
评论

相关推荐

    详解用Redis实现Session功能

    总结起来,使用Redis实现Session功能可以提高系统性能、减少数据丢失风险,并且易于扩展到集群环境。此外,Redis还提供了丰富的数据结构和操作,如哈希、列表、集合等,可以进一步优化和扩展Session管理功能。在实际...

    ssm+redis 实现session共享

    SSM+Redis 实现Session共享是现代Web应用中常见的技术组合,主要目的是在分布式系统中保持用户Session的一致性。SSM是指Spring、Spring MVC和MyBatis这三大Java Web开发框架的组合,而Redis则是一种高性能的键值存储...

    springboot +shiro+redis实现session共享(方案二)1

    本文档旨在介绍如何使用 Spring Boot、Shiro 和 Redis 实现分布式 session 共享,以解决 Web 应用程序的登录 session 统一问题。 2. 相关依赖 在实现 session 共享之前,需要在项目中引入相关依赖项,包括: * ...

    Tomcat8(Tomcat9)+redis实现Session共享(支持Redis集群)

    本教程将详细介绍如何利用Tomcat 8或9以及Redis实现Session共享,支持Redis集群,以提高系统的可伸缩性和数据一致性。 首先,我们需要理解Session的概念。Session是服务器端用于存储用户状态的一种机制,通常在用户...

    tomcat-redis实现session共享

    本教程将详细讲解如何使用Tomcat与Redis集成,实现Session的共享。 首先,我们需要理解Tomcat和Redis的基本概念。Tomcat是一款开源的Java Servlet容器,广泛用于部署Java Web应用程序。而Redis则是一种高性能的键值...

    tomcat-redis-session-manager

    《Tomcat Redis Session Manager:实现高效会话管理》 ...它将Redis的强大功能引入Tomcat,实现了跨服务器的session共享,提高了应用的可扩展性和可靠性。正确配置和使用这个组件,将有助于构建更健壮、高效的Web服务。

    利用redis实现session共享

    本篇文章将深入探讨如何利用Redis实现Session共享,同时结合Nginx的负载均衡策略,以及Spring Boot的应用框架,构建一个高效、可靠的分布式系统。 一、Session共享的挑战与解决方案 在传统的单体应用中,Session...

    nginx+redis实现session共享

    在IT行业中,构建高效、可扩展的Web服务是至关重要的,而"nginx+redis实现session共享"的主题就涉及到了这一核心需求。为了实现单点登录(Single Sign-On, SSO)以及跨应用的session共享,我们可以结合使用Nginx作为...

    SpringSession+Redis实现Session共享案例

    下面将详细解释`SpringSession`和`Redis`在实现Session共享中的关键知识点。 1. **SpringSession**: - `SpringSession` 是Spring生态系统的一个扩展,它允许我们将HTTP Session数据存储在外部存储(如Redis)中,...

    tomcat-redis-session-manager的jar包-包含Tomcat7和Tomcat8

    这两个jar包包含了实现session与Redis交互的所有必要组件,如session序列化和反序列化,以及与Redis服务器的通信接口。 在配置Tomcat-Redis-Session-Manager时,开发者需要在Tomcat的`context.xml`文件中添加相关的...

    tomcat8集群redis实现session共享jar包

    本压缩包提供了在Tomcat8集群中通过Redis实现会话共享所需的jar包,这些jar包已经预先编译好,可以直接使用。 首先,让我们了解为什么要在Tomcat集群中使用Redis进行会话共享。在没有会话共享的情况下,当用户从一...

    集群redis实现session共享jar包之tomcat7

    "集群redis实现session共享jar包之tomcat7"这个主题涉及到的是如何在基于Tomcat 7的Web应用集群中,利用Redis作为中央存储来共享用户的Session数据。下面将详细解释这一技术的实现原理和步骤。 首先,理解Session...

    tomcat基于redis实现session共享所依赖的jar包

    "tomcat基于redis实现session共享所依赖的jar包"就是解决这个问题的关键组件。 首先,我们需要理解session共享的基本概念。Session是Web服务器为特定用户浏览器创建的一种持久化的数据存储方式,用于存储用户在网站...

    tomcat-redis-session-manager包集合下载(tomcat8)

    它的高速读写能力使其成为存储session的理想选择,尤其是在分布式环境中,可以轻松实现session共享。 **知识点三:tomcat-redis-session-manager** tomcat-redis-session-manager是专门为Tomcat设计的一个插件,它...

    redis实现session一致性的Lib

    这个名为"redis实现session一致性"的库提供了将Tomcat服务器中的session数据同步到Redis的方法。它包含了三个jar文件,这些文件很可能是实现了与Tomcat集成的session管理器、与Redis通信的客户端库以及可能的配置或...

    session 共享 tomcat-redis-session-manager 所需要的jar (绝对可用)

    总结来说,这个压缩包提供了一套完整的解决方案,包括了连接Redis的Jedis客户端、对象池管理、Tomcat的Session管理器以及配置文件,使得开发者可以轻松地在Tomcat集群中实现Session共享,提升系统的可扩展性和容错性...

    Spring Session + redis实现session共享

    Spring Session的核心思想是将session数据从传统的JVM内存中移出,存储到一个独立的数据存储系统,如Redis,这样可以实现session在多台服务器之间的共享。 Redis是一个高性能的键值数据库,常用于缓存和消息代理。...

    tomcat8集群与redis实现session共享所需Jar包

    标题"tomcat8集群与redis实现session共享所需Jar包"指的是将Redis作为中央存储来保存Tomcat集群中的session数据。Redis因其高性能、轻量级以及丰富的数据结构支持,常被选作session共享的中间件。描述中的"本人已经...

    tomcat8-redis-session共享

    标题 "tomcat8-redis-session共享" 涉及到的是在Tomcat 8中使用Redis作为Session共享存储的解决方案。这是一个常见的需求,特别是在分布式系统中,为了保持用户会话的一致性,需要将Session数据在多台服务器之间共享...

Global site tag (gtag.js) - Google Analytics