发表于20小时前(2016-02-22 12:51) 阅读( 401 ) | 评论( 0 ) 0 人收藏此文章,
赞 0
3月19日 深圳 OSC 源创会开始报名啦 —— React Native 实践
在分布式系统中.前提是分布式或者集群环境,常常需要多个系统中,保持sesstion. nginx可以配置IP的hash,实现每次都访问同一台应用容器,从而不需要共享sesstion,也有tomcat的复制. 虽然tomcat等容器可以实现sesstion的复制,但是在tomcat的数量过多时,复制的延迟和性能的损失 将因为tomcat的数量直线上升. 这里可以用redis简单的将sesstion集中管理.线上环境将redis高可用即可.
redis sesstion共享 jedis 分布式sesstion管理
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="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
`<br /> private String getJointName(String sid) { String key = RedisExpire.ONLINEUSER + ":" + sid;//":"为文件夹形式 return key; }
准备常量 ``
public class RedisExpire {
/** * sesstion超时时间为30分钟 */ public final static Long ThirtyMinuteSecend= 30*60L;//秒 public final static String ONLINEUSER= "OnLineUser";
} ```
然后即可开始操作...如在登陆时写入redis并设置seestion时长. ``` /* * 添加在线用户 * * @param sid 生成对用户的唯一id.即sesstion中的sesstionid * 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
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
} }); 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 即你需要放入sesstion的登陆对象,可以自行编辑
` public class onLineUserInfo implements Serializable{
private String name;// 用户名字 ..........
} ``` 不管存入cookie还是重写url...系统请求是需要带上sid即可.
PS:有人问我为什么要用顶级的key,不用Hash,因为redis的key是有上限的.主要是只有顶级的key才能有过期时间一说.这里牵涉到Redis的一些内部特征,大家可以去查阅关于Redis的文章.