摘自:http://www.th7.cn/Program/java/201411/323454.shtml
利用memcache实现session共享
在开发过程中,为了缓解访问压力,往往需要配置负载均衡,也就是相同的项目放在多台机子上,保证一台机子挂了,网站仍然可以正常访问,除了需要使用相同的数据源,资料源之外,最大的问题莫过于session的共享了。这里session共享的核心在于改变原来session中的键值对存放在每台机子各自的内存中的情况,而是把session中的内容集中存放在一个nosql数据库中。
3.1封装request对象:
package com.sse.roadshow.session;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import com.sse.roadshow.common.SpyMemcachedManager;
public class HttpServletRequestWrapper extends
javax.servlet.http.HttpServletRequestWrapper {
String sid = "";
private SpyMemcachedManager spyMemcachedManager;
public HttpServletRequestWrapper(String sid, HttpServletRequest request,SpyMemcachedManager spyMemcachedManager) {
super(request);
this.sid = sid;
this.spyMemcachedManager = spyMemcachedManager;
}
public HttpSession getSession(boolean create) {
return new HttpSessionSidWrapper(this.sid, super.getSession(create), this.spyMemcachedManager);
}
public HttpSession getSession() {
return new HttpSessionSidWrapper(this.sid, super.getSession(), this.spyMemcachedManager);
}
}
通过封装传递数据源,并且覆盖getSession方法,自定义的session对象在下一步
3.2封装session对象
package com.sse.roadshow.session;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpSession;
import com.sse.roadshow.common.Constants;
import com.sse.roadshow.common.SpyMemcachedManager;
import com.sse.roadshow.vo.Enumerator;
publicclass HttpSessionSidWrapper extends HttpSessionWrapper {
private Stringsid = "";
privateMap map =new HashMap();
private SpyMemcachedManagerspyMemcachedManager;
@SuppressWarnings("rawtypes")
public HttpSessionSidWrapper(Stringsid, HttpSession session, SpyMemcachedManagerspyMemcachedManager) {
super(session);
if (spyMemcachedManager ==null) {
System.out.println("spyMemcachedManager is null.....");
return;
}
this.spyMemcachedManager =spyMemcachedManager;
this.sid =sid;
MapmemSession = null;
memSession = (Map)this.spyMemcachedManager.get(sid);
//sid没有加入到session中,需要初始化session,替换为自定义session
if (memSession ==null) {
// System.out.println("memSession is null");
memSession =new HashMap();
// this.spyMemcachedManager.set(sid, memSession, Constants.SPMEM_EXPTIME);
if (session !=null) {
Enumerationnames = session.getAttributeNames();
while (names.hasMoreElements()) {
Stringkey = (String) names.nextElement();
memSession.put(key,session.getAttribute(key));
}
}
}
this.map =memSession;
}
public Object getAttribute(Stringkey) {
if (this.map !=null && this.map.containsKey(key)) {
returnthis.map.get(key);
}else {
returnnull;
}
}
@SuppressWarnings({"unchecked", "rawtypes" })
public Enumeration getAttributeNames() {
return (new Enumerator(this.map.keySet(),true));
// return super.getAttributeNames();
}
publicvoid invalidate() {
// super.invalidate();
this.map.clear();
longs1= System.currentTimeMillis();
try {
spyMemcachedManager.delete(sid);
System.out.print("removeSession sid is:" +sid);
}
finally{
System.out.println(System.currentTimeMillis() -s1);
}
}
publicvoid removeAttribute(String name) {
// super.removeAttribute(name);
this.map.remove(name);
attributeChange();
// System.out.print("removeAttribute");
// System.out.println("key : " + name);
}
@SuppressWarnings("unchecked")
publicvoid setAttribute(String name, Object value) {
// super.setAttribute(name, value);
this.map.put(name,value);
attributeChange();
// System.out.print("setAttribute-");
// System.out.println("key : " + name + ", value : " + value);
}
privatevoid attributeChange() {
spyMemcachedManager.set(sid,this.map, Constants.MYFILTER_COOKIE_EXPTIME);
}
}
这里覆盖session的操作方法,取值使用我们从memcache中查出来的数据
3.3引入我们刚才封装好的request对象:
使用过滤器过滤对应路径的请求,引入自定义request:
3.3.1自定义过滤器:
package com.sse.roadshow.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.context.support.WebApplicationContextUtils;
import com.sse.roadshow.common.Constants;
import com.sse.roadshow.common.SpyMemcachedManager;
import com.sse.roadshow.common.Util;
import com.sse.roadshow.session.HttpServletRequestWrapper;
public class MemcachedSessionFilter extends HttpServlet implements Filter {
/**
*
*/
private static final long serialVersionUID = 8928219999641126613L;
// private FilterConfig filterConfig;
private String cookieDomain = "";
private String cookiePath = "/";
private SpyMemcachedManager spyMemcachedManager;
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
String sessionId = "XmlBeanDefinitionReaderSid";
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
Cookie cookies[] = request.getCookies();
Cookie sCookie = null;
String sid = "";
if (cookies != null && cookies.length > 0) {
for (int i = 0; i < cookies.length; i++) {
sCookie = cookies[i];
if (sCookie.getName().equals(sessionId)) {
sid = sCookie.getValue();
}
}
}
if (sid == null || sid.length() == 0) {
sid = java.util.UUID.randomUUID().toString();
Cookie mycookies = new Cookie(sessionId, sid);
mycookies.setMaxAge(-1);
mycookies.setPath("/");
mycookies.setHttpOnly(true);
mycookies.setDomain(Constants.DOMAIN);
response.addCookie(mycookies);
}
spyMemcachedManager = getBean(request);
filterChain.doFilter(new HttpServletRequestWrapper(sid, request, spyMemcachedManager),
servletResponse);
}
private SpyMemcachedManager getBean(HttpServletRequest request) {
if(Util.isNull(spyMemcachedManager)) {
spyMemcachedManager = WebApplicationContextUtils.getWebApplicationContext(request.getServletContext()).getBean(SpyMemcachedManager.class);
}
return spyMemcachedManager;
}
public void init(FilterConfig filterConfig) throws ServletException {
// this.filterConfig = filterConfig;
// this.sessionId = filterConfig.getInitParameter("sessionId");
this.cookiePath = filterConfig.getInitParameter("cookiePath");
if (this.cookiePath == null || this.cookiePath.length() == 0) {
this.cookiePath = "/";
}
this.cookieDomain = filterConfig.getInitParameter("cookieDomain");
if (this.cookieDomain == null) {
this.cookieDomain = Constants.DOMAIN;
}
}
public SpyMemcachedManager getSpyMemcachedManager() {
return spyMemcachedManager;
}
public void setSpyMemcachedManager(SpyMemcachedManager spyMemcachedManager) {
this.spyMemcachedManager = spyMemcachedManager;
}
}
3.3.2.在web.xml中配置filter:
mySessionFilter
com.sse.roadshow.filter.MemcachedSessionFilter
mySessionFilter
/*
这样session共享就配置完毕了。
分享到:
相关推荐
为了解决这个问题,我们可以引入外部存储系统,如memcache,来实现session的集中存储和共享。Memcache是一款高性能、分布式的内存对象缓存系统,它可以将数据存储在内存中,以提供快速的数据访问。在Tomcat8中,我们...
确保它能在网络中被Tomcat访问到,并设置合适的内存大小以存储Session数据。 2. **添加依赖**:压缩包中的jar文件包含了实现Memcached Session管理所需的类库。你需要将这些jar添加到Tomcat的类路径中,这通常通过...
为了解决这个问题,我们可以利用第三方缓存系统,如Memcached,来实现Session的集中式存储和共享。"tomcat7集群session共享memcache依赖包1.8.3"这个标题正揭示了这样一个解决方案。 首先,让我们深入了解Tomcat7...
5. **处理session数据一致性**:在使用Memcache存储session数据时,需要注意数据的一致性问题。由于Memcache是非持久化的,当服务器重启或memcache服务出现问题时,session数据可能会丢失。为避免这种情况,可以考虑...
2. 使用独立的服务(如redis或memcache)存储session数据,这种方式更为推荐,因为它避免了转发规则的复杂性,并且支持跨服务器的数据共享。 在Nginx配置示例中,upstream块定义了服务器集群,其中每个服务器都有一...
通过将Session数据存储在集中式的缓存系统(如Memcached)或数据库中,所有服务器都可以访问同一份Session数据。 - PHP中实现Session共享,需要在配置文件中设置`session.save_handler`为`memcached`或`redis`,并...
不依赖PHP内置的Session机制,而是在memcache中存储类似Session的数据,避免了单点故障,增强了系统的可靠性。 #### 四、服务器硬件与软件配置 针对不同功能的服务器,设计了差异化的硬件配置方案。例如,nginx...
- 使用中央数据库或缓存服务(如Redis)来集中存储Session数据。 2. **PHP连接MySQL的几种方式及区别** - **MySQLi**:面向对象,支持预处理语句,提供了更多的功能和更好的性能。 - **PDO**(PHP Data Objects...
1. 系统的整体架构:航旅纵横的系统架构设计采用了分布式设计理念,包括了接入接口协议、用户授权、消息通知、session数据缓存(memcache)、分布式RPC调用、业务逻辑处理、IM缓存数据二次缓存、分布式数据访问、...