📄 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.isSendClusterDomainOnly()) 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 + -