tomcat源码解析--SessionManager

Manager 是tomcat 用于管理session的操作的定义,ManagerBase 设置默认参数,实现一些公用方法

StandardManager 是真正tomcat用来处理session的管理器,它实现了lifecycle接口,具体的关系如下



 其中clusterManager是定义集群环境下session管理的操作,clusterManagerBase继承了ManagerBase,实现了ClusterManager,是真正集群环境中使用的session管理器

Manager中的操作:



 

每个managerbase都会与一个context绑定,初始化init方法

 

Java代码   收藏代码
  1. if( initialized ) return;  
  2.         initialized=true;          
  3.           
  4.         log = LogFactory.getLog(ManagerBase.class);  
  5.           
  6.         if( oname==null ) {  
  7.             try {  
  8.                 StandardContext ctx=(StandardContext)this.getContainer();  
  9.                 Engine eng=(Engine)ctx.getParent().getParent();  
  10.                 domain=ctx.getEngineName();  
  11.                 distributable = ctx.getDistributable();  
  12.                 StandardHost hst=(StandardHost)ctx.getParent();  
  13.                 String path = ctx.getPath();  
  14.                 if (path.equals("")) {  
  15.                     path = "/";  
  16.                 }     
  17.                 oname=new ObjectName(domain + ":type=Manager,path="  
  18.                 + path + ",host=" + hst.getName());  
  19.                 Registry.getRegistry(nullnull).registerComponent(this, oname, null );  
  20.             } catch (Exception e) {  
  21.                 log.error("Error registering ",e);  
  22.             }  
  23.         }  
  24.           
  25.         // Initialize random number generation  
  26.         getRandomBytes(new byte[16]);  
  27.           
  28.         // Ensure caches for timing stats are the right size by filling with  
  29.         // nulls.  
  30.         while (sessionCreationTiming.size() < TIMING_STATS_CACHE_SIZE) {  
  31.             sessionCreationTiming.add(null);  
  32.         }  
  33.         while (sessionExpirationTiming.size() < TIMING_STATS_CACHE_SIZE) {  
  34.             sessionExpirationTiming.add(null);  
  35.         }  
  36.   
  37.         if(log.isDebugEnabled())  
  38.             log.debug("Registering " + oname );  


 ManagerBase 中定义了用于生成session的random 值的方法(值得参考)

 

(entropy[i]) << ((i % 8) * 8)

 

Java代码   收藏代码
  1. public Random getRandom() {  
  2.        if (this.random == null) {  
  3.            // Calculate the new random number generator seed  
  4.            long seed = System.currentTimeMillis();  
  5.            long t1 = seed;  
  6.            char entropy[] = getEntropy().toCharArray();  
  7.            for (int i = 0; i < entropy.length; i++) {  
  8. /这里提供了一个 char 字符 变成long的方法, entropy[i]) << ((i % 8) * 8  
  9.                long update = ((long) entropy[i]) << ((i % 8) * 8);  
  10.                seed ^= update;  
  11.            }  
  12.            try {  
  13.                // Construct and seed a new random number generator  
  14.                Class clazz = Class.forName(randomClass);  
  15.                this.random = (Random) clazz.newInstance();  
  16.                this.random.setSeed(seed);  
  17.            } catch (Exception e) {  
  18.                // Fall back to the simple case  
  19.                log.error(sm.getString("managerBase.random", randomClass),  
  20.                        e);  
  21.                this.random = new java.util.Random();  
  22.                this.random.setSeed(seed);  
  23.            }  
  24.            if(log.isDebugEnabled()) {  
  25.                long t2=System.currentTimeMillis();  
  26.                if( (t2-t1) > 100 )  
  27.                    log.debug(sm.getString("managerBase.seeding", randomClass) + " " + (t2-t1));  
  28.            }  
  29.        }  
  30.          
  31.        return (this.random);  

 调用得到32bit 随机字符的方法

 

注意,这里调用了org.apache.tomcat.jni.OS的静态方法public static native int random(byte [] buf, int len);来得到随机数组,native关键字是指tomcat在这里调用了外部的非java方法来实现这个调用

 

Java代码   收藏代码
  1. public String getEntropy() {  
  2.   
  3.         // Calculate a semi-useful value if this has not been set  
  4.         if (this.entropy == null) {  
  5.             // Use APR to get a crypto secure entropy value  
  6.             byte[] result = new byte[32];  
  7.             boolean apr = false;  
  8.             try {  
  9.                 String methodName = "random";  
  10.                 Class paramTypes[] = new Class[2];  
  11.                 paramTypes[0] = result.getClass();  
  12.                 paramTypes[1] = int.class;  
  13.                 Object paramValues[] = new Object[2];  
  14.                 paramValues[0] = result;  
  15.                 paramValues[1] = new Integer(32);  
  16.                 Method method = Class.forName("org.apache.tomcat.jni.OS")  
  17.                     .getMethod(methodName, paramTypes);  
  18.                 method.invoke(null, paramValues);  
  19.                 apr = true;  
  20.             } catch (Throwable t) {  
  21.                 // Ignore  
  22.             }  
  23.             if (apr) {  
  24.                 try {  
  25.                     setEntropy(new String(result, "ISO-8859-1"));  
  26.                 } catch (UnsupportedEncodingException ux) {  
  27.                     // ISO-8859-1 should always be supported  
  28.                     throw new Error(ux);  
  29.                 }  
  30.             } else {  
  31.                 setEntropy(this.toString());  
  32.             }  
  33.         }  
  34.   
  35.         return (this.entropy);  
  36.   
  37.     }  

 

 

sessionID的生成方法

 

Java代码   收藏代码
  1. protected synchronized String generateSessionId() {  
  2.   
  3.         byte random[] = new byte[16];  
  4.         String jvmRoute = getJvmRoute();  
  5.         String result = null;  
  6.   
  7.         // Render the result as a String of hexadecimal digits  
  8.         StringBuffer buffer = new StringBuffer();  
  9.         do {  
  10.             int resultLenBytes = 0;  
  11.             if (result != null) {  
  12.                 buffer = new StringBuffer();  
  13.                 duplicates++;  
  14.             }  
  15.   
  16.             while (resultLenBytes < this.sessionIdLength) {  
  17. //生成随机数组  
  18.                 getRandomBytes(random);  
  19. //对数组进行加密,默认MD5  
  20.                 random = getDigest().digest(random);  
  21.                 for (int j = 0;  
  22.                 j < random.length && resultLenBytes < this.sessionIdLength;  
  23.                 j++) {  
  24. //涉及到数学,不是很懂为啥??  
  25.                     byte b1 = (byte) ((random[j] & 0xf0) >> 4);  
  26.                     byte b2 = (byte) (random[j] & 0x0f);  
  27.                     if (b1 < 10)  
  28.                         buffer.append((char) ('0' + b1));  
  29.                     else  
  30.                         buffer.append((char) ('A' + (b1 - 10)));  
  31.                     if (b2 < 10)  
  32.                         buffer.append((char) ('0' + b2));  
  33.                     else  
  34.                         buffer.append((char) ('A' + (b2 - 10)));  
  35.                     resultLenBytes++;  
  36.                 }  
  37.             }  
  38.             if (jvmRoute != null) {  
  39. //其中jvmRoute是为了防止tomcat集群导致的sessionId冲突  
  40.                 buffer.append('.').append(jvmRoute);  
  41.             }  
  42.             result = buffer.toString();  
  43.         } while (sessions.containsKey(result));  
  44.         return (result);  

 

 

StandardManager 生命周期:

start()

 

Java代码   收藏代码
  1. if( ! initialized )  
  2. //managerbase.init  
  3.             init();  
  4.   
  5.         // Validate and update our current component state  
  6.         if (started) {  
  7.             return;  
  8.         }  
  9.         lifecycle.fireLifecycleEvent(START_EVENT, null);  
  10.         started = true;  
  11.   
  12.         // Force initialization of the random number generator  
  13.         if (log.isDebugEnabled())  
  14.             log.debug("Force random number initialization starting");  
  15.         String dummy = generateSessionId();  
  16.         if (log.isDebugEnabled())  
  17.             log.debug("Force random number initialization completed");  
  18.   
  19.         // Load unloaded sessions, if any  
  20.         try {  
  21.             load();  
  22.         } catch (Throwable t) {  
  23.             log.error(sm.getString("standardManager.managerLoad"), t);  
  24.         }  

 load

 

 

Java代码   收藏代码
  1. if (SecurityUtil.isPackageProtectionEnabled()){  
  2.            try{  
  3.                AccessController.doPrivileged( new PrivilegedDoLoad() );  
  4.            } catch (PrivilegedActionException ex){  
  5.                Exception exception = ex.getException();  
  6.                if (exception instanceof ClassNotFoundException){  
  7.                    throw (ClassNotFoundException)exception;  
  8.                } else if (exception instanceof IOException){  
  9.                    throw (IOException)exception;  
  10.                }  
  11.                if (log.isDebugEnabled())  
  12.                    log.debug("Unreported exception in load() "  
  13.                        + exception);  
  14.            }  
  15.        } else {  
  16.            doLoad();  
  17.        }  

 doload方法

 

 

Java代码   收藏代码
  1. if (log.isDebugEnabled())  
  2.             log.debug("Start: Loading persisted sessions");  
  3.   
  4.         // Initialize our internal data structures  
  5.         sessions.clear();  
  6.   
  7.         // Open an input stream to the specified pathname, if any  
  8. //根据pathname得到 session文件  
  9.         File file = file();  
  10.         if (file == null)  
  11.             return;  
  12.         if (log.isDebugEnabled())  
  13.             log.debug(sm.getString("standardManager.loading", pathname));  
  14.         FileInputStream fis = null;  
  15.         ObjectInputStream ois = null;  
  16.         Loader loader = null;  
  17.         ClassLoader classLoader = null;  
  18.         try {  
  19.             fis = new FileInputStream(file.getAbsolutePath());  
  20.             BufferedInputStream bis = new BufferedInputStream(fis);  
  21.             if (container != null)  
  22.                 loader = container.getLoader();  
  23.             if (loader != null)  
  24.                 classLoader = loader.getClassLoader();  
  25.             if (classLoader != null) {  
  26.                 if (log.isDebugEnabled())  
  27.                     log.debug("Creating custom object input stream for class loader ");  
  28.                 ois = new CustomObjectInputStream(bis, classLoader);  
  29.             } else {  
  30.                 if (log.isDebugEnabled())  
  31.                     log.debug("Creating standard object input stream");  
  32.                 ois = new ObjectInputStream(bis);  
  33.             }  
  34.         } catch (FileNotFoundException e) {  
  35.             if (log.isDebugEnabled())  
  36.                 log.debug("No persisted data file found");  
  37.             return;  
  38.         } catch (IOException e) {  
  39.             log.error(sm.getString("standardManager.loading.ioe", e), e);  
  40.             if (ois != null) {  
  41.                 try {  
  42.                     ois.close();  
  43.                 } catch (IOException f) {  
  44.                     ;  
  45.                 }  
  46.                 ois = null;  
  47.             }  
  48.             throw e;  
  49.         }  
  50.   
  51.         // Load the previously unloaded active sessions  
  52.         synchronized (sessions) {  
  53.             try {  
  54.                 Integer count = (Integer) ois.readObject();  
  55.                 int n = count.intValue();  
  56.                 if (log.isDebugEnabled())  
  57.                     log.debug("Loading " + n + " persisted sessions");  
  58.                 for (int i = 0; i < n; i++) {  
  59. //初始化session  
  60.                     StandardSession session = getNewSession();  
  61.                     session.readObjectData(ois);  
  62.                     session.setManager(this);  
  63.                     sessions.put(session.getIdInternal(), session);  
  64.                     session.activate();  
  65.                     if (!session.isValidInternal()) {  
  66.                         // If session is already invalid,  
  67.                         // expire session to prevent memory leak.  
  68.                         session.setValid(true);  
  69.                         session.expire();  
  70.                     }  
  71.                     sessionCounter++;  
  72.                 }  
  73.             } catch (ClassNotFoundException e) {  
  74.                 log.error(sm.getString("standardManager.loading.cnfe", e), e);  
  75.                 if (ois != null) {  
  76.                     try {  
  77.                         ois.close();  
  78.                     } catch (IOException f) {  
  79.                         ;  
  80.                     }  
  81.                     ois = null;  
  82.                 }  
  83.                 throw e;  
  84.             } catch (IOException e) {  
  85.                 log.error(sm.getString("standardManager.loading.ioe", e), e);  
  86.                 if (ois != null) {  
  87.                     try {  
  88.                         ois.close();  
  89.                     } catch (IOException f) {  
  90.                         ;  
  91.                     }  
  92.                     ois = null;  
  93.                 }  
  94.                 throw e;  
  95.             } finally {  
  96.                 // Close the input stream  
  97.                 try {  
  98.                     if (ois != null)  
  99.                         ois.close();  
  100.                 } catch (IOException f) {  
  101.                     // ignored  
  102.                 }  
  103.   
  104.                 // Delete the persistent storage file  
  105.                 if (file != null && file.exists() )  
  106.                     file.delete();  
  107.             }  
  108.         }  
  109.   
  110.         if (log.isDebugEnabled())  
  111.             log.debug("Finish: Loading persisted sessions");  

 stop 方法 

 

先unload,对session 钝化 发出事件通知,写入文件

然后session过期

最后销毁

 

Java代码   收藏代码
  1. // Write out sessions  
  2.         try {  
  3.             unload();  
  4.         } catch (Throwable t) {  
  5.             log.error(sm.getString("standardManager.managerUnload"), t);  
  6.         }  
  7.   
  8.         // Expire all active sessions  
  9.         Session sessions[] = findSessions();  
  10.         for (int i = 0; i < sessions.length; i++) {  
  11.             Session session = sessions[i];  
  12.             try {  
  13.                 if (session.isValid()) {  
  14.                     session.expire();  
  15.                 }  
  16.             } catch (Throwable t) {  
  17.                 ;  
  18.             } finally {  
  19.                 // Measure against memory leaking if references to the session  
  20.                 // object are kept in a shared field somewhere  
  21.                 session.recycle();  
  22.             }  
  23.         }  
  24.   
  25.         // Require a new random number generator if we are restarted  
  26.         this.random = null;  
  27.   
  28.         if( initialized ) {  
  29.             destroy();  
  30.         }  

 dounload(), 

 

 

Java代码   收藏代码
  1. if (log.isDebugEnabled())  
  2.             log.debug(sm.getString("standardManager.unloading.debug"));  
  3.   
  4.         if (sessions.isEmpty()) {  
  5.             log.debug(sm.getString("standardManager.unloading.nosessions"));  
  6.             return// nothing to do  
  7.         }  
  8.   
  9.         // Open an output stream to the specified pathname, if any  
  10.         File file = file();  
  11.         if (file == null)  
  12.             return;  
  13.         if (log.isDebugEnabled())  
  14.             log.debug(sm.getString("standardManager.unloading", pathname));  
  15.         FileOutputStream fos = null;  
  16.         ObjectOutputStream oos = null;  
  17.         try {  
  18.             fos = new FileOutputStream(file.getAbsolutePath());  
  19.             oos = new ObjectOutputStream(new BufferedOutputStream(fos));  
  20.         } catch (IOException e) {  
  21.             log.error(sm.getString("standardManager.unloading.ioe", e), e);  
  22.             if (oos != null) {  
  23.                 try {  
  24.                     oos.close();  
  25.                 } catch (IOException f) {  
  26.                     ;  
  27.                 }  
  28.                 oos = null;  
  29.             }  
  30.             throw e;  
  31.         }  
  32.   
  33.         // Write the number of active sessions, followed by the details  
  34.         ArrayList list = new ArrayList();  
  35.         synchronized (sessions) {  
  36.             if (log.isDebugEnabled())  
  37.                 log.debug("Unloading " + sessions.size() + " sessions");  
  38.             try {  
  39.                 oos.writeObject(new Integer(sessions.size()));  
  40.                 Iterator elements = sessions.values().iterator();  
  41.                 while (elements.hasNext()) {  
  42.                     StandardSession session =  
  43.                         (StandardSession) elements.next();  
  44.                     list.add(session);  
  45.                     ((StandardSession) session).passivate();  
  46.                     session.writeObjectData(oos);  
  47.                 }  
  48.             } catch (IOException e) {  
  49.                 log.error(sm.getString("standardManager.unloading.ioe", e), e);  
  50.                 if (oos != null) {  
  51.                     try {  
  52.                         oos.close();  
  53.                     } catch (IOException f) {  
  54.                         ;  
  55.                     }  
  56.                     oos = null;  
  57.                 }  
  58.                 throw e;  
  59.             }  
  60.         }  
  61.   
  62.         // Flush and close the output stream  
  63.         try {  
  64.             oos.flush();  
  65.             oos.close();  
  66.             oos = null;  
  67.         } catch (IOException e) {  
  68.             if (oos != null) {  
  69.                 try {  
  70.                     oos.close();  
  71.                 } catch (IOException f) {  
  72.                     ;  
  73.                 }  
  74.                 oos = null;  
  75.             }  
  76.             throw e;  
  77.         }  
  78.   
  79.         // Expire all the sessions we just wrote  
  80.         if (log.isDebugEnabled())  
  81.             log.debug("Expiring " + list.size() + " persisted sessions");  
  82.         Iterator expires = list.iterator();  
  83.         while (expires.hasNext()) {  
  84.             StandardSession session = (StandardSession) expires.next();  
  85.             try {  
  86.                 session.expire(false);  
  87.             } catch (Throwable t) {  
  88.                 ;  
  89.             } finally {  
  90.                 session.recycle();  
  91.             }  
  92.         }  
  93.   
  94.         if (log.isDebugEnabled())  
  95.             log.debug("Unloading complete");  

 destory()

 

 

Java代码   收藏代码
  1. if( oname != null )  
  2.             Registry.getRegistry(nullnull).unregisterComponent(oname);  
  3.         if (randomIS!=null) {  
  4.             try {  
  5.                 randomIS.close();  
  6.             } catch (IOException ioe) {  
  7.                 log.warn("Failed to close randomIS.");  
  8.             }  
  9.             randomIS=null;  
  10.         }  
  11.   
  12.         initialized=false;  
  13.         oname = null;  

 

 

 

ClusterManger 接口方法



 包含一些集群获取,消息通知,处理等方法

DeltaManager 继承了 ClusterManagerBase 方法,是集群的session管理器

创建session

 

Java代码   收藏代码
  1. public Session createSession(String sessionId, boolean distribute) {  
  2.         if ((maxActiveSessions >= 0) && (sessions.size() >= maxActiveSessions)) {  
  3.             rejectedSessions++;  
  4.             throw new TooManyActiveSessionsException(  
  5.                     sm.getString("deltaManager.createSession.ise"),  
  6.                     maxActiveSessions);  
  7.         }  
  8.         DeltaSession session = (DeltaSession) super.createSession(sessionId) ;  
  9.         if (distribute) {  
  10.             sendCreateSession(session.getId(), session);  
  11.         }  
  12.         if (log.isDebugEnabled())  
  13.             log.debug(sm.getString("deltaManager.createSession.newSession",session.getId(), new Integer(sessions.size())));  
  14.         return (session);  
  15.   
  16.     }  

 发送消息

 

 

Java代码   收藏代码
  1. protected void sendCreateSession(String sessionId, DeltaSession session) {  
  2.         if(cluster.getMembers().length > 0 ) {  
  3.             SessionMessage msg =   
  4.                 new SessionMessageImpl(getName(),  
  5.                                        SessionMessage.EVT_SESSION_CREATED,   
  6.                                        null,   
  7.                                        sessionId,  
  8.                                        sessionId + "-" + System.currentTimeMillis());  
  9.             if (log.isDebugEnabled()) log.debug(sm.getString("deltaManager.sendMessage.newSession",name, sessionId));  
  10.             msg.setTimestamp(session.getCreationTime());  
  11.             counterSend_EVT_SESSION_CREATED++;  
  12.             send(msg);  
  13.         }  
  14.     }  

 

Java代码   收藏代码
  1. protected void send(SessionMessage msg) {  
  2.         if(cluster != null) {  
  3.             if(doDomainReplication())  
  4.                 cluster.sendClusterDomain(msg);  
  5.             else  
  6.                 cluster.send(msg);  
  7.         }  
  8.     }  

 sessionID 序列化操作

 

 

Java代码   收藏代码
  1. protected byte[] serializeSessionId(String sessionId) throws IOException {  
  2.         ByteArrayOutputStream bos = new ByteArrayOutputStream();  
  3.         ObjectOutputStream oos = new ObjectOutputStream(bos);  
  4.         oos.writeUTF(sessionId);  
  5.         oos.flush();  
  6.         oos.close();  
  7.         return bos.toByteArray();  
  8.     }  
  9.   
  10.     /** 
  11.      * Load sessionID 
  12.      * @throws IOException if an input/output error occurs 
  13.      */  
  14.     protected String deserializeSessionId(byte[] data) throws IOException {  
  15.         ReplicationStream ois = getReplicationStream(data);  
  16.         String sessionId = ois.readUTF();  
  17.         ois.close();  
  18.         return sessionId;  
  19.     }  

 变更sessionID

 

 

Java代码   收藏代码
  1. public void changeSessionId(Session session, boolean notify) {  
  2.         // original sessionID  
  3.         String orgSessionID = session.getId();  
  4.         super.changeSessionId(session);  
Java代码   收藏代码
  1. public void changeSessionId(Session session) {  
  2.         String oldId = session.getIdInternal();  
  3.         session.setId(generateSessionId(), false);  
  4.         String newId = session.getIdInternal();  
  5.         if (container instanceof ContainerBase) {  
  6.             ((ContainerBase)container).fireContainerEvent(  
  7.                     Context.CHANGE_SESSION_ID_EVENT,  
  8.                     new String[] {oldId, newId});  
  9.         }  
  10.     }  
Java代码   收藏代码
  1.   if (notify) { // changed sessionID String newSessionID = session.getId(); try { // serialize sessionID byte[] data = serializeSessionId(newSessionID); // notify change sessionID SessionMessage msg = new SessionMessageImpl(getName(), SessionMessage.EVT_CHANGE_SESSION_ID, data, orgSessionID, orgSessionID + "-" + System.currentTimeMillis()); msg.setTimestamp(System.currentTimeMillis()); counterSend_EVT_CHANGE_SESSION_ID++; send(msg); } catch (IOException e) { log.error(sm.getString("deltaManager.unableSerializeSessionID", newSessionID), e); } } }  

 start方法

 

 

Java代码   收藏代码
  1. if (!initialized) init();  
  2.   
  3.         // Validate and update our current component state  
  4.         if (started) {  
  5.             return;  
  6.         }  
  7.         started = true;  
  8.         lifecycle.fireLifecycleEvent(START_EVENT, null);  
  9.   
  10.         // Force initialization of the random number generator  
  11.         generateSessionId();  
  12.   
  13.         // Load unloaded sessions, if any  
  14.         try {  
  15.             //the channel is already running  
  16.             Cluster cluster = getCluster() ;  
  17.             // stop remove cluster binding  
  18.             //wow, how many nested levels of if statements can we have ;)  
  19.             if(cluster == null) {  
  20.                 Container context = getContainer() ;  
  21.                 if(context != null && context instanceof Context) {  
  22. //集群环境下 必须有Host 或者 Engine 容器  
  23.                      Container host = context.getParent() ;  
  24.                      if(host != null && host instanceof Host) {  
  25.                          cluster = host.getCluster();  
  26.                          if(cluster != null && cluster instanceof CatalinaCluster) {  
  27.                              setCluster((CatalinaCluster) cluster) ;  
  28.                          } else {  
  29.                              Container engine = host.getParent() ;  
  30.                              if(engine != null && engine instanceof Engine) {  
  31.                                  cluster = engine.getCluster();  
  32.                                  if(cluster != null && cluster instanceof CatalinaCluster) {  
  33.                                      setCluster((CatalinaCluster) cluster) ;  
  34.                                  }  
  35.                              } else {  
  36.                                      cluster = null ;  
  37.                              }  
  38.                          }  
  39.                      }  
  40.                 }  
  41.             }  
  42.             if (cluster == null) {  
  43.                 log.error(sm.getString("deltaManager.noCluster", getName()));  
  44.                 return;  
  45.             } else {  
  46.                 if (log.isInfoEnabled()) {  
  47.                     String type = "unknown" ;  
  48.                     if( cluster.getContainer() instanceof Host){  
  49.                         type = "Host" ;  
  50.                     } else if( cluster.getContainer() instanceof Engine){  
  51.                         type = "Engine" ;  
  52.                     }  
  53.                     log.info(sm.getString("deltaManager.registerCluster", getName(), type, cluster.getClusterName()));  
  54.                 }  
  55.             }  
  56.             if (log.isInfoEnabled()) log.info(sm.getString("deltaManager.startClustering", getName()));  
  57.             //to survice context reloads, as only a stop/start is called, not  
  58.             // createManager  
  59. //在cluster中注册此session管理器  
  60.             cluster.registerManager(this);  
  61. //得到其他context的session  
  62.             getAllClusterSessions();  
  63.   
  64.         } catch (Throwable t) {  
  65.             log.error(sm.getString("deltaManager.managerLoad"), t);  
  66.         }  

 getAllClusterSessions

 

 

Java代码   收藏代码
  1. if (cluster != null && cluster.getMembers().length > 0) {  
  2.             long beforeSendTime = System.currentTimeMillis();  
  3.             Member mbr = findSessionMasterMember();  
  4.             if(mbr == null) { // No domain member found  
  5.                  return;  
  6.             }  
  7.             SessionMessage msg = new SessionMessageImpl(this.getName(),SessionMessage.EVT_GET_ALL_SESSIONS, null"GET-ALL","GET-ALL-" + getName());  
  8.             // set reference time  
  9.             stateTransferCreateSendTime = beforeSendTime ;  
  10.             // request session state  
  11.             counterSend_EVT_GET_ALL_SESSIONS++;  
  12.             stateTransfered = false ;  
  13.             // FIXME This send call block the deploy thread, when sender waitForAck is enabled  
  14.             try {  
  15.                 synchronized(receivedMessageQueue) {  
  16.                      receiverQueue = true ;  
  17.                 }  
  18.                 cluster.send(msg, mbr);  
  19.                 if (log.isWarnEnabled()) log.warn(sm.getString("deltaManager.waitForSessionState",getName(), mbr,getStateTransferTimeout()));  
  20.                 // FIXME At sender ack mode this method check only the state transfer and resend is a problem!  
  21.                 waitForSendAllSessions(beforeSendTime);  
  22.             } finally {  
  23.                 synchronized(receivedMessageQueue) {  
  24.                     for (Iterator iter = receivedMessageQueue.iterator(); iter.hasNext();) {  
  25.                         SessionMessage smsg = (SessionMessage) iter.next();  
  26.                         if (!stateTimestampDrop) {  
  27.                             messageReceived(smsg, smsg.getAddress() != null ? (Member) smsg.getAddress() : null);  
  28.                         } else {  
  29.                             if (smsg.getEventType() != SessionMessage.EVT_GET_ALL_SESSIONS && smsg.getTimestamp() >= stateTransferCreateSendTime) {  
  30.                                 // FIXME handle EVT_GET_ALL_SESSIONS later  
  31.                                 messageReceived(smsg,smsg.getAddress() != null ? (Member) smsg.getAddress() : null);  
  32.                             } else {  
  33.                                 if (log.isWarnEnabled()) {  
  34.                                     log.warn(sm.getString("deltaManager.dropMessage",getName(), smsg.getEventTypeString(),new Date(stateTransferCreateSendTime), new Date(smsg.getTimestamp())));  
  35.                                 }  
  36.                             }  
  37.                         }  
  38.                     }          
  39.                     receivedMessageQueue.clear();  
  40.                     receiverQueue = false ;  
  41.                 }  
  42.            }  
  43.         } else {  
  44.             if (log.isInfoEnabled()) log.info(sm.getString("deltaManager.noMembers", getName()));  
  45.         }  

 

 

整个集群环境下的session管理,可以总结为,集群环境下的context都使用DeltaManager作为管理器,管理DeltaSession, 同时不同cluster之间使用 DeltaRequest 封装 SessionMessage来传递消息

然后ClusterSessionListener 通过在 ChannelListener中的messageReceived 事件来 触发DeltaManager中的messageReceived事件

具体见图:

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值