温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

zk中的会话管理SessionTrackerImpl的方法

发布时间:2021-06-26 10:25:13 来源:亿速云 阅读:278 作者:chen 栏目:大数据

本篇内容主要讲解“zk中的会话管理SessionTrackerImpl的方法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“zk中的会话管理SessionTrackerImpl的方法”吧!

SessionTrackerImpl中包含实现SessionImpl继承Session(在SessionTracker中) SessionTracker接口

SessionImpl是session属性集合类

属性

sessionsById

sessionid和会话的对应map

sessionExpiryQueue

会话到期队列

sessionsWithTimeout

sessionid对应过期时间

nextSessionId

下一个sessionid

expirer

让session过期,获取服务id

running

运行中

  

涉及到的类ExpiryQueue

类SessionImpl

类SessionExpirer

会话管理功能主要有:

1 会话过期

2 设置会话超时时间

3 生成下一个会话id

方法

将time->sessions map转成time->sessionIds 映射

getSessionExpiryMap

public synchronized Map<Long, Set<Long>> getSessionExpiryMap() {
    // Convert time -> sessions map to time -> session IDs map
    Map<Long, Set<SessionImpl>> expiryMap = sessionExpiryQueue.getExpiryMap();
    Map<Long, Set<Long>> sessionExpiryMap = new TreeMap<Long, Set<Long>>();
    for (Entry<Long, Set<SessionImpl>> e : expiryMap.entrySet()) {
        Set<Long> ids = new HashSet<Long>();
        sessionExpiryMap.put(e.getKey(), ids);
        for (SessionImpl s : e.getValue()) {
            ids.add(s.sessionId);
        }
    }
    return sessionExpiryMap;
}

run 超时会话检查线程,更新超时时间

public void run() {
    try {
        while (running) {
            //没有超时,需要等待超时时间
            long waitTime = sessionExpiryQueue.getWaitTime();
            //线程等待一段时间
            if (waitTime > 0) {
                Thread.sleep(waitTime);
                continue;
            }
            //已经超时了,拿出会话队列中的会话进行清理
            for (SessionImpl s : sessionExpiryQueue.poll()) {
                ServerMetrics.getMetrics().STALE_SESSIONS_EXPIRED.add(1);
                //将标记设置为SessionImpl isClosing true
                setSessionClosing(s.sessionId);
                //zookeeperServer让session过期
                expirer.expire(s);
            }
        }
    } catch (InterruptedException e) {
        handleException(this.getName(), e);
    }
    LOG.info("SessionTrackerImpl exited loop!");
}

方法

说明

getSessionTimeout

通过sessionId获取超时时间

setSessionClosing

设置会话关闭

removeSession

通过sessionId移除会话,同时移除会话相关的映射关系图

createSession(int sessionTimeout)

创建session,指定过期时间

trackSession(sessionId, sessionTimeout);

取得sessionId,调用trackSession(sessionId, sessionTimeout);方法进行session创建,更新会话超时时间

 

@Override
public synchronized boolean trackSession(long id, int sessionTimeout) {
    boolean added = false;

    SessionImpl session = sessionsById.get(id);
    //没有就新增一个session对象
    if (session == null) {
        session = new SessionImpl(id, sessionTimeout);
    }

    // findbugs2.0.3 complains about get after put.
    //?为什么
    // long term strategy would be use computeIfAbsent after JDK 1.8
    SessionImpl existedSession = sessionsById.putIfAbsent(id, session);

    if (existedSession != null) {
        session = existedSession;
    } else {
        added = true;
        if (LOG.isDebugEnabled()) {
            LOG.debug("Adding session 0x{}", Long.toHexString(id));
        }
    }

    if (LOG.isTraceEnabled()) {
        String actionStr = added ? "Adding" : "Existing";
        ZooTrace.logTraceMessage(
            LOG,
            ZooTrace.SESSION_TRACE_MASK,
            "SessionTrackerImpl --- " + actionStr
            + " session 0x" + Long.toHexString(id) + " " + sessionTimeout);
    }
    //存在更新超时时间
    updateSessionExpiry(session, sessionTimeout);
    return added;
}

方法

说明

涉及异常

commitSession(long id, int sessionTimeout)

提交session

UnknownSessionException

isTrackingSession(long sessionId)

是否为可以追踪会话,说明会话有效

SessionExpiredException

checkSession(long sessionId, Object owner)

通过会话和拥有者检查会话信息

SessionMovedException

分桶策略

将不同超时时间的会话分配到不同的桶中,做到有效管理,按照时间间隔来分桶

private long roundToNextInterval(long time) {

return (time / expirationInterval + 1) * expirationInterval;

}

会话建立之后,会话如何保持激活状态

问题 会话如何迁移?

zk中的会话管理SessionTrackerImpl的方法

会话激活的方法有
public synchronized boolean touchSession(long sessionId, int timeout) {
    //获取会话
    SessionImpl s = sessionsById.get(sessionId);

    if (s == null) {
        logTraceTouchInvalidSession(sessionId, timeout);
        return false;
    }
    //关闭
    if (s.isClosing()) {
        logTraceTouchClosingSession(sessionId, timeout);
        return false;
    }
    //更新会话 将旧过期时间桶中session移动到新桶
    updateSessionExpiry(s, timeout);
    return true;
}

client 什么时候会发出激活会话请求

1客户端向服务端发送请求,包含读写请求,就会激活会话

2 客户端发现在sessionTimeout/3时间内未收到任何通信,就会向服务器发起ping请求,

服务端收到请求后,就会进行会话激活操作

超时检测策略

对于会话超时检测而言,zookeeper使用SessionTracker负责,sessionTracker使用单独线程(超时检查线程)

专门进行会话超时检测,即逐个一次地对会话桶中剩余会话进行清理。

如果一个会话被激活,那么zookeeper会将其从上一个会话桶迁移到下一个会话桶中,

如ExpirationTIme 1的session n迁移到ExpirationTime n桶中,此时ExpirationTime 1中留下的会话就是没有被激活的

超时检测程序就定时检查这个会话桶中剩余未被迁移的会话,并且只在指定时间点上检查(ExpirationTime 1,ExpirationTime2,

ExpirationTime3,...n)这样有利于提高性能

@Override
public void run() {
    try {
        while (running) {
            long waitTime = sessionExpiryQueue.getWaitTime();
            if (waitTime > 0) {
                Thread.sleep(waitTime);
                continue;
            }

            for (SessionImpl s : sessionExpiryQueue.poll()) {
                ServerMetrics.getMetrics().STALE_SESSIONS_EXPIRED.add(1);
                setSessionClosing(s.sessionId);
                expirer.expire(s);
            }
        }
    } catch (InterruptedException e) {
        handleException(this.getName(), e);
    }
    LOG.info("SessionTrackerImpl exited loop!");
}

到此,相信大家对“zk中的会话管理SessionTrackerImpl的方法”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

zk
AI