ZF2 Optimize for high traffic

2019-01-21 02:45发布

问题:

My ZF2 application seems to be extremely slow when more than 3 users are using it at the same time.

I profile my code with xdebug and webgrind and non of my functions seems to be slow so it has to be an optimalisation issue within the zf2 it's self.

For cache I make use of the EdpSuperluminal module by EvanDotPro, this seems to increase the performance of the application.

We make use of nginx reverse proxy but make no sense as well.

I need some good advices to increase the response for high traffic. I speak about 30+ connected user at the same time.

回答1:

There's few very simple steps to achieve a faster application. There's three things that can always be considered.

  1. ZF2 Performance QuickTipp #1 - ViewModels Always manually assign the fully qualified script to render. This will increase the performance a little. It's done like this:

    public function someAction()
    {
        $viewModel = new ViewModel();
        $viewModel->setTemplate('MODULE / CONTROLLER / ACTION.phtml');
        // In this given example: $viewModel->setTemplate('foo/bar/some.phtml');
    
        // Do some other Controller-logic as used to
    
        return $viewModel->setVariables(array(
            //key-value-paired view-variables
        ));
    }
    
  2. ZF2 Performance QuickTipp #2 - Classmap Autoloading This probably is one of the most important parts of speeding up your application. Personally i've seen an increase in LoadingTimes by up to 40%. Implementing this is pretty simple:

    class Module 
    {
        public function getAutoloaderConfig()
        {
            return array(
               'Zend\Loader\ClassMapAutoloader' => array(
                    __DIR__ . '/autoload_classmap.php',
               ),
            );
        }
    }
    

    The autoload_classmap.php then is a simple array of 'FQ-CLASSNAME' => 'FQ-FILEPATH'. This can be automatted pretty easily using the classmap_generator-utility of ZF2

  3. ZF2 Performance QuickTipp #3 - Keep Module.php light! Sadly this is a post i haven't come around to write yet. The Module.php is a file that is loaded on every single request. Lots of people forget about this and write lots and lots of factories inside them. At one point, ZfcUser-Module.php was an example of what not to do. Closures or anonymous functions are executed on every request, too. This is quite a bit of work to be done if there's too many of them over the whole project. A better approach would be to simply write Factory-Classes. ZfcUser later updated Module.php to use this strategy.

And that's pretty much all the easy stuff one can do (that i know of - i dont know much! :D). However what sounds interesting is that starting to use 3 users your application runs slow. To my experience this has nothing to do with the scripts itself but is rather an server issue. Is this from a Staging Machine or locally?



回答2:

If you are using Doctrine, don't forget to add a cache for annotations. This drastically improve performance (when I activate this cache I divide nearly by two the loading time). If you are using DoctrineORMModule:

'doctrine' => array(
    'driver' => array(

        'cache' => array(
            'class' => 'Doctrine\Common\Cache\ApcCache'
        ),

        'configuration' => array(
            'orm_default' => array(
                'metadata_cache' => 'apc',
                'query_cache'    => 'apc',
                'result_cache'   => 'apc'
            )
        ),
    )
)

However, it's quite inconvenient while developing because you must clear the cache whenever your mapping change.



回答3:

the ZF2 classmap generator will give you a big boost if you have a large project:

http://framework.zend.com/manual/2.0/en/modules/zend.loader.classmap-generator.html

Alternatively if you are using composer (you should do) then you can use composer to generate the classmap for all your modules and dependdencies too which is even better:

php composer.phar install --optimize-autoloader

php composer.phar update --optimize-autoloader


回答4:

All of the above and using some kind of opcode caching like APC / Opcache it will speed things up. But yes ZF 2 seems to be very slow unfortunately even more slow then ZF 1 :(

Also the module config cache speeds things up, you cannot have any closures though to make this working ;)

http://hounddog.github.io/blog/performance-in-zend-framework-2/



回答5:

First of all to speedup your zf2 application you should use ZendOptimizerPlus. The vast part of execution time used to read and precompile php code. Typical ZF2 app has a lot of files, so it takes a lot of time to handle them.

ZendOp+ saves bytecode of your php application in shared memory, so server doesn't read a lot of files and doesn't parse it every request. ZendOp+ will be at php5.5 by default, so it is useful to know it and to use it.

Benchmarks gives 9x increase in performance for simple framework applications (symfony2 tests - http://www.ricardclau.com/2013/03/apc-vs-zend-optimizer-benchmarks-with-symfony2/ ).

I use it for my zf2 + doctrine2 + zfcUser application. Memcached is used for doctrine2 purposes, it gives only about 5% performance increase. So with ZendOp+ I got 6x increase (0.2 -> 0.03s) for simple pages and 3x increase (0.2 - 0.06) for complex pages with a lot of forms, entities, views. If I use classmap generator, I will update the answer.

Another issue is to use nginx + php-fpm rather than apache2+module. It saves server resources.