公司网站用Apache+Tomcat集群后,经过观察发现Tomcat之间的Session复制非常的消耗资源。一个Tomcat挂掉后,另外一个要复制很久才能复制完成。导致如果session很多,一个Tomcat挂掉,网站访问变得很慢.
现在改成Cookie来取替Tomcat之间的复制,具体实现方式如下:
登录时将用户信息存入一份在Session中,然后向用户的本机中插入一条cookie信息。由于去掉了Tomcat之间Session的复制所以需要用到Session业务的时候,在一个Tomcat中有session信息,如果在这个过程中被分配到另外一个Tomcat运行后就会出现找不到Session信息的错误。考虑到这一条我写了一个过滤器来对网站的请求进行过滤,先判断session中有没有值。如果有就过,如果没有就到本地来取一次cookie,如果存在即在当前Tomcat上恢复Session.代码如下
Cookie工具类
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* Cookie 工具类增,删,查
*
* @author ws715
*
*/
public class CookieUtil {
/**
* 按名字得到Cookie
*
* @param request
* @param name
* @return
*/
private CookieUtil() {
}
public static Cookie getCookie(HttpServletRequest request, String name) {
Cookie cookies[] = request.getCookies();
if (cookies == null || name == null || name.length() == 0) {
return null;
}
if (cookies != null) {
for (int i = 0; i < cookies.length; i++) {
if (name.equals(cookies[i].getName())) {
return cookies[i];
}
}
}
return null;
}
/**
* 将cookie中的数据保存到session中
*
* @param request
* @param name
* @return
*/
public static boolean setSessionFormCookie(HttpServletRequest request,
String name) {
String target = null;
Cookie cookies[] = request.getCookies();
boolean bool = false;
if (cookies == null || name == null || name.length() == 0) {
bool = false;
}
if (cookies != null) {
for (int i = 0; i < cookies.length; i++) {
if (name.equals(cookies[i].getName())) {
target = cookies[i].getValue();
break;
}
}
}
if (target != null && !target.equals("")) {
HttpSession session = request.getSession();
session.setAttribute("UserName", target.toString());
bool = true;
}
return bool;
}
/**
* 删除Cookie
*
* @param request
* @param response
* @param cookie
*/
public static void deleteCookie(HttpServletRequest request,
HttpServletResponse response, Cookie cookie) {
if (cookie != null) {
cookie.setPath(getPath(request));
cookie.setValue("");
// cookie.setDomain("");
cookie.setMaxAge(0);
response.addCookie(cookie);
}
}
/**
* 按名字删除
*
* @param request
* @param response
* @param name
*/
public static void deleteCookie(HttpServletRequest request,
HttpServletResponse response, String name) {
Cookie cookies[] = request.getCookies();
Cookie myCookie = null;
boolean bool = false;
if (cookies == null || name == null || name.length() == 0) {
throw new NullPointerException(
"getCookie deleteCookie method name is not null");
}
if (cookies != null) {
for (int i = 0; i < cookies.length; i++) {
if (name.equals(cookies[i].getName())) {
myCookie = cookies[i];
break;
}
}
if (myCookie != null) {
deleteCookie(request, response, myCookie);
}
}
}
/**
* 保存到Cookie中
*
* @param request
* @param response
* @param name
* @param value
*/
public static void setCookie(HttpServletRequest request,
HttpServletResponse response, String name, String value) {
setCookie(request, response, name, value, 0x278d00);
}
/**
* 可以设置时间
*
* @param request
* @param response
* @param name
* @param value
* @param maxAge
*/
public static void setCookie(HttpServletRequest request,
HttpServletResponse response, String name, String value, int maxAge) {
Cookie cookie = new Cookie(name, value == null ? "" : value);
cookie.setMaxAge(maxAge);
// cookie.setDomain(request.getServerName());
cookie.setPath(getPath(request));
response.addCookie(cookie);
}
private static String getPath(HttpServletRequest request) {
String path = request.getContextPath();
return (path == null || path.length() == 0) ? "/" : path;
}
/**
* 从cookie中获得username
*
* @param request
* @param name
* @return
*/
public static String getUserNameForCookie(HttpServletRequest request,
String name) {
String username = "";
Cookie cookies[] = request.getCookies();
if (cookies == null || name == null || name.length() == 0) {
return null;
}
if (cookies != null) {
for (int i = 0; i < cookies.length; i++) {
if (name.equals(cookies[i].getName())) {
try {
username = (cookies[i].getValue().split("#"))[0];
} catch (Exception e) {
username = null;
}
}
}
}
return username;
}
}
过滤器
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.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class SessionCookieFilter implements Filter {
public void destroy() {
// TODO Auto-generated method stub
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
// 通过检查session中的变量,过虑请求
HttpSession session = httpServletRequest.getSession();
String UserName="guest" ;
if(session.getAttribute("UserName")==null ||
session.getAttribute("UserName").equals("guest")){
if(!com.pixel.util.CookieUtil.setSessionFormCookie(httpServletRequest,"cookiename")){
session.setAttribute("UserName",UserName);
}
}
chain.doFilter(request, response);
}
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
登录时加入cookie中
CookieUtil.setCookie(request,response,"cookiename",cookieValue.toString(),60*120);
不知道还有没有更好的办法和改进的余地