客户端无法重连 session

  • nebula 版本:3.1.0
  • 部署方式: 单机
  • 安装方式: Docker
  • 是否为线上版本:Y
  • 问题的具体描述

客户端因为异常重启后,session 无法复用,导致 session 数量达到上限。
client 为 golang 版本。
没有进行权限认证,密码直接使用的随机数,但密码只有在重装的时候会变动,重启不影响密码的值

如果 graph 可以重启的话更改配置后重启, 不然的话只能等待 session 过期了

1 个赞

所以请问为什么会无法复用呢?换句话说一个session能复用的前提是什么?

按理说 session 是持久化在硬盘的, 同一个 sessionID 只要没有过期都是可用的, 你说的无法复用具体是啥表现? 如果你的客户端重启了那客户端怎么知道之前的 sessionID? 看你的描述你应该是在客户端重启后做了鉴权 GetSession(), 这个操作是会生产新的 session 的

是的,我重启之后使用了 GetSession()
这样的话,请问如果我事先存储了 SessionID,当程序因为异常重启之后,我该怎利用这个 SessionID 复用这个 session 呢?

两种方法:

  1. 你在客户端创建好session后把 sessionID 写在本地磁盘, 这样工具重启了你也能拿到之前建立过的 sessionID
  2. show sessions 命令能看到当前服务端的 session, 把结果处理下也可以获得 sessionID
1 个赞

可能是我没有说清楚,我的意思是 client 重启之后,从文件里读取了上次的 sessionID, 并且确保这个 ID 是没有过期的,我应该在 client 中怎么利用这个 sessionID 去复用这个 session。

看了下这块现在确实没有接口, 因为设计的时候希望总是从 pool 获取 session.

你自己用的话需要修改下代码, 把 connection 变成 public 的, 这样的话构造了 connection 可以用 func (cn *connection) ExecuteJsonWithParameter(sessionID int64, stmt string, params map[string]*nebula.Value) ([]byte, error) , 把 sessionID 换成你获取到的 id 来执行语句

2 个赞

感谢您的回复,我会认真研究一下这个方案

可以考虑把改 connection 的部分 PR 过来呢

cc @Aiee

我觉得改动需要评估下, 因为原本不把 connection 暴露给用户是为了让用户始终通过 session 来使用, 不需要关注 session 持有的 connection

1 个赞

嗯嗯,同意 :heart:

那么可不可以从 ConnectionPool 暴露出一个复用 SessionID 的接口?ConnectionPool 拿到 SessionID 的列表之后去鉴定是否可用,可用的就继续使用。不然客户端由于一些原因重启之后,服务器那里拿着一堆 SessionID 没有什么意义。

1 个赞

不建议这么弄,原因:

  1. 小概率时间,这个问题是客户端异常退出或者退出时没有 release session,服务端会有无效的 session,这个就按过期时间处理就好了。未来我们会有 drop session 的命令,admin 可以 drop 掉无用的 sesssion。

  2. 如果暴露,用户可以保存 session 然后拿着已经存在的 session 请求,会有伪造的问题。对于 session 的生命周期,也不好管理。(比如你保存在文件,那客户端什么时候 release?)

综上,没什么特别的好处

核心问题,还是之前我们设计时,session 可以复用。而一旦客户端的 connection 断开,服务端 session 因为共用还是得保存,只能由客户端主动释放或者等待超时。

如果 session 和 connection 是一一对应,一旦 connection 断开,服务端就自动把 session 回收,可能会好一点。这个看未来的 session 管理的计划吧。
@MuYi

2 个赞

此话题已在最后回复的 7 天后被自动关闭。不再允许新回复。