服务器运行多天后提示session不存在

session获取已经是从推荐的连接池中拿到的了,但是还是会提示session不存在,我不理解,为什么失效后没有获取一个新的session?

我的配置如下
初始化连接池

/**
 * @ClassName: SessionPool
 */
@Slf4j
public class SessionPool {

    /**
     * 创建连接池
     *
     * @param maxCountSession 默认创建连接数
     * @param minCountSession 最大创建连接数
     * @param hostAndPort     机器端口列表
     * @param userName        用户名
     * @param passWord        密码
     * @throws UnknownHostException
     * @throws NotValidConnectionException
     * @throws IOErrorException
     * @throws AuthFailedException
     */
    public SessionPool(int maxCountSession, int minCountSession, String hostAndPort, String userName, String passWord) throws UnknownHostException, NotValidConnectionException, IOErrorException, AuthFailedException, ClientServerIncompatibleException {
        this.minCountSession = minCountSession;
        this.maxCountSession = maxCountSession;
        this.userName = userName;
        this.passWord = passWord;
        this.queue = new LinkedBlockingQueue<>(minCountSession);
        this.pool = this.initGraphClient(hostAndPort, maxCountSession, minCountSession);
        initSession();
    }

    public Session borrow() {
        Session se = queue.poll();
        if (se != null) {
            return se;
        }
        try {
            return this.pool.getSession(userName, passWord, true);
        } catch (Exception e) {
            log.error("execute borrow session fail, detail: ", e);
            throw new RuntimeException(e);
        }
    }

    @PreDestroy
    public void release() {
        Queue<Session> queue = this.queue;
        for (Session se : queue) {
            if (se != null) {
                boolean success = this.queue.offer(se);
                if (!success) {
                    se.release();
                }
            }
        }
    }

    public void close() {
        this.pool.close();
    }

    private void initSession() throws NotValidConnectionException, IOErrorException, AuthFailedException, ClientServerIncompatibleException {
        for (int i = 0; i < minCountSession; i++) {
            queue.offer(this.pool.getSession(userName, passWord, true));
        }
    }

    private NebulaPool initGraphClient(String hostAndPort, int maxConnSize, int minCount) throws UnknownHostException {
        List<HostAddress> hostAndPorts = getGraphHostPort(hostAndPort);
        NebulaPool pool = new NebulaPool();
        NebulaPoolConfig nebulaPoolConfig = new NebulaPoolConfig();
        nebulaPoolConfig = nebulaPoolConfig.setMaxConnSize(maxConnSize);
        nebulaPoolConfig = nebulaPoolConfig.setMinConnSize(minCount);
        nebulaPoolConfig = nebulaPoolConfig.setIdleTime(1000 * 600);
        pool.init(hostAndPorts, nebulaPoolConfig);
        return pool;
    }

    private List<HostAddress> getGraphHostPort(String hostAndPort) {
        String[] split = hostAndPort.split(",");
        return Arrays.stream(split).map(item -> {
            String[] splitList = item.split(":");
            return new HostAddress(splitList[0], Integer.parseInt(splitList[1]));
        }).collect(Collectors.toList());
    }

    private Queue<Session> queue;

    private String userName;

    private String passWord;

    private int minCountSession;

    private int maxCountSession;

    private NebulaPool pool;

}

获取连接池session

@Component
public class NebulaSession {


    //@Autowired
    //NebulaPool nebulaPool;

    @Autowired
    NebulaGraphProperties nebulaGraphProperties;

    @Bean(destroyMethod = "release")
    public Session session() throws Exception {
        //return nebulaPool.getSession(nebulaGraphProperties.getUserName(),nebulaGraphProperties.getPassword(),false);
        SessionPool sessionPool = new SessionPool(nebulaGraphProperties.getMaxConnSize(), nebulaGraphProperties.getMinConnsSize(), nebulaGraphProperties.getHostAddresses().get(0),
            nebulaGraphProperties.getUserName(), nebulaGraphProperties.getPassword());
        return sessionPool.borrow();
    }

配置文件映射

@Configuration
@ConfigurationProperties(prefix = "nebula")
@EnableConfigurationProperties(NebulaGraphProperties.class)
@Data
public class NebulaGraphProperties {
    private String userName;
    private String password;
    /**
     * 格式:ip:prot
     */
    private List<String> hostAddresses;
    private int minConnsSize;
    private int maxConnSize;
    private int timeout;
    private int idleTime;
}

贴下错误 可能 session idle 太久在服务端被清掉了

sessionId 1709849895 不存在

那应该怎么办呢

  1. 应用层加个逻辑, 如果 session id 不存在了就再从 connection pool 里拿一个出来用
  2. 增加 session 在服务的过期时间, 减少问题发生

我这每次到了服务端这里的逻辑有的呀,但是似乎不行呀~~,应该是验证的的逻辑这里,并不是null,所以返回的还是原来的session,但是却是一个过期了的 session

无论如何增加时间,如果不能自动续约,还是不能解决根本的问题

想了下确实有问题, pool 是从 idleSession 里返回一个 session 出来的, 如果这个队列里的 session 已经是过期的那重新调用 getSession() 还是不能拿到可用 session. 给我们的 repo 提个 issue 吧, 可能需要在周期检测时 ping 一下 session, 发现不可用了要移除

1 个赞

您好,我在使用flink-nebula的过程中也遇到了同样的问题,在sink数据的流程中,程序运行了一段时间后再执行getSession方法会报session不存在,这个问题在后续版本中能进行优化吗?

1 个赞

看起来 nebula-flink writer session 是提前准备的,冷却时间长之后会有问题?

@jerryzhou1997 请问你能来 nebula-flink-connector 建立一个 issue 描述你的问题么?如果是这个问题应该是 nebula-flink-connector 来处理的,算是一个小bug

cc @nicole

好的,稍晚些我会将问题在issue那边进行细节描述

感谢 :heart:

浙ICP备20010487号