1、使用场景
分布式session功能在于集中式管理session信息,强化session的高可用,例如单机版session存储,当用户请求的服务器发生故障时,此时将用户的访问请求重定向到另外一台服务器就会出现session丢失而用户被迫退出,分布式session可以集中管理,去掉中心化带来的系统扩展性弱和高可用性差等问题。一般分布式的缓存服务可以充当session存储,由于zookeeper的节点最大存储内容体可以达到1M,并且session的特点基本是读多写少,所以zookeeper也可以作为分布式session实现的一个承载体。本章我们就zookeeper实现的一个分布式session进行一个详细阐述。
2、实现逻辑
系统首先需要session将访问zookeeper接口做一层封装,对外提供基于zookeeper的增加,删除,获取session的接口,同时需要设计一个sessionData的类,用来存储session的原数据,其中有一个map就是用来存储session的属性值的。接下来需要自定义一个filter,将所有请求进行过滤,并且将request转化为httpRequestWapper,包装之后应用系统通过request任何操作session的接口都会被代理到我们事先事先的httpRequestWapper里面,进而通过httpRequestWapper将session数据存储到zookeeper,或者从zookeeper读取。
3、代码实现
首先我们定义一个session元数据类,用来操作所有session的属性,如下
/**
*
*/
package com.flykingmz.zookeeper.dSession.model;
import java.io.Serializable;
import java.util.Map;
/**
* @author flyking
*
*/
public class DSessionData implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* sessionId
*/
private String id;
/**
* session创建时间
*/
private Long createTime;
/**
* 最后一次访问时间
*/
private Long lastAccessTime;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Long getCreateTime() {
return createTime;
}
public Long getLastAccessTime() {
return lastAccessTime;
}
public void setLastAccessTime(Long lastAccessTime) {
this.lastAccessTime = lastAccessTime;
}
public Map<String, String> getSessionContext() {
return sessionContext;
}
public void setSessionContext(Map<String, String> sessionContext) {
this.sessionContext = sessionContext;
}
/**
* session内容体
*/
private Map<String, String> sessionContext;
public DSessionData() {
this.createTime = System.currentTimeMillis();
this.lastAccessTime = this.createTime;
}
}
接下来定义基于zookeeper的dao层封装实现。
/**
*
*/
package com.flykingmz.zookeeper.dSession.dao;
import org.I0Itec.zkclient.ZkClient;
import com.flykingmz.zookeeper.dSession.json.Json;
import com.flykingmz.zookeeper.dSession.model.DSessionData;
/**
* @author flyking
*
*/
public class DSessionDaoImpl implements DSessionDao {
private ZkClient client;
private String zookeeperURL;
public void setZookeeperURL(String zookeeperURL) {
this.zookeeperURL = zookeeperURL;
}
public void init() {
this.client = new ZkClient(zookeeperURL);
}