swoole http server 整合 phalcon,ab测试,报php内存耗尽

 lluuaalulua619 发布于 2022-11-17 15:55

在整合swoole http server和phalcon,server.php如下:

registerDirs(array(
            '../apps/controllers/',
            '../apps/models/'
        ));

        $loader->register();
    }

    /**
     * This methods registers the services to be used by the application
     */
    protected function registerServices()
    {

        $di = new DI();

        //Registering a router
        $di->set('router', function(){
            return new Router();
        });

        //Registering a dispatcher
        $di->set('dispatcher', function(){
            return new Dispatcher();
        });

        //Registering a Http\Response
        $di->set('response', function(){
            return new Response();
        });

        //Registering a Http\Request
        $di->set('request', function(){
            return new Request();
        });

        //Registering the view component
        $di->set('view', function(){
            $view = new View();
            $view->setViewsDir('../apps/views/');
            return $view;
        });

        $di->set('db', function(){
            return new Database(array(
                "host" => "localhost",
                "username" => "root",
                "password" => "",
                "dbname" => "invo"
            ));
        });

        //Registering the Models-Metadata
        $di->set('modelsMetadata', function(){
            return new MemoryMetaData();
        });

        //Registering the Models Manager
        $di->set('modelsManager', function(){
            return new ModelsManager();
        });

        $this->setDI($di);
    }

    public function main()
    {
        $this->registerServices();
        $this->registerAutoloaders();
    }
}

$application = null;

$http = new swoole_http_server("0.0.0.0", 9501);

$http->on('request', function ($request, $response) {
    try {
        $_GET = $_POST = $_COOKIE = $_REQUEST = [];

        if (!empty($request->get)) {
            $_GET = $request->get;
            $_REQUEST += $_GET;
        }

        if (!empty($request->post)) {
            $_POST = $request->post;
            $_REQUEST += $_POST;
        }

        if (!empty($request->cookie)) {
            $_COOKIE = $request->cookie;
        }

        global $application;
        $html = $application->handle($request->server['request_uri'])->getContent();
        $response->end($html);
    } catch (\Exception $e){
        print_r($e);
        echo $e->getMessage();
    }
});

$http->on('WorkerStart', function($server, $workerId) {
    global $application;
    $application = new Application();
    $application->main();
});
# 启动服务器
$http->start();

浏览器访问没什么问题
做ab测试就报错了

ab -n 10000 -c 1000 -rk http://phalcon.com/

错误信息:

[root@localhost public]# [2016-08-25 17:12:45 *12502.0]    ERROR    zm_deactivate_swoole (ERROR 103): Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 16384 bytes) in /srv/www/single/public/server.php on line 126.
[2016-08-25 17:12:45 $12497.0]    WARNING    swManager_check_exit_status: worker#0 abnormal exit, status=255, signal=0

请教这是什么原因导致的,是onRequest那里写的不对吗?

7 个回答
  • 建议拉个进程实时监控内存使用情况

    2022-11-17 16:09 回答
  • 使用swoole,就会出现内存泄漏的问题,建议拉个进程实时监控内存使用情况,内存达到一定量就重启进程

    2022-11-17 16:09 回答
  • 估计是因为php.ini的 memory_limit = 256M 限制导致 Swoole 遇到内存不足:
    Fatal error: Allowed memory size of 268435456 bytes exhausted
    建议分配512MB或者更大.并发越大,Swoole每个工作进程占用的内存也越多.

    2022-11-17 16:09 回答
  • $http->on('WorkerStart', function($server, $workerId) {
        global $application;
        $application = new Application();
        $application->main();
    });

    修改成为

    $http->on('WorkerStart', function($server, $workerId) {
        $server->application = new Application();
        $server->application->main();
    });

    之后你都可以使用 $server->application来访问Application对象了。

    如果已上方法你不想这样做,请修改onrequest方法:

    $http->on('request', function ($request, $response) {
        try {
            //你的代码
            global $application;
            $html = $application->handle($request->server['request_uri'])->getContent();
            $response->end($html);
        } catch (\Exception $e){
            print_r($e);
            echo $e->getMessage();
        } finally{
            unset($application);
        }
    });
    2022-11-17 16:09 回答
  • 感觉像是global $application;的缘故,可以建议对于公用的东西走单例模式

    2022-11-17 16:09 回答
  • 看起来$application 是一个单例,那么内部状态应该会有冲突吧

    2022-11-17 16:09 回答
  • 这个问题,目前我还没找到答案,说下目前的情况
    这个是有人写的一个demo:https://github.com/yekongmei/...
    这个我测了,在ab -n 10000 -c 1000 -kr http://phalcon.com/这样的测试下,可以做大概7-8轮测试,然后也报

    PHP Fatal error:  Allowed memory size of 268435456 bytes exhausted (tried to allocate 16384 bytes) in /srv/www/single/public/server.php on line 56

    特别是配置这里:

    $http->set(array(
        'worker_num' => 4,
        'daemonize' => true,
        'max_request' => 100000,
        'dispatch_mode' => 1
    ));

    如果注释掉,也就只能跑一轮,第二次就也报内存不够的问题了
    继续探究吧,我也再问问


    2016-09-30 18:25:18 更新
    现在找到了问题所在,是控制器里面返回内容所用的方式引起的:

    public function indexAction()
    {
        return "hello world"; //这种会导致报Allowed memory exhausted
    }
    public function indexAction()
    {
        echo "hello world"; //这种不会
    }

    这两种都能正常打印hello world。
    看起来应该是return回去的内容,导致$html没有释放掉?暂时这么猜的,我想看内存里面哪个变量没有释放,但没找到看php的内存变量的方法,有知道的贴个答案。

    2022-11-17 16:09 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有