java客户端无法释放因为graphd宕机导致无效的session

最nebula升级到3.3.0了,看到java客户端3.3.0版本也支持session pool了,就升级了一下,但是我发现session pool使用无法隔离掉宕机的机器。
是这样的,集群部署的一台graphd宕机后,我发现我的服务总是会出现报错,就研究了一下,发现宕机机器的session一直没有被释放,还能一直被使用,非常奇怪。然后我试了多次去主动停止graphd观察发现这个情况稳定复现,就分析了一下。
我看在SessionPool这个类中,有个checkSession方法是定时去检测session可不可用的,会把不可用的session释放掉。

但是问题在于,现在他发现无效session后,在release的时候报错了,报错是java.net.SocketException:Broken pipe(Write failed),下图里也有,而这里又没又catch住这个异常,导致整个checkSession定时任务直接失效了,无效的session也没有被释放,一直在sessionlist中仍然会被请求拿到。

也就是说集群部署的有一台graphd宕机后,失效的session无法被清除,这台宕机的graphd竟然无法被识别隔离掉,后续的请求一直会有报错。我看实际上sessionpool的代码是想要做检测隔离的,这个是不是一个bug?

是的,release失败会导致无法remove掉失效的session,这是个bug

那这个现在3.3.0版本的session pool没法用是吗? :joy: :joy: :joy: :joy: :joy:
connection pool应该没有这个问题吧?
那现在还是要自己实现session pool?或者说你们会在下个版本修复吗?

会修复,修复好会发bug fix的小版本的

大概会在什么时候发布啊

我还有个问题,我现在发现这个release失败这个报错不是一定会出现的,有几率出现。请问什么样的情况session release会报这个错误啊?

当你的服务关掉的时候,release session时会向服务端发起个signout的请求,此时就会报错 broken pipe啊, 因为服务端连接的端口关掉了

这些没有释放的session服务端会在配置的那个过期时间之后清理是吗?

是的

https://github.com/vesoft-inc/nebula-java/pull/499 pr已经合了,你可以使用snapshot版本

2 个赞

好的,我看到了,但是snapshot版本我只能测试用,使用起来我这里不太方便。
能问下正式版本什么时候会发吗?

预计下个月会发个小版本

既然SessionPool存在这个bug,是不是必须升级到最新的小版本才能完全避免该bug呀

如果connection.signout(sessionID)调用报错,服务端没能释放掉session,客户端却把session移除了,导致客户端频繁创建session,会触发max_sessions_per_ip_per_user

如果你是服务不可用,signout 一定是失败的, 此时session已经是不可用的了。这时候客户端会新建session重新执行,执行结束新session会释放放回池子中。下次执行时会获取sessionPool中的session重新执行的。
但如果你池子里全部都是异常的session,当并发执行时会在每次重新执行语句创建新session,理论上重新创建session的次数=session pool中异常session数。

你触发了max_sessions_per_ip_per_user时 该配置是多少,使用场景是什么样的?

这个好像是不是不太准确,signout虽然失败了(比如网络超时),客户端认定它是异常的,重新创建了新的session,但实际服务端的旧session好像还是有效的。
max_sessions_per_ip_per_user配的300,服务端session过期配的8小时

网络抖动导致的 执行失败,此时服务大概率是能短时间内恢复可用状态,signout就可以正常退出登录了,服务端也会释放session的。但如果signout时 网络未恢复,后面恢复后的确该session只能等过期失效了。

你客户端是怎么用的,使用场景是啥,并发执行 同时服务端会暂停服务? 并发多少,session pool的maxConnSize多大?配置的graphd hosts是几个?

用master分支打的maven快照。服务端可能因为并发高->负载高,暂时处理不了sigout这种请求。并发高的时候,大概200QPS,执行find path。maxConnSize=100。graphd hosts 2个。

我是通过max_sessions_per_ip_per_user配置10000,过期配成10分钟,暂时解决了这个问题

如果没有停止服务 且 网络正常的话,理论上不会出现超过100个session,除非查询请求存在大量的execution error 和 socket 连接异常,才会导致重建那么多的session。 可以在graphd的日志中确认下是否有很多execution_error