ICE 对象之间大数据量传输的Bug
这两天,上司给了一个之前版本的Bug,说是在现场发现的,让尽快解决。由于公司项目管理上并不规范,Bug描述信息很少,主要给了简短的文字描述,和bug发生时界面截图,连复现bug的步骤都没有,最初只是当作性能bug对待的。以下是复现、解决bug的过程。
通过分析,主要是认为ICE对象之间传输的数据量过大导致的问题,因此,搭建了环境,并制造了大数据量传输的情形,问题复现还算顺利。但调试、修复bug的过程确着实费了番劲。
1. 系统简要描述
先描述下系统大致情况吧,如下图所示
+-------------+
| PHP |
+-------------+
| |
+-------------+
| ICE APP A |
+-------------+
| |
+-------------+ +--------------+
| ICE APP B | ———| DataBase |
+-------------+ +--------------+
|
PHP 服务器程序调用ICE 应用A,有些业务A需要调用B,B访问数据库获取到业务数据并通过 ICE 运行时发送给A;当然PHP与A之间也是通过ICE通信,IcePHP,系统是不是挺简单?
2. GDB 调试
在Bug复现之后,就开始了GDB调试,很快发现,在B从数据库取回20000条记录后,返回 A 时没了响应;
于是,接下来在 A 调用B 的接口的前后插入了调试代码,重新进行GDB调试,发现代码没有从 B 返回,根据经验,要么发生异常,要么系统崩溃(很容易排除此可能)。这时去研究了下ICE的API,又发现了一个问题,A调用B时是可能抛出异常的,而写代码的人却没有去捕获。我想,接下来我要做的工作,任何做这技术的人都清楚了,那就是去捕获这个异常,查看异常信息。最终,发现是 MemoryLimitException。
通过查看 ICE Manual 知道,是因为传递的数据量超过了 Ice.MessageSizeMax 值,只需把该属性值调大就可以了;不过很遗憾,我改过之后没起作用,我在想为什么没起作用?于是,在代码中又插入了些调试代码,取得 A、B 的 Ice.MessageSizeMax 的属性值,很奇怪的发现 B 的该属性值为0(即使用默认值,而不是真的为0), 也就是说在配置文件中的配置没起作用了。
我想起在 Ice 文档中曾看到过, 一个 ICE 应用可以有多个通信器,每个通信器都是独立的,各有各的配置(当然可能相同,完全取决于开发者);同时,B 的通信器器就是A动态生成的,于是猜想可能跟这有关系,即不同的通信器配置不同,其中使用的就是用默认配置的那个通信器。
于是我查看了 A 生成 B 通信器的代码,果然发现 A没有给 initialize 函数传递配置数据,这导致A所使用的所有B的通信器都是缺省配置,也就是说在配置文件中对 B 的配置都没有任何作用了。
不过,考虑到 PHP 与 A 之间也是 ice 通信,肯定也存在这个问题。
3. Bug解决
在定位到问题以后,解决方案也就出炉了:
(1) 修改 A、B的配置文件,修改(添加) Ice.MessageSizeMax 属性值,使他为一个合适的值
(2) 修改 A 的代码,读取 B 的配置数据,用作分配 B 通信器的配置
(3) 修改 PHP 的 ICE配置,设置Ice.MessageSizeMax 属性值为一个合适的值
修改之后,进行测试,问题解决。
阅读(7218) | 评论(1) | 转发(0) |