Chinaunix首页 | 论坛 | 博客
  • 博客访问: 409397
  • 博文数量: 47
  • 博客积分: 1488
  • 博客等级: 上尉
  • 技术积分: 729
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-15 11:35
文章分类

全部博文(47)

文章存档

2012年(4)

2011年(22)

2010年(21)

分类: LINUX

2010-08-24 23:24:10

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 属性值为一个合适的值
  
修改之后,进行测试,问题解决。


阅读(7206) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-09-15 18:17:45

请问博主,ICE APP B到ICE APP A之间传输数据库的dataset,是一行行传输的,还是多行打包传输的?用的是ICE的什么方法?