📄 jvmroutebindervalve.java
字号:
/**
* @param cluster The cluster to set.
*/
public void setCluster(CatalinaCluster cluster) {
this.cluster = cluster;
}
/**
* Handle jvmRoute stickyness after tomcat instance failed. After this
* correction a new Cookie send to client with new jvmRoute and the
* SessionID change propage to the other cluster nodes.
*
* @param request current request
* @param response
* Tomcat Response
* @param sessionId
* request SessionID from Cookie
* @param localJvmRoute
* local jvmRoute
*/
protected void handleJvmRoute(
Request request, Response response,String sessionId, String localJvmRoute) {
// get requested jvmRoute.
String requestJvmRoute = null;
int index = sessionId.indexOf(".");
if (index > 0) {
requestJvmRoute = sessionId
.substring(index + 1, sessionId.length());
}
if (requestJvmRoute != null && !requestJvmRoute.equals(localJvmRoute)) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("jvmRoute.failover", requestJvmRoute,
localJvmRoute, sessionId));
}
// OK - turnover the session ?
String newSessionID = sessionId.substring(0, index) + "."
+ localJvmRoute;
Session catalinaSession = null;
try {
catalinaSession = getManager(request).findSession(sessionId);
} catch (IOException e) {
// Hups!
}
if (catalinaSession != null) {
changeSessionID(request, response, sessionId, newSessionID,
catalinaSession);
numberOfSessions++;
} else {
if (log.isDebugEnabled()) {
log.debug(sm.getString("jvmRoute.cannotFindSession",
sessionId));
}
}
}
}
/**
* change session id and send to all cluster nodes
*
* @param request current request
* @param response current response
* @param sessionId
* original session id
* @param newSessionID
* new session id for node migration
* @param catalinaSession
* current session with original session id
*/
protected void changeSessionID(Request request,
Response response, String sessionId, String newSessionID, Session catalinaSession) {
lifecycle.fireLifecycleEvent("Before session migration",
catalinaSession);
request.setRequestedSessionId(newSessionID);
catalinaSession.setId(newSessionID);
if (catalinaSession instanceof DeltaSession)
((DeltaSession) catalinaSession).resetDeltaRequest();
if(request.isRequestedSessionIdFromCookie()) setNewSessionCookie(request, response,newSessionID);
// set orginal sessionid at request, to allow application detect the
// change
if (sessionIdAttribute != null && !"".equals(sessionIdAttribute)) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("jvmRoute.set.orignalsessionid",sessionIdAttribute,sessionId));
}
request.setAttribute(sessionIdAttribute, sessionId);
}
// now sending the change to all other clusternode!
ClusterManager manager = (ClusterManager)catalinaSession.getManager();
sendSessionIDClusterBackup(manager,request,sessionId, newSessionID);
lifecycle
.fireLifecycleEvent("After session migration", catalinaSession);
if (log.isDebugEnabled()) {
log.debug(sm.getString("jvmRoute.changeSession", sessionId,
newSessionID));
}
}
/**
* Send the changed Sessionid to all clusternodes.
*
* @see JvmRouteSessionIDBinderListener#messageReceived(ClusterMessage)
* @param manager
* ClusterManager
* @param sessionId
* current failed sessionid
* @param newSessionID
* new session id, bind to the new cluster node
*/
protected void sendSessionIDClusterBackup(ClusterManager manager,Request request,String sessionId,
String newSessionID) {
SessionIDMessage msg = new SessionIDMessage();
msg.setOrignalSessionID(sessionId);
msg.setBackupSessionID(newSessionID);
Context context = request.getContext();
msg.setContextPath(context.getPath());
msg.setHost(context.getParent().getName());
if(manager.doDomainReplication())
cluster.sendClusterDomain(msg);
else
cluster.send(msg);
}
/**
* Sets a new cookie for the given session id and response and see
* {@link org.apache.catalina.connector.Request#configureSessionCookie(javax.servlet.http.Cookie)}
*
* @param request current request
* @param response Tomcat Response
* @param sessionId The session id
*/
protected void setNewSessionCookie(Request request,
Response response, String sessionId) {
if (response != null) {
Context context = request.getContext();
if (context.getCookies()) {
// set a new session cookie
Cookie newCookie = new Cookie(Globals.SESSION_COOKIE_NAME,
sessionId);
newCookie.setMaxAge(-1);
String contextPath = null;
if (!response.getConnector().getEmptySessionPath()
&& (context != null)) {
contextPath = context.getEncodedPath();
}
if ((contextPath != null) && (contextPath.length() > 0)) {
newCookie.setPath(contextPath);
} else {
newCookie.setPath("/");
}
if (request.isSecure()) {
newCookie.setSecure(true);
}
if (log.isDebugEnabled()) {
log.debug(sm.getString("jvmRoute.newSessionCookie",
sessionId, Globals.SESSION_COOKIE_NAME, newCookie
.getPath(), new Boolean(newCookie
.getSecure())));
}
response.addCookie(newCookie);
}
}
}
// ------------------------------------------------------ Lifecycle Methods
/**
* Add a lifecycle event listener to this component.
*
* @param listener
* The listener to add
*/
public void addLifecycleListener(LifecycleListener listener) {
lifecycle.addLifecycleListener(listener);
}
/**
* Get the lifecycle listeners associated with this lifecycle. If this
* Lifecycle has no listeners registered, a zero-length array is returned.
*/
public LifecycleListener[] findLifecycleListeners() {
return lifecycle.findLifecycleListeners();
}
/**
* Remove a lifecycle event listener from this component.
*
* @param listener
* The listener to add
*/
public void removeLifecycleListener(LifecycleListener listener) {
lifecycle.removeLifecycleListener(listener);
}
/**
* Prepare for the beginning of active use of the public methods of this
* component. This method should be called after <code>configure()</code>,
* and before any of the public methods of the component are utilized.
*
* @exception LifecycleException
* if this component detects a fatal error that prevents this
* component from being used
*/
public void start() throws LifecycleException {
// Validate and update our current component state
if (started)
throw new LifecycleException(sm
.getString("jvmRoute.valve.alreadyStarted"));
lifecycle.fireLifecycleEvent(START_EVENT, null);
started = true;
if (cluster == null) {
Container hostContainer = getContainer();
// compatibility with JvmRouteBinderValve version 1.1
// ( setup at context.xml or context.xml.default )
if (!(hostContainer instanceof Host)) {
if (log.isWarnEnabled())
log.warn(sm.getString("jvmRoute.configure.warn"));
hostContainer = hostContainer.getParent();
}
if (hostContainer instanceof Host
&& ((Host) hostContainer).getCluster() != null) {
cluster = (CatalinaCluster) ((Host) hostContainer).getCluster();
} else {
Container engine = hostContainer.getParent() ;
if (engine instanceof Engine
&& ((Engine) engine).getCluster() != null) {
cluster = (CatalinaCluster) ((Engine) engine).getCluster();
}
}
}
if (cluster == null) {
throw new RuntimeException("No clustering support at container "
+ container.getName());
}
if (log.isInfoEnabled())
log.info(sm.getString("jvmRoute.valve.started"));
}
/**
* Gracefully terminate the active use of the public methods of this
* component. This method should be the last one called on a given instance
* of this component.
*
* @exception LifecycleException
* if this component detects a fatal error that needs to be
* reported
*/
public void stop() throws LifecycleException {
// Validate and update our current component state
if (!started)
throw new LifecycleException(sm
.getString("jvmRoute.valve.notStarted"));
lifecycle.fireLifecycleEvent(STOP_EVENT, null);
started = false;
cluster = null;
numberOfSessions = 0;
if (log.isInfoEnabled())
log.info(sm.getString("jvmRoute.valve.stopped"));
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -