📄 jvmroutebindervalve.java
字号:
/* * Copyright 1999,2004-2005 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.catalina.ha.session;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.Cookie;import org.apache.catalina.Container;import org.apache.catalina.Context;import org.apache.catalina.Engine;import org.apache.catalina.Globals;import org.apache.catalina.Host;import org.apache.catalina.Lifecycle;import org.apache.catalina.LifecycleException;import org.apache.catalina.LifecycleListener;import org.apache.catalina.Manager;import org.apache.catalina.Session;import org.apache.catalina.ha.CatalinaCluster;import org.apache.catalina.ha.ClusterManager;import org.apache.catalina.ha.ClusterMessage;import org.apache.catalina.ha.ClusterValve;import org.apache.catalina.connector.Request;import org.apache.catalina.connector.Response;import org.apache.catalina.session.ManagerBase;import org.apache.catalina.util.LifecycleSupport;import org.apache.catalina.util.StringManager;import org.apache.catalina.valves.ValveBase;/** * Valve to handle Tomcat jvmRoute takeover using mod_jk module after node * failure. After a node crashed the next request going to other cluster node. * Now the answering from apache is slower ( make some error handshaking. Very * bad with apache at my windows.). We rewrite now the cookie jsessionid * information to the backup cluster node. After the next response all client * request goes direct to the backup node. The change sessionid send also to all * other cluster nodes. Well, now the session stickyness work directly to the * backup node and traffic don't go back too restarted cluster nodes! * * At all cluster node you must configure the as ClusterListener since 5.5.10 * {@link org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener JvmRouteSessionIDBinderListener} * or before with * org.apache.catalina.ha.session.JvmRouteSessionIDBinderListenerLifecycle. * * Add this Valve to your host definition at conf/server.xml . * * Since 5.5.10 as direct cluster valve:<br/> * <pre> * <Cluster> * <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve" /> * </Cluster> * </pre> * <br /> * Before 5.5.10 as Host element:<br/> * <pre> * <Hostr> * <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve" /> * </Hostr> * </pre> * * Trick:<br/> * You can enable this mod_jk turnover mode via JMX before you drop a node to all backup nodes! * Set enable true on all JvmRouteBinderValve backups, disable worker at mod_jk * and then drop node and restart it! Then enable mod_jk Worker and disable JvmRouteBinderValves again. * This use case means that only requested session are migrated. * * @author Peter Rossbach * @version $Revision: 326110 $ $Date: 2005-10-18 09:08:36 -0500 (Tue, 18 Oct 2005) $ */public class JvmRouteBinderValve extends ValveBase implements ClusterValve, Lifecycle { /*--Static Variables----------------------------------------*/ public static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory .getLog(JvmRouteBinderValve.class); /** * The descriptive information about this implementation. */ protected static final String info = "org.apache.catalina.ha.session.JvmRouteBinderValve/1.2"; /*--Instance Variables--------------------------------------*/ /** * the cluster */ protected CatalinaCluster cluster; /** * The string manager for this package. */ protected StringManager sm = StringManager.getManager(Constants.Package); /** * Has this component been started yet? */ protected boolean started = false; /** * enabled this component */ protected boolean enabled = true; /** * number of session that no at this tomcat instanz hosted */ protected long numberOfSessions = 0; protected String sessionIdAttribute = "org.apache.catalina.ha.session.JvmRouteOrignalSessionID"; /** * The lifecycle event support for this component. */ protected LifecycleSupport lifecycle = new LifecycleSupport(this); /*--Logic---------------------------------------------------*/ /** * Return descriptive information about this implementation. */ public String getInfo() { return (info); } /** * set session id attribute to failed node for request. * * @return Returns the sessionIdAttribute. */ public String getSessionIdAttribute() { return sessionIdAttribute; } /** * get name of failed reqeust session attribute * * @param sessionIdAttribute * The sessionIdAttribute to set. */ public void setSessionIdAttribute(String sessionIdAttribute) { this.sessionIdAttribute = sessionIdAttribute; } /** * @return Returns the number of migrated sessions. */ public long getNumberOfSessions() { return numberOfSessions; } /** * @return Returns the enabled. */ public boolean getEnabled() { return enabled; } /** * @param enabled * The enabled to set. */ public void setEnabled(boolean enabled) { this.enabled = enabled; } /** * Detect possible the JVMRoute change at cluster backup node.. * * @param request * tomcat request being processed * @param response * tomcat response being processed * @exception IOException * if an input/output error has occurred * @exception ServletException * if a servlet error has occurred */ public void invoke(Request request, Response response) throws IOException, ServletException { if (getEnabled() && getCluster() != null && request.getContext() != null && request.getContext().getDistributable() ) { // valve cluster can access manager - other cluster handle turnover // at host level - hopefully! Manager manager = request.getContext().getManager(); if (manager != null && manager instanceof ClusterManager && getCluster().getManager(((ClusterManager)manager).getName()) != null) handlePossibleTurnover(request, response); } // Pass this request on to the next valve in our pipeline getNext().invoke(request, response); } /** * handle possible session turn over. * * @see JvmRouteBinderValve#handleJvmRoute(Request, Response, String, String) * @param request current request * @param response current response */ protected void handlePossibleTurnover(Request request, Response response) { Session session = request.getSessionInternal(false); if (session != null) { long t1 = System.currentTimeMillis(); String jvmRoute = getLocalJvmRoute(request); if (jvmRoute == null) { if (log.isWarnEnabled()) log.warn(sm.getString("jvmRoute.missingJvmRouteAttribute")); return; } handleJvmRoute( request, response,session.getIdInternal(), jvmRoute); if (log.isDebugEnabled()) { long t2 = System.currentTimeMillis(); long time = t2 - t1; log.debug(sm.getString("jvmRoute.turnoverInfo", new Long(time))); } } } /** * get jvmroute from engine * * @param request current request * @return return jvmRoute from ManagerBase or null */ protected String getLocalJvmRoute(Request request) { Manager manager = getManager(request); if(manager instanceof ManagerBase) return ((ManagerBase) manager).getJvmRoute(); return null ; } /** * get Cluster DeltaManager * * @param request current request * @return manager or null */ protected Manager getManager(Request request) { Manager manager = request.getContext().getManager(); if (log.isDebugEnabled()) { if(manager != null) log.debug(sm.getString("jvmRoute.foundManager", manager, request.getContext().getName())); else log.debug(sm.getString("jvmRoute.notFoundManager", manager, request.getContext().getName())); } return manager; } /** * @return Returns the cluster. */ public CatalinaCluster getCluster() { return cluster; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -