遇到的问题
SM04中看到有部分JCO调用的RFC的会话无法释放,极端情况导致所有第三方系统基于RFC的方式,都无法访问SAP。
解决方案
问题原因没有定位到,其实也算不上解决
在确认调用方代码没问题后,在SAP服务器端做了一些优化
- SAP推荐升级Kernel,出于风险没有采纳
- 对于特别耗性能的RFC系列接口
- 优化处理逻辑
- 减少调用、甚至不调用
- 过期会话,自动删除
自开发程序,定期执行,记录日志,在哪些接口上挂起了。 稍微一统计,就能识别哪个系统,哪些接口会导致问题。
RFC技术分析
正常的会话
可以通过参数设定多少时间后logout,比如rdisp/gui_auto_logout
RFC的会话
服务器端不会自动释放
个人猜测,RFC技术是很多其他技术的基础,比如ALE、iDoc,SAP在设计的时候就没有考虑去中断RFC的会话。只要调用端不主动释放,会话会一直被保持。
这里不讨论RFC调用时,分配了Work Process且一直在执行中,最后因为达到Work Process最大允许时间而被迫释放的场景。
JCO的会话管理
- 不使用连接池
调用完即释放 - 使用连接池
调用完后,继续放到连接池中。连接池中的另一个线程会定时检查池中的连接,若连接达到指定的时间未被使用,由该线程执行释放。
1.这里讨论的是stateless的JCO 3.0 访问方式 。
2.经常在SM04看到,连接池调用的会话保存一段时间后再消失,就很容理解。
挂起场景猜测
以下场景都是个人猜测
- 调用端突然中断
比如网络异常
RFC通常都是第三方服务器发起,请求SAP RFC接口,服务器之间网络异常比较少。但是以前在搞ITS时频繁遇到类似问题(ITS和RFC是两个东西),手持设备直接访问SAP ITS服务,仓库之间切换AP,导致SM04中看到会话挂起,这个和ITS的版本也有关系。
- JCO 2.0中访问没有主动释放
- JCO 3.0有状态调用没有主动close
- SAP服务器端异常
归根到底因为SAP Kernal在特定场景下,无法重置当前会话状态(比如标识此RFC函数已经调用结束),导致调用端无法回收,SM04中看到就是长时间挂起。
- Kernal 问题,SAP自己产品的Bug
感觉这次遇到的问题类似这个场景,RFC中的代码逻辑,无论CPU处理还是DB取值都比较麻烦,并且函数内部有submit和call transaction之类的调用,可能特定条件触发了会话管理异常,无法标识调用结束?
- 内部工作过程挂起
比如Dialog WP 等待 DB WP,DB WP因为数据库服务器问题,没有响应,导致Dialog WP也没有响应,表现为SM04中会话挂起
总结
- RFC会话服务器端不会主动去关闭
- 谁调用谁关闭
- 关闭的前提: 服务器端已标识RFC执行完毕
所以面对SM04无法释放的会话,调用方和SAP服务器都可能背锅。