06 05,2014

关于PHP使用ICE出现Ice_MemoryLimitException

场景:使用ICE做中间件,C++做服务端,PHP做客户端。

由于某个接口的传输数据过大,接口异常:Ice_MemoryLimitException,搜索了下是由于Ice的默认传输大小是1MB,最大可以设置为2G。

很明显我们传输的数据超过了1M。找到问题那就好办了,设置下Ice.MessageMaxSize即可,找到PHP.ini加上这面这句话:

ice.options="--Ice.MessageSizeMax=2048"

重启php-fpm,在phpinfo中查看确实是生效了。本以为这样就解决了。

但是刷新页面,异常依旧,Google了下,发现C#或者python都可以在代码中设置MessageSizeMax参数。想到PHP应该也可以直接在代码中设置。

在官方网站找到以下例子:

<?php
require 'Ice.php';
require 'Hello.php';
$communicator = null;
try {
    $data = new Ice_InitializationData;
    $data->properties = Ice_createProperties();
    //记载配置文件
    $data->properties->load("props.cfg");
    $communicator = Ice_initialize($data);
    $proxy = $communicator->stringToProxy("...");
    $hello = Demo_HelloPrxHelper::checkedCast($proxy);
    $hello->sayHello();
} catch(Ice_LocalException $ex) {
    // Deal with exception...
}
if($communicator) {
    try {
        $communicator->destroy();
    } catch(Ice_LocalException $ex) {
        // Ignore.
    }
}
?>

确实是可以设置参数,但是这里是配置的文件的,为了方便我直接使用以下代码进行设置:

$data = new Ice_InitializationData;

$data->properties = Ice_createProperties();
//设置传输数据大小, 单位KB
$data->properties->setProperty('Ice.MessageSizeMax', 2048);


$init = Ice_initialize($data);

OK,刷新之后问题解决。

PS:注意Ice.MessageSizeMax参数需要服务端和客户端同时设置。

参考资料:

C#的设置方式:http://stackoverflow.com/questions/8434429/why-do-i-get-icememorylimitexception-even-with-ice-messagesizemax-2000000

官方提供的调用实例:http://doc.zeroc.com/display/Ice/Application+Notes+for+PHP

Ice.MessageMaxSize的设置BUG:http://blog.chinaunix.net/uid-24439730-id-144103.html