j'aimerais optimisé au maximum les performances du ZF dans son architecture MVC.
j'ai sur un même serveur, fait des tests de montée en charge avec JMeter de 2 applications PHP
App 1 : développée avec un framework maison
App 2 : developpée avec ZF (v1.11)
La batterie de test consiste à charger 3 pages de l'app 1 et 3 pages de l'app 2
les pages choisies sont similaires en terme d'interactions avec les autre processus (pas de requêtes SQL ultra lourde , utilisation de Memcached ...) .
En fait, sachant ZF non forcément optimisé pour les performances, j'ai volontairement, charger des pages sur l'app1 (framework maison) avec plus d'accès aux bases de données pour laisser une petite chance au ZF d'être plus rapide (j'ai fait de la discrimination positive en quelque sorte)
Malheureusement, les tests sont clairs, mon app ZF pète beaucoup plus rapidement sous le fait d'une montée en charge.
j'ai fait les tests sur un serveur de dev, ce qui est intéressant sont plus les comparatifs que les chiffres brutes
Sur des montées en charges sur 1 minutes, je compte les erreurs de type "PHP Fatal error: Maximum execution time of 30 seconds exceeded"
60 utilisateurs app1 : 0, app 2 (zf) :0
120 utilisateurs app1 : 0, app 2 (zf): 30
180 utilisateurs app1 : 0, app 2 (zf) : 350
300 utilisateurs app1 : 50, app 2 (zf): >1000
Pour le ZF, ces erreurs ne se produisent pas au niveau des modèles, mais au niveau des librairies Zend, ce qui montre en engorgement de l'application au niveau de bootstrap
Plusieurs choses sont possiles pour booster les performances du ZF
1. Au niveau des accès base de données (serveur MySQL dans notre exemple) ,qui sont les causes de baisse de performance les plus courantes
Une petite analyse des logs de MySQL avec par exemple un outil comme jetprofiler montre que dans le top 10 des requêtes apparaissent des "DESCRIBE TABLE", mais pas de panique, les développeurs du ZF y ont pensé et on peut mettre en cache les données des tables en ajoutant une méthode d'initialisation dans la classe du bootstrap, comme ceci :
protected function _initMetadataCache() {
$frontendOptions = array(
'lifetime' =>500,
'automatic_serialization' => true,
//'debug_header' => true,
);
$backendOptions = array(
'lifetime' => 500,
'cache_dir' => APPLICATION_PATH .'/../cache/metadata'
);
$cache = Zend_Cache::factory('Core', 'File', $frontendOptions, $backendOptions);
//Zend_Registry::set('MetadataCache', $cache);
Zend_Db_Table_Abstract::setDefaultMetadataCache($cache);
//return $cache;
}
2. Au niveau du chargement des classes, c'est bien pratique d'utiliser l'autoloader de Zend, mais on peut l'optimiser :
2.a. En précisant dans le .htaccess de l'application l'include_path PHP pour celle ci
Dans mon exemple, je préfère utiliser le .htaccess que le php.ini car, l'app Zend n'est as la seule à tourner.
2.b On charge l'autoloader de Zend le pus tôt possible dans l'application, par exemple comme ceci :
//redéfinition de l'autoloader par défaut afin d'optimiser le chargement :
include 'Zend/Loader/Autoloader.php';
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->setDefaultAutoloader(create_function('$class', "include str_replace('_', '/', \$class) . '.php';" ));
Et on met en commentaires tous les appels "require_once" de la librairie Zend.
Après ces optimisations, le gain de performances est notable :
60 utilisateurs app1 : 0, app 2 (zf) :0
120 utilisateurs app1 : 0, app 2 (zf): 2
180 utilisateurs app1 : 0, app 2 (zf) : 175
300 utilisateurs app1 : 50, app 2 (zf): >1000
Mais l'appli du framework maison résiste quand même bien mieux à la montée en charge.
C'est normal étant plus simple, elle moins scalable , mais gère moins d'exception, charge moins de ressources,...
Au niveau du développement, évidemment, je préfère me replonger dans du code Zend que dans le code de l'appli maison, après tout c'est pour cela qu'on utilise un framework tel que Zend.
Cependant, je me demandait si quelqu'un aurait encore quelques conseils éclairés pour optimiser une application Zend.
Donc si quelqu'un a des pistes ...
merci

j'aimerais optimisé au maximum les performances du ZF dans son architecture MVC.
j'ai sur un même serveur, fait des tests de montée en charge avec JMeter de 2 applications PHP
App 1 : développée avec un framework maison
App 2 : developpée avec ZF (v1.11)
La batterie de test consiste à charger 3 pages de l'app 1 et 3 pages de l'app 2
les pages choisies sont similaires en terme d'interactions avec les autre processus (pas de requêtes SQL ultra lourde , utilisation de Memcached ...) .
En fait, sachant ZF non forcément optimisé pour les performances, j'ai volontairement, charger des pages sur l'app1 (framework maison) avec plus d'accès aux bases de données pour laisser une petite chance au ZF d'être plus rapide (j'ai fait de la discrimination positive en quelque sorte)
Malheureusement, les tests sont clairs, mon app ZF pète beaucoup plus rapidement sous le fait d'une montée en charge.
j'ai fait les tests sur un serveur de dev, ce qui est intéressant sont plus les comparatifs que les chiffres brutes
Sur des montées en charges sur 1 minutes, je compte les erreurs de type "PHP Fatal error: Maximum execution time of 30 seconds exceeded"
60 utilisateurs app1 : 0, app 2 (zf) :0
120 utilisateurs app1 : 0, app 2 (zf): 30
180 utilisateurs app1 : 0, app 2 (zf) : 350
300 utilisateurs app1 : 50, app 2 (zf): >1000
Pour le ZF, ces erreurs ne se produisent pas au niveau des modèles, mais au niveau des librairies Zend, ce qui montre en engorgement de l'application au niveau de bootstrap
Plusieurs choses sont possiles pour booster les performances du ZF
1. Au niveau des accès base de données (serveur MySQL dans notre exemple) ,qui sont les causes de baisse de performance les plus courantes
Une petite analyse des logs de MySQL avec par exemple un outil comme jetprofiler montre que dans le top 10 des requêtes apparaissent des "DESCRIBE TABLE", mais pas de panique, les développeurs du ZF y ont pensé et on peut mettre en cache les données des tables en ajoutant une méthode d'initialisation dans la classe du bootstrap, comme ceci :
[php]protected function _initMetadataCache() {
$frontendOptions = array(
'lifetime' =>500,
'automatic_serialization' => true,
//'debug_header' => true,
);
$backendOptions = array(
'lifetime' => 500,
'cache_dir' => APPLICATION_PATH .'/../cache/metadata'
);
$cache = Zend_Cache::factory('Core', 'File', $frontendOptions, $backendOptions);
//Zend_Registry::set('MetadataCache', $cache);
Zend_Db_Table_Abstract::setDefaultMetadataCache($cache);
//return $cache;
}[/php]
2. Au niveau du chargement des classes, c'est bien pratique d'utiliser l'autoloader de Zend, mais on peut l'optimiser :
2.a. En précisant dans le .htaccess de l'application l'include_path PHP pour celle ci
[code]php_value include_path "/dir/library/Zend"[/code]
Dans mon exemple, je préfère utiliser le .htaccess que le php.ini car, l'app Zend n'est as la seule à tourner.
2.b On charge l'autoloader de Zend le pus tôt possible dans l'application, par exemple comme ceci :
[php]//redéfinition de l'autoloader par défaut afin d'optimiser le chargement :
include 'Zend/Loader/Autoloader.php';
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->setDefaultAutoloader(create_function('$class', "include str_replace('_', '/', \$class) . '.php';" ));[/php]
Et on met en commentaires tous les appels "require_once" de la librairie Zend.
Après ces optimisations, le gain de performances est notable :
60 utilisateurs app1 : 0, app 2 (zf) :0
120 utilisateurs app1 : 0, app 2 (zf): 2
180 utilisateurs app1 : 0, app 2 (zf) : 175
300 utilisateurs app1 : 50, app 2 (zf): >1000
Mais l'appli du framework maison résiste quand même bien mieux à la montée en charge.
C'est normal étant plus simple, elle moins scalable , mais gère moins d'exception, charge moins de ressources,...
Au niveau du développement, évidemment, je préfère me replonger dans du code Zend que dans le code de l'appli maison, après tout c'est pour cela qu'on utilise un framework tel que Zend.
Cependant, je me demandait si quelqu'un aurait encore quelques conseils éclairés pour optimiser une application Zend.
Donc si quelqu'un a des pistes ...
merci :D