我使用ZendFramework2和Doctrine来启动我的项目。我的CPU在httpd
请求上的使用率很高。我为filecaching启用opcache
,为Doctrine启用memcache
。
知道为什么它的平均负载接近5.0吗?一次我把die('test1')
放在ZendFramework2的onBootstrap
里面,另一次我把die('test')
放在前面。
die('test2')
ZendMvcApplication::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 "....modulesMODULENAME"
。
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(
'ZendLoaderClassMapAutoloader' => array(
__DIR__ . '/autoload_classmap.php',
),
'ZendLoaderStandardAutoloader' => 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相关)告诉你memcache和memcached之间的区别;无论如何,如果您的数据库负载过重或查询缓慢/繁重,它可能是补救措施。
那么平均负载接近5.0的原因是什么呢?
这是相当复杂的,因为整个系统必须分析。是的,可能会发生只有一部分代码需要重做,也可能会发生整个应用程序有严重的问题,web服务器,数据库,缓存层的配置。
我的建议是采取同样的方法,并开始reverse engineer
。
- 你确定只是服务器端慢吗?任何外部脚本,大图像,字体?
- 然后按照第一个列表中的步骤操作。
- 如果仍然没有变化,查看日志(尽管,必须非常非常频繁地检查)。
- 检查系统配置-最近移动到
nginx
,能够服务21倍以上的请求/秒,静态文件也在飞行,低内存消耗(不是真正的CPU相关,我知道)
我的apache bench显示,当框架加载时没有任何连接到数据库或转到任何控制器,其速度慢5倍
这很有趣,因为与DB建立连接时总是有开销,无论大小…
为什么zf2太重,解决方法是什么?
我想这太宽泛了,你只需要选择你喜欢的框架,考虑它附带的优点和缺点。