📄 jvmroutebindervalve.java
字号:
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $
*/
public class JvmRouteBinderValve extends ValveBase implements ClusterValve, Lifecycle {
/*--Static Variables----------------------------------------*/
public static org.apache.juli.logging.Log log = org.apache.juli.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.isDebugEnabled())
log.debug(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 + -