国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

tomcat session管理

2019-11-08 02:10:33
字體:
來源:轉載
供稿:網友

最近有空看了一下tomcat 6源碼里面對session管理的實現,現在寫下來,以供后考,也希望能對對此感興趣的朋友

有所提示。

 

閑話少說,先貼一下tomcat6的component層次圖(此圖來自tomcat doc)

  Server                                         就是一個servlet container           |         Service                                 包含一個或多個connector的組                    |         Engine                                  servlet engine.最頂級的container.            |  /            |  --- Cluster --*           |         Host                                      第二級container           |         ------        /      /     Cluster    Context(1-N)             第三級container. servlet context. 也就是一個應用。        |             /        |             -- Manager               應用的session管理器        |                   /        |                   -- DeltaManager        |                   -- BackupManager        |     ---------------------------        |                       /      Channel                    /    ----------------------------- /        |                          /     Interceptor_1 ..               /        |                            /     Interceptor_N                    /    -----------------------------      /     |          |         |             /   Receiver    Sender   Membership       /                                         -- Valve                                         |      /                                         |       -- ReplicationValve                                         |       -- JvmRouteBinderValve                                          |                                         -- LifecycleListener                                          |                                         -- ClusterListener                                          |      /                                         |       -- ClusterSessionListener                                         |       -- JvmRouteSessionIDBinderListener                                         |                                         -- Deployer                                                 /                                                 -- FarmWarDeployer     

OK,基本層級關系說過了,就開始分析session的管理。

1. session 的創建。

   更正:下面這段我理解錯了。其實進一步看下來,發現其實session的創建是在每個context里面。具體的創建可以看我

   這篇之后的那篇文章. Session的生成實際是在調用最終處理的servlet的時候生成的。

    session的創建的入口是在Host里面,每次request進來之后,會沿著container 的pipeline一直往下進行、

    處理,順序是:engine->host->context->wrapper. 而pipeline的作用就是調用對應級別的value對

   request和response進行處理。在StandardHostValue里面首先出現對session的調用:

 

java代碼  收藏代碼public final void invoke(Request request, Response response)          throws IOException, ServletException {            // Select the Context to be used for this Request          Context context = request.getContext();          if (context == null) {              response.sendError                  (HttpServletResponse.SC_INTERNAL_SERVER_ERROR,                   sm.getString("standardHost.noContext"));              return;          }            // Bind the context CL to the current thread          if( context.getLoader() != null ) {              // Not started - it should check for availability first              // This should eventually move to Engine, it's generic.              Thread.currentThread().setContextClassLoader                      (context.getLoader().getClassLoader());          }            // Ask this Context to PRocess this request          context.getPipeline().getFirst().invoke(request, response);            // access a session (if present) to update last accessed time, based on a          // strict interpretation of the specification          if (Globals.STRICT_SERVLET_COMPLIANCE) {              request.getSession(false);          }            // Error page processing          response.setSuspended(false);            Throwable t = (Throwable) request.getAttribute(Globals.EXCEPTION_ATTR);            if (t != null) {              throwable(request, response, t);          } else {              status(request, response);          }            // Restore the context classloader          Thread.currentThread().setContextClassLoader              (StandardHostValve.class.getClassLoader());        }  

 

    注意里面的:request.getSession(false) 這一句。這一句最終會調用如下代碼;

  

Java代碼  收藏代碼protected Session doGetSession(boolean create) {           // There cannot be a session if no context has been assigned yet         if (context == null)             return (null);           // Return the current session if it exists and is valid         if ((session != null) && !session.isValid())             session = null;         if (session != null)             return (session);           // Return the requested session if it exists and is valid         Manager manager = null;         if (context != null)             manager = context.getManager();         if (manager == null)             return (null);      // Sessions are not supported         if (requestedSessionId != null) {             try {                 session = manager.findSession(requestedSessionId);             } catch (IOException e) {                 session = null;             }             if ((session != null) && !session.isValid())                 session = null;             if (session != null) {                 session.access();                 return (session);             }         }           // Create a new session if requested and the response is not committed         if (!create)             return (null);         if ((context != null) && (response != null) &&             context.getCookies() &&             response.getResponse().isCommitted()) {             throw new IllegalStateException               (sm.getString("coyoteRequest.sessionCreateCommitted"));         }           // Attempt to reuse session id if one was submitted in a cookie         // Do not reuse the session id if it is from a URL, to prevent possible         // phishing attacks         if (connector.getEmptySessionPath()                  && isRequestedSessionIdFromCookie()) {             session = manager.createSession(getRequestedSessionId());         } else {             session = manager.createSession(null);         }           // Creating a new session cookie based on that session         if ((session != null) && (getContext() != null)                && getContext().getCookies()) {             Cookie cookie = new Cookie(Globals.SESSION_COOKIE_NAME,                                        session.getIdInternal());             configureSessionCookie(cookie);             response.addCookieInternal(cookie, context.getUseHttpOnly());         }           if (session != null) {             session.access();             return (session);         } else {             return (null);         }       }  

   

  通過以上代碼,container或者返回一個已存在的session,或者新建一個session,或者返回Null(特殊情況).

      而session的創建是由manager完成的。Manager接口的實現根據具體情況有很多種,比如:

      StandardManager:默認的單機環境tomcat session manager.創建standardsession.

      DeltaSessionManager:適用于集群環境。創建DeltaSession

      ....

     不同的Manager管理不同具體類型的session,從而使得tomcat能夠很好的支持集群環境下面的session復制,持久化 等等。比如DeltaSession創建session的時候,會向集群中的其他節點群播一個信息。

   

 

2. session的管理。

    大家都知道tomcat的session需要不斷使超時的session失效,那么這個共是怎么實現的呢?

    在StandardContext啟動的時候哦,會同時啟動一個thread. 這個線程是一個daemon線程,

   會定時調用ManagerBase的一下方法:

  

Java代碼  收藏代碼public void processExpires() {            long timeNow = System.currentTimeMillis();          Session sessions[] = findSessions();          int expireHere = 0 ;                    if(log.isDebugEnabled())              log.debug("Start expire sessions " + getName() + " at " + timeNow + " sessioncount " + sessions.length);          for (int i = 0; i < sessions.length; i++) {              if (sessions[i]!=null && !sessions[i].isValid()) {                  expireHere++;              }          }          long timeEnd = System.currentTimeMillis();          if(log.isDebugEnabled())               log.debug("End expire sessions " + getName() + " processingTime " + (timeEnd - timeNow) + " expired sessions: " + expireHere);          processingTime += ( timeEnd - timeNow );        }  

 

  很顯然,session的有效性管理也通過session具體實現的。比如DeltaSession:

  

Java代碼  收藏代碼public void expire(boolean notify, boolean notifyCluster) {         if (expiring)             return;         String expiredId = getIdInternal();           if(expiredId != null && manager != null &&            manager instanceof DeltaManager) {             DeltaManager dmanager = (DeltaManager)manager;             CatalinaCluster cluster = dmanager.getCluster();             ClusterMessage msg = dmanager.requestCompleted(expiredId, true);             if (msg != null) {                 if(dmanager.doDomainReplication()) {                     cluster.sendClusterDomain(msg);                 } else {                     cluster.send(msg);                 }             }         }           super.expire(notify);           if (notifyCluster) {             if (log.isDebugEnabled())                 log.debug(sm.getString("deltaSession.notifying",                                        ((ClusterManager)manager).getName(),                                         new Boolean(isPrimarySession()),                                         expiredId));             if ( manager instanceof DeltaManager ) {                 ( (DeltaManager) manager).sessionExpired(expiredId);             }         }     }  

 

    可以看出,當session失效的時候,manager會廣播這個消息。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 娱乐| 革吉县| 新乐市| 固镇县| 元江| 洛南县| 离岛区| 霸州市| 赤城县| 西乡县| 肃北| 鄂伦春自治旗| 二连浩特市| 武宣县| 千阳县| 抚顺县| 南京市| 鹤壁市| 原阳县| 缙云县| 固始县| 额尔古纳市| 仙游县| 兴化市| 崇左市| 惠州市| 锡林浩特市| 许昌市| 加查县| 玛沁县| 遵义市| 奇台县| 汉沽区| 吴桥县| 巩义市| 赞皇县| 页游| 台安县| 高平市| 菏泽市| 龙海市|