NebulaGraph学习笔记-SessionPool之getSession

之前在 NebulaGraph学习笔记-自定义SessionPool 这篇文章中实现了自定义的SessionPool,后续在使用中发现经常查询的都是用的同一个Session,以至于某一个节点的负载压力很大。于是看了一下获取Session的方法,发现是顺序遍历,后续可以调整遍历方式来改变。
  • 依赖包还是跟之前的一致
typescript 复制代码
<!-- Client依赖包 -->
<dependency>
    <groupId>com.vesoft</groupId>
    <artifactId>client</artifactId>
    <version>3.8.4</version>
</dependency>
  • SessionPool会在构造函数中进行初始化
java 复制代码
/**
 * init the SessionPool
 * this function is moved into SessionPool's constructor, no need to call it manually.
 */
@Deprecated
public boolean init() {
    if (hasInit.get()) {
        return true;
    }

    while (sessionList.size() < minSessionSize) {
        try {
            createSessionObject(SessionState.IDLE);
            idleSessionSize.incrementAndGet();
        } catch (Exception e) {
            log.error("SessionPool init failed. ");
            throw new RuntimeException("create session failed.", e);
        }
    }
    healthCheckSchedule.scheduleAtFixedRate(this::checkSession, 0, healthCheckTime,
            TimeUnit.SECONDS);
    sessionQueueMaintainSchedule.scheduleAtFixedRate(this::updateSessionQueue, 0, cleanTime,
            TimeUnit.SECONDS);
    hasInit.compareAndSet(false, true);
    return true;
}


/**
 * create a {@link NebulaSession} with specified state
 *
 * @param state {@link SessionState}
 * @return NebulaSession
 */
private NebulaSession createSessionObject(SessionState state)
        throws ClientServerIncompatibleException, AuthFailedException,
        IOErrorException, BindSpaceFailedException {
    SyncConnection connection = new SyncConnection();
    int tryConnect = sessionPoolConfig.getGraphAddressList().size();
    // reconnect with all available address
    while (tryConnect-- > 0) {
        try {
            if (sessionPoolConfig.isEnableSsl()) {
                connection.open(getAddress(), sessionPoolConfig.getTimeout(),
                        sessionPoolConfig.getSslParam(),
                        sessionPoolConfig.isUseHttp2(),
                        sessionPoolConfig.getCustomHeaders());
            } else {
                connection.open(getAddress(), sessionPoolConfig.getTimeout(),
                        sessionPoolConfig.isUseHttp2(),
                        sessionPoolConfig.getCustomHeaders());
            }
            break;
        } catch (Exception e) {
            if (tryConnect == 0 || !reconnect) {
                throw e;
            } else {
                log.warn("connect failed, " + e.getMessage());
            }
        }
    }

    AuthResult authResult;
    try {
        authResult = connection.authenticate(sessionPoolConfig.getUsername(),
                sessionPoolConfig.getPassword());
    } catch (AuthFailedException e) {
        log.error(e.getMessage());
        if (e.getMessage().toLowerCase().contains("user not exist")
                || e.getMessage().toLowerCase().contains("invalid password")) {
            // close the session pool
            close();
        } else {
            // just close the connection
            connection.close();
        }
        throw e;
    }

    NebulaSession nebulaSession = new NebulaSession(connection, authResult.getSessionId(),
            authResult.getTimezoneOffset(), state);
    ResultSet result = null;
    try {
        result = nebulaSession.execute(useSpace);
    } catch (IOErrorException e) {
        log.error("binding space failed,", e);
        nebulaSession.release();
        throw new BindSpaceFailedException("binding space failed:" + e.getMessage());
    }
    if (!result.isSucceeded()) {
        nebulaSession.release();
        throw new BindSpaceFailedException(result.getErrorMessage());
    }
    sessionList.add(nebulaSession);
    return nebulaSession;
}


public HostAddress getAddress() {
    List<HostAddress> addresses = sessionPoolConfig.getGraphAddressList();
    int newPos = (pos.getAndIncrement()) % addresses.size();
    HostAddress hostAddress = addresses.get(newPos);
    log.info("ng address {} {} {} {}", pos.get(), newPos, hostAddress.getHost(), hostAddress.getPort());
    return hostAddress;
}
  • getSession用于为每次执行查询提供Session,可以看出每次都是从sessionList中顺序取出nebulaSession
java 复制代码
/**
 * return an idle session
 */
private synchronized NebulaSession getSession() throws ClientServerIncompatibleException,
        AuthFailedException, IOErrorException, BindSpaceFailedException {
    int retry = sessionPoolConfig.getRetryConnectTimes();
    while (retry-- >= 0) {
        // if there are idle sessions, get session from queue
        if (idleSessionSize.get() > 0) {
             for (NebulaSession nebulaSession : sessionList) {
                 if (nebulaSession.isIdleAndSetUsed()) {
                     int currentIdleSessionSize = idleSessionSize.decrementAndGet();
                     log.info("ng session {} {}", currentIdleSessionSize, nebulaSession.getSessionID());
                     return nebulaSession;
                 }
             }
        }
        // if session size is less than max size, get session from pool
        if (sessionList.size() < maxSessionSize) {
            return createSessionObject(SessionState.USED);
        }
        // there's no available session, wait for SessionPoolConfig.getWaitTime and re-get
        try {
            Thread.sleep(sessionPoolConfig.getWaitTime());
        } catch (InterruptedException e) {
            log.error("getSession error when wait for idle sessions, ", e);
            throw new RuntimeException(e);
        }
    }

    // if session size is equal to max size and no idle session here, throw exception
    throw new RuntimeException("no extra session available");
}
  • 可以调整从sessionList中随机取出nebulaSession
java 复制代码
/**
 * return an idle session
 */
private synchronized NebulaSession getSession() throws ClientServerIncompatibleException,
        AuthFailedException, IOErrorException, BindSpaceFailedException {
    int retry = sessionPoolConfig.getRetryConnectTimes();
    while (retry-- >= 0) {
        // if there are idle sessions, get session from queue
        if (idleSessionSize.get() > 0) {
            int[] randomInts = RandomUtil.randomInts(sessionList.size());
            for (int randomInt : randomInts) {
                NebulaSession nebulaSession = sessionList.get(randomInt);
                if (nebulaSession.isIdleAndSetUsed()) {
                    int currentIdleSessionSize = idleSessionSize.decrementAndGet();
                    log.debug("ng session {} {}", currentIdleSessionSize, nebulaSession.getSessionID());
                    return nebulaSession;
                }
            }
        }
        // if session size is less than max size, get session from pool
        if (sessionList.size() < maxSessionSize) {
            return createSessionObject(SessionState.USED);
        }
        // there's no available session, wait for SessionPoolConfig.getWaitTime and re-get
        try {
            Thread.sleep(sessionPoolConfig.getWaitTime());
        } catch (InterruptedException e) {
            log.error("getSession error when wait for idle sessions, ", e);
            throw new RuntimeException(e);
        }
    }

    // if session size is equal to max size and no idle session here, throw exception
    throw new RuntimeException("no extra session available");
}
相关推荐
EXI-小洲3 小时前
Java 操作 Word:字符串替换、图片插入、动态生成表格与API接口下载
java·开发语言·spring boot·word
2601_961901704 小时前
SpringBoot使用Nacos进行application.yml配置管理
java·spring boot·spring
何以解忧,唯有..5 小时前
LangChain 工具调用(Tool Calling)实战指南
java·前端·langchain
QQ_21696290966 小时前
【源码编号:project79475】SpringBoot校内二手交易平台:商品发布、分类检索、留言交流、订单管理全流程实战
java·spring boot·后端
前端 贾公子7 小时前
第09章:上下文与记忆 (2)
java·服务器·前端
2601_962203517 小时前
Java进阶07集合(续)
java·开发语言
郑州光合科技余经理7 小时前
本地生活服务系统:模块边界与结算字段怎么拆
java·开发语言·前端·后端·系统架构·uni-app·php
roman_日积跬步-终至千里7 小时前
【数据治理(6)】DataOps 不是调度工具,而是让数据产品长期可信的运行机制
java·服务器·网络
落魄大学生之流水线上谋生计8 小时前
LangGraph 基本用法指南
java·windows·python·langchain
2601_962128418 小时前
SpringBoot篇(缓存层)
java·spring boot·缓存