Redis将Session 集中管理
2016-02-23 08:45
615 查看
摘要: 在分布式系统中.前提是分布式或者集群环境,常常需要多个系统中,保持Session .
nginx可以配置IP的hash,实现每次都访问同一台应用容器,从而不需要共享Session ,对Java来说,也有tomcat的复制.
虽然tomcat等容器可以实现Session 的复制,但是在tomcat的数量过多时,复制的延迟和性能的损失
将因为tomcat的数量直线上升.
这里可以用redis简单的将Session 集中管理.线上环境将redis高可用即可.
在分布式系统中.前提是分布式或者集群环境,常常需要多个系统中,保持Session .
nginx可以配置IP的hash,实现每次都访问同一台应用容器,从而不需要共享Session ,也有tomcat的复制.
虽然tomcat等容器可以实现Session 的复制,但是在tomcat的数量过多时,复制的延迟和性能的损失
将因为tomcat的数量直线上升.
这里可以用redis简单的将Session 集中管理.线上环境将redis高可用即可.
Java对Redis的操作可以用 Jedis.spring-data-redis封装Jedis,更加易用
本文采用 spring data redis作为Redis的连接工具.
采用Sping管理.
Maven pom.xml引入
spring-redis.xml 配置 Redis的连接池和连接
redis.properties 连接的配置肯定是需要的
在需要使用的类中注入
组装一下key,统一设置前缀,可以方便的管理key
准备常量
然后即可开始操作...如在登陆时写入redis并设置Session时长.
同理删除和获取
文中的 onLineUserInfo 即你需要放入Session的登陆对象,可以自行编辑
不管存入cookie还是重写url...系统请求是需要带上sid即可.
PS:有人问我为什么要用顶级的key,不用Hash,因为redis的key是有上限的.主要是只有顶级的key才能有过期时间一说.这里牵涉到Redis的一些内部特征,大家可以去查阅关于Redis的文章.
nginx可以配置IP的hash,实现每次都访问同一台应用容器,从而不需要共享Session ,对Java来说,也有tomcat的复制.
虽然tomcat等容器可以实现Session 的复制,但是在tomcat的数量过多时,复制的延迟和性能的损失
将因为tomcat的数量直线上升.
这里可以用redis简单的将Session 集中管理.线上环境将redis高可用即可.
在分布式系统中.前提是分布式或者集群环境,常常需要多个系统中,保持Session .
nginx可以配置IP的hash,实现每次都访问同一台应用容器,从而不需要共享Session ,也有tomcat的复制.
虽然tomcat等容器可以实现Session 的复制,但是在tomcat的数量过多时,复制的延迟和性能的损失
将因为tomcat的数量直线上升.
这里可以用redis简单的将Session 集中管理.线上环境将redis高可用即可.
Java对Redis的操作可以用 Jedis.spring-data-redis封装Jedis,更加易用
本文采用 spring data redis作为Redis的连接工具.
采用Sping管理.
Maven pom.xml引入
<dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.5.2.RELEASE</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.6.2</version> </dependency>
spring-redis.xml 配置 Redis的连接池和连接
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxIdle" value="${redis.pool.maxIdle}" /> <property name="maxTotal" value="${redis.pool.maxTotal}" /> <property name="timeBetweenEvictionRunsMillis" value="${redis.pool.timeBetweenEvictionRunsMillis}" /> <property name="testOnBorrow" value="${redis.pool.testOnBorrow}" /> </bean> <bean id="jedisConnFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:host-name="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}" p:use-pool="true" p:pool-config-ref="poolConfig" /> <!-- <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate"> <property name="connectionFactory" ref="connectionFactory" /> </bean> --> <!-- redis template definition --> <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" p:connection-factory-ref="jedisConnFactory" />
redis.properties 连接的配置肯定是需要的
redis.host=x.x.x.x redis.port=6379 redis.pass= redis.maxWait=30000 redis.pool.maxTotal=1024 redis.pool.maxIdle=200 redis.pool.timeBetweenEvictionRunsMillis=30000 redis.pool.testOnBorrow=true
在需要使用的类中注入
@Resource protected RedisTemplate<Serializable, Serializable> redisTemplate;
组装一下key,统一设置前缀,可以方便的管理key
private String getJointName(String sid) { String ke 7fe0 y = RedisExpire.ONLINEUSER + ":" + sid;//":"为文件夹形式 return key; }
准备常量
public class RedisExpire { /** * Session 超时时间为30分钟 */ public final static Long ThirtyMinuteSecend= 30*60L;//秒 public final static String ONLINEUSER= "OnLineUser"; }
然后即可开始操作...如在登陆时写入redis并设置Session时长.
/** * 添加在线用户 * * @param sid 生成对用户的唯一id.即Session中的sessionid * source 为来源为后续app预留 * @param user * @return * @throws Exception */ public boolean addOnLinuUser(final String sid, final onLineUserInfo user, final String source) throws Exception { if (user != null && sid.trim().length() > 0) { final String key; key = getJointName(sid); Boolean falg = redisTemplate.execute(new RedisCallback<Boolean>() { public Boolean doInRedis(RedisConnection connection) throws DataAccessException { /*这里是存入时,序列化操作,可选 * @SuppressWarnings("unchecked") * RedisSerializer<onLineUserInfo> valueSerializer = * (RedisSerializer<onLineUserInfo>) redisTemplate * .getValueSerializer(); */ connection.select(2);//切换redis的DB可以不需要,redis默认配置为0-15共16个库,可以通过这行代码实现切换 connection.setEx(key.getBytes(), RedisExpire.ThirtyMinuteSecend, stringToByte(JSONObject.toJSONString(user)));//序列化采用了fastjson return true; } }); return falg; } return false; }
同理删除和获取
/** * 移除在线登陆用户 * * @param sid * source 为来源为后续app预留 * @return * @throws Exception */ public boolean removeOnLinuUser(final String sid, final String source) throws Exception { if (sid != null) { final String key; key = getJointName(sid); Boolean falg = redisTemplate.execute(new RedisCallback<Boolean>() { public Boolean doInRedis(RedisConnection connection) throws DataAccessException { connection.select(2); Long del = connection.del(key.getBytes()); if (del == 1) { return true; } else { return false; } } }); return falg; } return false; } /** * 获取在线用户信息 * * @param sid * source 为来源为后续app预留 * @return * @throws Exception */ public onLineUserInfo getOnLinuUser(String sid, final String source) throws Exception { final String key; key = getJointName(sid); onLineUserInfo userInfo = redisTemplate .execute(new RedisCallback<onLineUserInfo>() { public onLineUserInfo doInRedis(RedisConnection connection) throws DataAccessException { connection.select(2); byte[] bs = connection.get(key.getBytes()); String byteToString = byteToString(bs); onLineUserInfo userinfo = JSONObject.parseObject( byteToString, onLineUserInfo.class); /*if (userinfo != null) { // 如果用户已登录,则增加在线时间 connection.expire(key.getBytes(), RedisExpire.ThirtyMinuteSecend); }*/ return userinfo; } }); return userInfo; } }
文中的 onLineUserInfo 即你需要放入Session的登陆对象,可以自行编辑
public class onLineUserInfo implements Serializable{ private String name;// 用户名字 .......... }
不管存入cookie还是重写url...系统请求是需要带上sid即可.
PS:有人问我为什么要用顶级的key,不用Hash,因为redis的key是有上限的.主要是只有顶级的key才能有过期时间一说.这里牵涉到Redis的一些内部特征,大家可以去查阅关于Redis的文章.
相关文章推荐
- redis安装问题小结
- Redis偶发连接失败案例实战记录
- Redis中实现查找某个值的范围
- Redis和Memcached的区别详解
- 分割超大Redis数据库例子
- Redis总结笔记(一):安装和常用命令
- Redis sort 排序命令详解
- 用Redis实现微博关注关系
- redis中修改配置文件中的端口号 密码方法
- 在Ruby on Rails上使用Redis Store的方法
- Redis和Memcache的区别总结
- 在Node.js应用中使用Redis的方法简介
- Redis服务器的启动过程分析
- web 应用中常用的各种 cache详解
- 利用yum安装Redis的方法详解
- 从MySQL到Redis的简单数据库迁移方法
- 为啥懒 Redis 是更好的 Redis
- 利用Redis实现SQL伸缩的方法
- 在Redis数据库中实现分布式速率限制的方法
- PHP+redis实现添加处理投票的方法