简单页面上的高负载平均zf2 +原则


High load average zf2 + doctrine on simple page

我使用ZendFramework2和Doctrine来启动我的项目。我的CPU在httpd请求上的使用率很高。我为filecaching启用opcache,为Doctrine启用memcache

知道为什么它的平均负载接近5.0吗?一次我把die('test1')放在ZendFramework2的onBootstrap里面,另一次我把die('test')放在前面。

die('test2')
Zend'Mvc'Application::init(require 'config/application.config.php')->run();

我的Apache bench显示,当框架加载时没有任何连接到数据库或转到任何控制器,它慢了5倍。为什么zf2会这样做,有什么可能的解决方案来规范它的行为?

(问题更新)

我用Xdebug和Webgrind进行了分析,发现像bootstrap这样的进程占用了很高的百分比

(应用程序'模块-> onBootstrap)

在bootstrap上我有这行代码

        //...
        $eventManager->attach(MvcEvent::EVENT_ROUTE, function($e) use ($blacklistForNormalUser, $auth) {
        $match = $e->getRouteMatch();
        // No route match, this is a 404
        if (!$match instanceof RouteMatch) {
            return;
        }
        // Route is whitelisted
        $name = $match->getMatchedRouteName();
        if (!in_array($name, $blacklistForNormalUser)  ) {
            return;
        }
        // User is authenticated
        if ($auth->hasIdentity() ) {
            return;
        }
        // Redirect to the user login page, as an example
        $router   = $e->getRouter();
        if(in_array($name, $blacklistForNormalUser)){
            $url      = $router->assemble(array(), array(
                'name' => 'user/login'
            ));
        }
        $response = $e->getResponse();
        $response->getHeaders()->addHeaderLine('Location', $url);
        $response->setStatusCode(302);
        return $response;
    }, -100);
    //...

另一个高点是

学说' ORM映射' '司机' AnnotationDriver -> loadMetadataForClass

如果系统支持50个用户,而不是100个。那么系统中可能会出现瓶颈。当它超过50个用户的阈值时,它可能会耗尽某些资源,从而导致负载迅速上升。

从字里行间可以看出,您正在使用LAMP堆栈。有用的命令有:

top

这将很快为您提供大量信息。查看顶部的行,以查看CPU行中处理器正在花费时间的内容。非常高的%wa可能意味着等待来自db的磁盘IO。

查看Mem:和Swap:行,检查低负载和高负载下的交换。如果它已经明显上升,那么这可能意味着您的系统正在耗尽内存。要么调整你的应用程序,要么增加更多的内存。

查看正在运行的任务,顶部显示什么?Httpd,也许mysql或其他一些工具,如备份运行和造成混乱。

试着去阅读你的系统中的信息。还有许多其他命令,如'free -m'或'vmstat -n 5',可能值得查询。

如果没有帮助,那么几个Apache工具可以帮助mod_status,这将显示Apache在任何给定时间正在处理的请求。此外,在apache的commonlog配置选项中添加%msT将使它记录服务每个请求所花费的时间,然后您可以在日志中查找任何非常慢的脚本。

在这一切之后-如果它仍然没有意义或所有。你可以带着另一个问题回来,再详细介绍一下你的系统。

....................

感谢您添加额外的细节和良好的工作与webgrind。有许多代码排列可能会导致速度变慢,但最好从一些基本的ZF2调优开始,这是一项有用的技能。

默认情况下,很容易让ZF2为视图和类做大量查找文件的工作。这大大降低了ZF2的速度,因为它必须在每个请求中找到它们。由于同样的原因,当不使用绝对路径名加载文件时,Opcache的效率也会降低。

ZF2在vendor/bin中有一个工具可以帮助完成这个任务,它可以生成类和文件位置的列表。对于Application文件夹中的每个模块。

php classmap_generator.php -l "..'..'modules'MODULENAME"

php classmap_generator.php -l ../../module/Application
Creating class file map for library in '/zend/module/Application'...
Wrote classmap file to '/zend/module/Application/autoload_classmap.php'

通过在Module.php文件中添加如下内容来确保classmap被使用:

public function getAutoloaderConfig()
{
    return array(
        'Zend'Loader'ClassMapAutoloader' => array(
            __DIR__ . '/autoload_classmap.php',
        ),
        'Zend'Loader'StandardAutoloader' => array(
            'namespaces' => array(
                __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
            ),
        ),
    );
}

通知Zend如何搜索要包含的文件,并跳过猜测部分。

不讨论任何特定框架的细节,只讨论一般的php。所以一点一点地思考这个问题。

我的cpu显示httpd请求的高使用率

是否有执行繁重的计算或繁重的查询?可能其他系统进程使用CPU太多(失控进程)?这是可能发生的,这是优化你的代码的合适时机。

  • 检查代码中的陷阱(冗余的for循环,计算等)
  • debug_backtrace是显示执行跟踪的好方法
  • 总结-使用像xcode这样的调试器/分析器。有很多功能和很好的工具来分析结果使用GUI工具,如kcachegrind。执行时间,内存消耗,逻辑树,图形等-都在那里供您探索。

我为文件缓存启用了opcache,为学说启用了memcache

访问php.net

OPcache通过在共享内存中存储预编译的脚本字节码来提高PHP的性能,从而消除了PHP在每次请求时加载和解析脚本的需要。

所以没有任何与文件缓存相关的内容。引用说它非常清晰和简洁-它加快了php部分。有一个类似的问题(也与zend相关)告诉你memcachememcached之间的区别;无论如何,如果您的数据库负载过重或查询缓慢/繁重,它可能是补救措施。

那么平均负载接近5.0的原因是什么呢?

这是相当复杂的,因为整个系统必须分析。是的,可能会发生只有一部分代码需要重做,也可能会发生整个应用程序有严重的问题,web服务器,数据库,缓存层的配置。

我的建议是采取同样的方法,并开始reverse engineer

  • 你确定只是服务器端慢吗?任何外部脚本,大图像,字体?
  • 然后按照第一个列表中的步骤操作。
  • 如果仍然没有变化,查看日志(尽管,必须非常非常频繁地检查)。
  • 检查系统配置-最近移动到nginx,能够服务21倍以上的请求/秒,静态文件也在飞行,低内存消耗(不是真正的CPU相关,我知道)

我的apache bench显示,当框架加载时没有任何连接到数据库或转到任何控制器,其速度慢5倍

这很有趣,因为与DB建立连接时总是有开销,无论大小…

为什么zf2太重,解决方法是什么?

我想这太宽泛了,你只需要选择你喜欢的框架,考虑它附带的优点和缺点。