I use ZendFramework2 and Doctrine for launching my project. My CPU shows high usage on httpd
requests. I enabled opcache
for filecaching, and memcache
for Doctrine.
Any idea why it might have a load average being near 5.0? I put die('test1')
inside of onBootstrap
of ZendFramework2 one time, and another time I put die('test')
before.
die('test2')
Zend\Mvc\Application::init(require 'config/application.config.php')->run();
My Apache bench shows that when the framework is loaded without any connection to a database or goes to any controller it's 5x slower. Why is zf2 acting like this and what might be a possible solution to normalize it's behavior?
[question update]
I profiled with Xdebug And Webgrind and found out processes like on bootstrap take high percentage
( Application\Module->onBootstrap)
on bootstrap I have this line of codes
//...
$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);
//...
another high point is
Doctrine\ORM\Mapping\Driver\AnnotationDriver->loadMetadataForClass
If you system works with 50 users, but not 100. Then you possibly have a bottleneck in your system. When it passes the threshold of 50 users then it may be running out of some resource which causes the load to rise rapidly.
Reading between the lines, you are using a LAMP stack. Useful commands are:
top
This gives you a lot of information very quickly. Look at the top rows to see in the CPU(s) row what the processors are spending their time on. Very high %wa could mean waiting on disk IO from a db.
Look at the Mem: and Swap: rows, check your swap at low and high load. If it has risen significantly then it could mean your system is running out of memory. Either tune your app or add more RAM.
Look at the tasks running, what shows at the top? httpd, maybe mysql or some other tool like a backup running and causing havoc.
Try to learn to read the information in your system. There are many other commands like 'free -m' or 'vmstat -n 5' which may be worth looking up.
If nothing there helps then a couple of Apache tools that may help are mod_status This will show what requests Apache is handling at any given time. Also adding %msT to your commonlog config option in apache will make it log the time taken to serve each request and you can then look for any very slow scripts in the logs.
After all this - if it still doesn't make sense or all. Come back with another question and add more detail about your system.
....................
Thanks for adding the extra detail and good work with webgrind. There are many permutations of code that could be causing slow down, but it may be best to start with some basic ZF2 tuning which is a useful skill.
By default, it's very easy to let ZF2 do a lot of work finding files for views and classes. This slows ZF2 down a lot as it has to find them on every request. The Opcache is also less effective when files are not loaded using absolute pathnames for the same reason.
ZF2 has a tool to help with this in vendor/bin which generates lists of classes and file locations. For each Module in your Application folder.
php classmap_generator.php -l "..\..\modules\MODULENAME"
e.g.
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'
Ensure the classmap is used by adding something like this to your Module.php files:
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\ClassMapAutoloader' => array(
__DIR__ . '/autoload_classmap.php',
),
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
__NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
),
),
);
}
This informs Zend how to search for files to include and skips the guessing part. It should be noticeably faster in your benchmarks.
Won't go into any particular framework details, just general php. So crunching the question bit by bit.
My cpu shows high usage on httpd requests.
Are there any heavy calculations executing or heavy queries? Maybe other system processes are using CPU too much (runaway processes)? It may happen and it is the proper time to optimize your code.
debug_backtrace
is a nice method to show the execution tracexcode
. There are A LOT features and nice tools to analyse the results using GUI tools like kcachegrind. Execution times, memory consumption, logical trees, graphs, etc - all there for you to explore.I enabled opcache for filecaching, and memcache for doctrine
Outing php.net
OPcache improves PHP performance by storing precompiled script bytecode in shared memory, thereby removing the need for PHP to load and parse scripts on each request.
So there is nothing related to file caching. The quote says it very clear and concise - it speeds up the php part. There is a simmilar question (also zend related) that tells you about differences between memcache and memcached; anyway it may be the remedy if your DB is under heavy load or the queries are slow/heavy.
So what is the reason for load average being near 5.0?
That is fair more complex since whole system has to be analysed. Yes, may happen that only a part of code has to be redone, also may happen that whole application has serious problems, conifiguration of webservers, DB's, caching layers.
What I suggest is to take the sane approach and start to reverse engineer
.
nginx
, able to serve 21x more requests/second, also static files are flying, low memory consumption (not really CPU related, I know)my apache bench shows that when framework loaded without any connection to database or goes to any controller its 5x slower
This is funny because there is always an overhead when establishing connection with DB, no matter big or small...
why zf2 is too heavy and what is the solution ?
I guess this would be to broad, you just have to pick framework you like considering pros and cons that comes bundled with it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With