公司网站用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);
不知道还有没有更好的办法和改进的余地
分享到:
相关推荐
在Tomcat 5.x 版本中,可以通过设置系统属性 `org.apache.catalina.SESSION_COOKIE_NAME` 来更改JSessionID在Cookie中的名称。具体操作步骤如下: 1. **Linux环境:** ```bash JAVA_OPTS="-Dorg.apache.catalina....
【描述】:“Tomcat集群Nginx使用Redis保证Session同步”这一场景中,通常是因为在多台Tomcat服务器组成的集群中,每个服务器各自维护独立的Session,当用户在集群中的不同服务器之间切换时,可能会导致Session丢失...
6. **Session粘滞(Session Stickiness)**:为了保持用户会话的连续性,可以配置mod_proxy_balancer来基于特定的会话ID或cookie将请求始终路由到同一个Tomcat实例。 7. **安全性**:使用SSL/TLS证书进行HTTPS配置...
Tomcat的集群功能依赖于org.apache.catalina.ha.session.JvmRouteBinderValve,它添加了JVM路由信息到Cookie,使得请求能够正确地发送到保存会话的服务器。此外,还需要配置共享的session存储,例如使用memcached或...
5. 配置session复制或粘滞会话:保持用户会话在集群中的连续性,可以通过session复制或者使用粘滞会话(基于cookie或IP哈希)来实现。 6. 测试和监控:完成配置后,通过测试各种请求来验证集群是否工作正常,并使用...
标题 "Tomcat7+Redis+Session 负载之后session 共享 tomcat jar包" 涉及的是在使用Nginx做负载均衡时,如何通过集成Redis来实现Tomcat7服务器之间的Session共享,从而确保用户在不同服务器之间切换时仍然能够保持...
Tomcat Redis Session Manager是一个插件,允许Tomcat将Session数据存储在Redis中,以便多个Tomcat实例之间共享。 以下是压缩包中提供的jar包及其作用: 1. tomcat-catalina-7.0.27.jar:这是Tomcat的主要组件之一...
- **cookie复制**:将session ID存储在cookie中,每次请求时,用户携带session ID到达任意节点,节点根据ID查找session。 - **共享内存**:所有Tomcat实例共享同一内存区域,session存储其中,但这种方法限制了集群...
标题中的“Tomcat8亲测可用 tomcat-redis-session-manager的jar包”指的是一个专为Tomcat8设计的,用于管理session的扩展组件。这个组件实现了将Tomcat应用服务器中的用户session数据存储到Redis分布式缓存系统中,...
Tomcat作为广泛使用的Java Servlet容器,可以通过整合其他技术,如Redis这样的内存数据存储系统,来实现跨服务器的session共享。本篇文章将深入讲解如何在Tomcat7中整合Redis,以实现session的共享,并提供必要的jar...
3. session ID管理:使用cookie或URL重写等方式保存session ID,确保请求能在不同的Tomcat实例间正确转发。 4. 故障转移:当某个Tomcat实例发生故障时,Apache应能够自动将请求切换到其他正常工作的实例,保证服务...
标题 "tomcat8-redis-session共享" 涉及到的是在Tomcat 8中使用Redis作为Session共享存储的解决方案。这是一个常见的需求,特别是在分布式系统中,为了保持用户会话的一致性,需要将Session数据在多台服务器之间共享...
- 在Tomcat的`conf/context.xml`或应用的`WEB-INF/web.xml`中添加`Manager`元素,指定使用`org.apache.catalina.session.PersistentManager`,并配置相关的Redis连接参数,如主机、端口、密码等。 - 配置Tomcat...
Tomcat 实现持久 Session Store 的接口为 org.apache.Catalina.store,目前提供了两个实现这一接口的类:org.apache.Catalina.FileStore 和 org.apache.Catalina.JDBCStore。 FileStore 将 HttpSession 对象保存在...
以下是实现Apache+Tomcat负载均衡整合的详细步骤: 1. **安装与配置Apache**: - 安装Apache HTTP服务器,并确保已启用mod_proxy、mod_proxy_balancer和mod_proxy_http模块。这些模块通常在默认的Apache安装中已经...
3. **使用cookie**:在cookie中存储session ID,每次请求时携带,Apache通过stickysession指令将请求定向到对应的Tomcat实例。 通过以上配置,我们可以构建一个高可用、负载均衡的Web服务系统。在实际操作中,还...
3. **Session复制**:Tomcat使用`org.apache.catalina.ha.session.DeltaManager`作为默认的集群session管理器,它负责在集群节点间同步session数据。DeltaManager使用序列化将session对象在节点间传输。 4. **...
3. **配置Session管理器**:Tomcat提供了`MemcachedSessionManager`和`org.apache.catalina.session.PersistentManagerBase`,但这里我们将使用`RedisSessionManager`。首先,添加`tomcat-redis-session-manager`...
可以使用Session对象或者Cookie来保存验证码值。 4. **用户输入验证**:用户提交验证码后,服务器会接收到用户输入的值。这时,需要对比用户输入与服务器存储的验证码是否一致,如果匹配则验证成功。 在Apache ...