ZK session用戶端到期(Expired)過程

來源:互聯網
上載者:User

一般情況下,zk用戶端與服務端建立串連後,會在2/3*sessionTime*1/2的時候發送一個心跳訊息到服務端,保持會話更新。但是可能在某個時候網路中斷可能導致用戶端無法串連上服務端,此時用戶端會不停的依次重試各個伺服器,一直到串連上某個伺服器為止。如果在未串連上這段時間內,服務端session已經到期,(參見SessionTracker的實現SessionTrackerImpl),它是依靠一個線程對到期的session進行清理,並關閉掉串連。

synchronized public void run() {       try {           while (running) {                currentTime =System.currentTimeMillis();                if (nextExpirationTime >currentTime) {                   this.wait(nextExpirationTime - currentTime);                    continue;                }                SessionSet set;                set =sessionSets.remove(nextExpirationTime);                if (set != null) {                    for (SessionImpl s :set.sessions) {                       sessionsById.remove(s.sessionId);                        expirer.expire(s);                    }                }                nextExpirationTime +=expirationInterval;           }       } catch (InterruptedException e) {           LOG.error("Unexpected interruption", e);       }       LOG.info("SessionTrackerImpl exited loop!");}

用戶端在session到期後這段時間後,串連上某個伺服器,並發送ConnectRequest,附帶串連中斷前的sessionid,以及lastZxid 等等訊息,請求重新與伺服器建立串連。伺服器發現是一個ConnectRequest請求,於是readConnectRequest,如果sessionid不為0,則表示是需要恢複原來這個串連。

if (connReq.getSessionId() != 0) {           long clientSessionId = connReq.getSessionId();           LOG.info("Client attempting to renew session 0x"                    +Long.toHexString(clientSessionId)                    + " at " +sock.socket().getRemoteSocketAddress());           factory.closeSessionWithoutWakeup(clientSessionId);           setSessionId(clientSessionId);           zk.reopenSession(this, sessionId, passwd, sessionTimeout);       } else {           LOG.info("Client attempting to establish new session at "                    +sock.socket().getRemoteSocketAddress());           zk.createSession(this, passwd, sessionTimeout);       }

reopenSession恢複時,會對session做一些校正

public void reopenSession(ServerCnxn cnxn, long sessionId, byte[]passwd,           int sessionTimeout) throws IOException, InterruptedException {       if (!checkPasswd(sessionId, passwd)) {           cnxn.finishSessionInit(false);       } else {          revalidateSession(cnxn, sessionId, sessionTimeout);       }}    protected void revalidateSession(ServerCnxncnxn, long sessionId,            int sessionTimeout) throwsIOException, InterruptedException {        boolean rc =sessionTracker.touchSession(sessionId, sessionTimeout);        if (LOG.isTraceEnabled()) {           ZooTrace.logTraceMessage(LOG,ZooTrace.SESSION_TRACE_MASK,                                    "Session 0x" + Long.toHexString(sessionId) +                    " is valid: " +rc);        }        cnxn.finishSessionInit(rc);    }

由於sessionid已經到期被刪除,所以touchSession時由於找不到sessionid,這裡rc會返回false, 根據rc的值,finishSessionInit會確定發送什麼樣的ConnectResponse給用戶端。

public voidfinishSessionInit(boolean valid)ConnectResponsersp = new ConnectResponse(0, valid ? sessionTimeout                    : 0, valid ? sessionId : 0,// send 0 if session is no                    // longer valid                    valid ?zk.generatePasswd(sessionId) : new byte[16]);

如果rc=false,同時服務端會發送關閉串連的指令。

用戶端收到響應後,發現sessionTimeout時間小於或者等於0,則表示session到期。觸發expired事件,並拋出異常。

negotiatedSessionTimeout =conRsp.getTimeOut();            if (negotiatedSessionTimeout <=0) {               zooKeeper.state =States.CLOSED;              eventThread.queueEvent(newWatchedEvent(                       Watcher.Event.EventType.None,                       Watcher.Event.KeeperState.Expired, null));               eventThread.queueEventOfDeath();                throw newSessionExpiredException(                        "Unable toreconnect to ZooKeeper service, session 0x"                        +Long.toHexString(sessionId) + " has expired");            }

整個用戶端執行個體退出,這個執行個體不能再次重用了,如果還需要串連伺服器,則需要重新建立新的zookeeper執行個體。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.