发表于: 2017-07-13 22:38:28

4 1183


今天完成的事情:

学习了一下如何用redis实现session功能,redis命令

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

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

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

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

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

1.Redis存取速度快。

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

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

4.能够查看在线用户。

5.能够实现用户一处登录。

6.支持持久化。


使用Redis进行Session存储

在应用编写时应该完全弃用HttpSession接口,而是将需要保存的状态信息放到Redis中。

生成session id

当用户登陆时,服务器生成一个全局唯一的字符串SESSION:日期:20位随机字符串做为redis中hash数据结构的key名,然后将该标识做为cookie返回给客户端。 之后该用户的后续请求都会带上此cookie, 我们编写一个filter, 其作用为读取请求中的标识,从redis中取出该标识对应的数据,然后放到HttpServletRequest对象中以供后续使用。

session过期

使用redis自带的过期功能为session id设置过期时间,轻松实现session过期。

session追踪

我们可以将每个用户的session id记录下来,如保存到数据库中,或者依然放在redis里,这样就可以查到某个注册用户所有session id, 轻松实现踢出登陆功能。

session更新

通过AOP, 在每个请求完后之后,检查在请求处理过程中有没有更新session信息,如果有则将新数据刷新到Redis中。

将session转移到redis中后,只要做好redis的运维工作,我们的应用服务器已经是完全无状态的了,水平扩展时只需要添加机器而不需要改动任何一行代码。

实现思路代码


Xml代码 

<welcome-file-list>  

    <welcome-file>IndexServlet</welcome-file>  

</welcome-file-list>  

 2. 在IndexServlet中生成user-key并存放至cookie:

String userKey = UUID.randomUUID().toString();  

Cookie cookie = new Cookie("user-key", userKey);   

response.addCookie(cookie);  

 3. 跳转到index.jsp: 

request.getRequestDispatcher("index.jsp").forward(request, response);  

 

 

<二>. 用户登录,存放用户信息到Redis里面:

1. 从cookie中获取userKey:

String userKey = null;  

Cookie[] cookies = request.getCookies();  

for (Cookie cookie : cookies) {  

    if("user-key".equals(cookie.getName())) {  

        userKey = cookie.getValue();  

        break;  

    }  

}  

 2. 如果用户成功登录,将用户信息存放至Redis:

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");  

UserCache userCache = (UserCache)context.getBean("userCache");  

if(null != user && null != userKey) {  

    userCache.addOrUpdate(userKey, user);  

}  

 3. 从Redis中获取用户数据: 

Userinfo loginUser = userCache.load(userKey);  

 

 

 <三>. UserCache类的API:

1. addOrUpdate:有效时间为30分钟 

public void addOrUpdate(String userKey, Userinfo user) {  

    redisTemplate.opsForValue().set(userKey, user, 30, TimeUnit.MINUTES);  

}  

 2. load:访问用户信息时,更新失效时间 

public Userinfo load(String userKey) {  

    Userinfo user = redisTemplate.opsForValue().get(userKey);  

    redisTemplate.expire(userKey, 30, TimeUnit.MINUTES);  

    return user;  

}  


看各种代码的时候发现这已经有个巨无霸出了一套框架整合方案了——Spring Session

Spring Session为企业级Java应用的session管理带来了革新,使得以下的功能更加容易实现:

编写可水平扩展的原生云应用。

将session所保存的状态卸载到特定的外部session存储中,如Redis或Apache Geode中,它们能够以独立于应用服务器的方式提供高质量的集群。

当用户使用WebSocket发送请求的时候,能够保持HttpSession处于活跃状态。

在非Web请求的处理代码中,能够访问session数据,比如在JMS消息的处理代码中。

支持每个浏览器上使用多个session,从而能够很容易地构建更加丰富的终端用户体验。

控制session id如何在客户端和服务器之间进行交换,这样的话就能很容易地编写Restful API,因为它可以从HTTP 头信息中获取session id,而不必再依赖于cookie。


明天计划的事情:星期一买的《精通Spring 4.x 企业应用开发实战》终于到了,感觉spring学的不是很好多话点时间学学。

遇到的问题:这些都是为了负载均衡所做的优化,可是我们也就那一两台服务器,没法直观感受。

收获:redis命令


返回列表 返回列表
评论

    分享到