::franek::

Aller au contenu | Aller au menu | Aller à la recherche

Mot-clé : Zend Server

Installer xhprof et xhprof gui sur Zend Server

Xhprof est un profiler de code PHP. C'est un concurrent de Xdebug développé par Facebook.

Il a le gros avantage de permettre de visualiser l'évolution de la mémoire. A ma connaissance, Xdebug ne le permet pas.

Il ne nécessite pas l'utilisation d'un logiciel tiers (type KCachegrind, non disponible sous Windows...argh...) et peut être installé sur un serveur de production sans, normalement, trop dégrader les performances.

Je vais ici vous décrire son installation sur Zend Server CE et l'installation de xhprof gui

Si vous utilisez une installation de PHP moins exotique (genre une debian avec les dotdeb), son installation sera, à mon avis, simplifiée :

apt-get install php5-xhprof


Installation de xhprof

On récupère les sources et on les décompresse :

$ wget http://pecl.php.net/get/xhprof-0.9.2.tgz
$ tar xvfz xhprof-0.9.2.tgz

On compile :

$ cd xhprof-0.9.2/extension
$ /usr/local/zend/bin/phpize
$ ./configure --with-php-config=/usr/local/zend/bin/php-config
$ make
$ make test
$ sudo make install

On modifie la configuration de PHP pour lui indiquer de charger cette extension :

$ sudo vi /usr/local/zend/etc/php.ini

On ajoute :

[xhprof]
extension=xhprof.so
;
; directory used by default implementation of the iXHProfRuns
; interface (namely, the XHProfRuns_Default class) for storing
; XHProf runs.
;
xhprof.output_dir=/tmp/xhprof

Il est nécessaire de créer le répertoire /tmp/xhprof et de donner les droits à l'utilisateur Apache (je fais un 777 par simplicité)

$ mkdir -p /tmp/xhprof
$ chmod 777 /tmp/xhprof

On redémarre Apache :

$ sudo /etc/init.d/zend-server restart-apache

Un phpinfo() doit normalement afficher l'extension xhprof.

On va tester rapidement que cela fonctionne en essayant de profiler un script PHP. Pour profiler il est nécessaire d'ajouter quelques lignes de code dans le script PHP. Vous verrez ensuite une technique pour l'ajouter de manière automatique sur l'ensemble des scripts PHP (via xhprof gui) :

<?php
...
xhprof_enable();

/**
 * your application code
 * ......
 * ......
 */

$xhprof_data = xhprof_disable();
$xhprof_root = '/chemin/vers/le/repertoire/xhprof-0.9.2/';
include_once $xhprof_root . "xhprof_lib/utils/xhprof_lib.php";
include_once $xhprof_root . "xhprof_lib/utils/xhprof_runs.php";
$xhprof_runs = new XHProfRuns_Default();
$run_id = $xhprof_runs->save_run($xhprof_data, "xr");

L'exécution de ce script devrait générer un fichier dans le répertoire /tmp/xhprof. Si oui, l'installation de l'extension xhprof est ok.

Visualiser l'analyse de vos scripts

xhprof propose une interface de consultation des "profiling" effectués. Cette application (xhprof gui) est disponible dans un dépôt git.

Xhprof gui

Actuellement, elle possède quelques dysfonctionnements (plantage lors de l'analyse d'un script trop important) mais qui peuvent être résolus.

Pour installer xhprof gui, vous pouvez suivre la procédure d'installation :

git clone https://github.com/preinheimer/xhprof.git
cd xhprof
ln -s xhprof_lib/utils/xhprof_runs_mysql.php xhprof_runs.php
mv xhprof_lib/config.sample.php xhprof_lib/config.php

Xhprof gui propose de stocker les éléments d'analyse dans une base (mysql, mssql, ...). Dans notre exemple, nous allons utiliser mysql.

On crée une base pour xhprof :

$ mysql -uroot -p
mysql > create database xhprof;

xhprof gui a besoin d'une table details dans la base xhprof. La description de la table est décrite dans le fichier Mysqli.

 CREATE TABLE `details` (
`id` char(17) NOT NULL,
`url` varchar(255) default NULL,
`c_url` varchar(255) default NULL,
`timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
`server name` varchar(64) default NULL,
`perfdata` MEDIUMBLOB,
`type` tinyint(4) default NULL,
`cookie` BLOB,
`post` BLOB,
`get` BLOB,
`pmu` int(11) unsigned default NULL,
`wt` int(11) unsigned default NULL,
`cpu` int(11) unsigned default NULL,
`server_id` char(3) NOT NULL default 't11',
`aggregateCalls_include` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `url` (`url`),
KEY `c_url` (`c_url`),
KEY `cpu` (`cpu`),
KEY `wt` (`wt`),
KEY `pmu` (`pmu`),
KEY `timestamp` (`timestamp`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

Il est ensuite nécessaire de créer un Virtual Host pour accéder à xhprof gui :

<VirtualHost *:80>
   DocumentRoot /mon/super/chemin/vers/xhprofgui/xhprof_html
   ServerName xhprof.local
   DirectoryIndex index.php
</VirtualHost>

N'oubliez pas de l'activer et d'ajouter dans votre fichier /etc/hosts une entrée pour ce nouveau domaine.

Il est nécessaire de modifier le fichier xhprof_lib/config.php avec les paramètres qui vont bien.

Voici les premières lignes du fichier config.php que j'utilise :

<?php
$_xhprof = array();

// Change these:
$_xhprof['dbhost'] = 'localhost';
$_xhprof['dbuser'] = 'root';
$_xhprof['dbpass'] = 'root';
$_xhprof['dbname'] = 'xhprof';
$_xhprof['servername'] = 'myserver';
$_xhprof['namespace'] = 'myapp';
$_xhprof['url'] = 'http://xhprof.local/';

//These are good for linux and its derivatives.
//*
$_xhprof['dot_binary']  = '/usr/bin/dot';
$_xhprof['dot_tempdir'] = '/tmp';
$_xhprof['dot_errfile'] = '/tmp/xh_dot.err';
//*/

$exceptionURLs = array();

$exceptionPostURLs = array();
$exceptionPostURLs[] = "login";


$_xhprof['display'] = false;
$_xhprof['doprofile'] = true;

$controlIPs = array();
$controlIPs[] = "127.0.0.1";   //Localhost, you'll want to add your own ip here
$controlIPs[] = "ma super ip personnelle";   // Je bosse sous Windows (on ne choisit pas toujours...) mais mon serveur est dans une VM. J'indique l'IP de mon Windows.

$otherURLS = array();

$weight = 100;

Ensuite pour tous les virtual hosts que vous souhaiteraient monitorer, vous pouvez ajouter les lignes suivantes dans la configuration du VH :

php_admin_value auto_prepend_file "/mon/super/chemin/vers/xhprofgui/external/header.php"

Désormais en bas de chaque page, vous disposerez normalement d'un lien permettant d'accéder au profiling de la page courante.

Dernier point, si vous souhaitez générer des graphiques de ce type xhprof gui callgraph, il est nécessaire d'installer graphviz :

$ sudo apt-get install graphviz

J'espère que ces quelques notes vous aiderons à débuter avec xhprof.

Cet article s'est largement inspiré de profiling php application?

Edit 27/11/2012 : Correction suite à commentaire d'un visiteur.

APC et Zend Server

Une des limitations du cache de Zend Server (ShMem ou Disk) est de ne pas proposer d'outils de monitoring des éléments mis en cache. Apc propose cela par défaut via l'installation du script apc.php.

Zend Server propose, par défaut, une émulation de APC via le Zend DataCache. Cependant, cette émulation ne propose pas toute l'API de APC. Le script apc.php ne fonctionne donc pas. Je n'ai pas trop cherché mais, a priori, cela vient du non support complet des méthodes suivantes apc_compile_file(), apc_sma_info(), apc_cache_info() (voir forum chez phpfrance).

Je viens de découvrir que Zend mettait à disposition un paquet Apc.

Pour l'installer sur une debian/ubuntu, il suffit de :

# php-5.2
sudo apt-get install php-5.2-apc-zend-server
# php-5.3
sudo apt-get install php-5.3-apc-zend-server

puis redémarrer Apache (vérifier au préalable que le fichier /usr/local/zend/etc/conf.d/apc.ini est bien présent)

Il est donc ensuite possible de charger l'extension apc.so dans son php.ini. A nous les joies de l'utilisation de apc.php avec Zend Server.

Utiliser plusieurs versions de PHP et switcher facilement d'une version à l'autre sous Ubuntu

EDIT du 09/04/2010 : En fait, cette technique est obsolète. Je viens de découvrir PHPFarm qui semble faire plus ou moins ce que je souhaite faire. A tester donc.

--

Sur mon environnement de développement, je souhaite pouvoir switcher facilement d'une version de PHP à l'autre. Mes pré-requis sont de disposer de versions compilées de PHP (avec les extensions APC et Xdebug) ainsi que d'une version de PHP packagée avec Zend Server.

Je souhaite conserver la même version d'Apache. Sous windows, j'aurai avantageusement pu utiliser Wampserver, EasyPHP, ... Sous Linux, à ma connaissance, il n'existe pas de mécanisme de ce type.

J'ai donc développé un petit script Bash qui permet d'installer rapidement l'ensemble des versions PHP nécessaires avec les mêmes options de compilation.

J'utilise une version de Ubuntu mais cela devrait fonctionner avec une autre distribution.

A l'issue de l'installation, je pourrais switcher d'une version de PHP en une seule commande. Le PHP installé contiendra les mêmes extensions.

Le script va installer les différentes versions de PHP en utilisant la ligne de compilation suivante (qui correspond à mes besoins - support Oracle, mysql, gettext - , il est bien entendu possible de l'adapter à votre besoin) :

./configure --prefix=$installdir/$version \
        --with-config-file-path=$installdir/$version/etc \
        --with-apxs2=/usr/bin/apxs2 \
        --with-oci8=instantclient,/usr/local/oracle/instantclient \
        --enable-pdo \
        --with-pdo-oci=instantclient,/usr/local/oracle/instantclient,10.2.0.3 \
        --with-libxml-dir=/usr/lib/libxml2 \
        --with-xsl \
        --enable-ftp \
        --with-gettext \
        --enable-mbstring \
        --enable-soap \
        --enable-calendar \
        --with-openssl \
        --with-zlib \
        --with-mysql \
        --with-gd \
        --with-freetype-dir=/usr \
        --with-jpeg-dir=/usr \
        --enable-gd-native-ttf \
        --with-ttf \
        --with-t1lib \
	--enable-cli

Préparation de l'environnement

  1. Installer Zend Server. Vous pouvez suivre la procédure habituelle.
  2. Installer les paquets manquants afin de pouvoir compiler PHP (si vous souhaitez d'autres modules PHP, vous devrez ajouter d'autres paquets) :
sudo apt-get install apache2-prefork-dev libxml2-dev libxslt-dev openssl bison flex gcc automake libt1-dev libjpeg62-dev libfreetype6-dev freetype1-tools libgd-dev libmysqlclient15-dev
  1. Créer un fichier compil-php.sh contenant :
#!/bin/bash
# ---------------------------------------------------------------
# Script d'installation de plusieurs versions PHP sous Ubuntu
# Auteur : franek (franek at chicour dot net)
# ---------------------------------------------------------------

# répertoire où seront stockées les sources compilées de PHP
compildir=/opt/compil-php

# répertoire où seront installées les différentes versions de PHP
installdir=/usr/local

# Liste des versions de PHP à installer. Respecter la syntaxe php-X.Y.Z (sauf pour zend-ce)
versioninstall="zend-ce php-5.2.5 php-5.2.13";

# Nom du programme
progname=$(basename $0)

# Usage de ce script
# ---
function Usage()
{
	echo ""
    echo " Objet :"
    echo "   Ce programme permet d'installer plusieurs version de PHP sur un même serveur et de switcher d'une version de PHP à l'autre"
    echo ""
    echo " Usage : "
    echo "   $progname <action>"
	echo " Les <action> possibles sont : "
	echo "   - list : liste les versions de php installées"
	echo "   - install : installe toutes les versions PHP"
	echo "   - switch : permet de switcher de version"
    echo "   exemple : "
    echo "   $progname list"
}

# Création de l'environnement
# ---
function CreateEnv
{
	echo " - Création de l'environnement de compilation"
	if [ ! -d $compildir ]; then
		echo " - Création du répertoire $compildir"
		sudo mkdir -p $compildir
		sudo chmod 777 $compildir
	fi
}

# Téléchargement des sources de PHP à installer
# ---
function Download
{
	version=$1
	echo " - Téléchargement de $version"
	cd $compildir
	# Pour la version 5.2.5, il faut la récupérer sur museum.php.net
	# @todo : gérer les versions inférieures à 5.2.5
	if [ $version = "php-5.2.5" ]; then
		url=http://museum.php.net/php5/php-5.2.5.tar.gz
	else
		url=http://fr.php.net/get/$version.tar.gz/from/this/mirror
	fi
	wget $url
}

# Décompression des sources de PHP
# ---
function Unzip
{
	version=$1
	cd $compildir
	tar xvfz $version.tar.gz
	rm $version.tar.gz
}

# Compilation de PHP
# ---
function Compil
{
	version=$1
	phpcompildir="$compildir/$version"
	echo $phpcompildir
	cd $phpcompildir
	
	export OPTIM=-02
	make clean

	# compilation de PHP avec support Oracle, Gettext, ...
	# cette configuration peut être modifiée.
	./configure --prefix=$installdir/$version \
        --with-config-file-path=$installdir/$version/etc \
        --with-apxs2=/usr/bin/apxs2 \
        --with-oci8=instantclient,/usr/local/oracle/instantclient \
        --enable-pdo \
        --with-pdo-oci=instantclient,/usr/local/oracle/instantclient,10.2.0.3 \
        --with-libxml-dir=/usr/lib/libxml2 \
        --with-xsl \
        --enable-ftp \
        --with-gettext \
        --enable-mbstring \
        --enable-soap \
        --enable-calendar \
        --with-openssl \
        --with-zlib \
        --with-mysql \
        --with-gd \
        --with-freetype-dir=/usr \
        --with-jpeg-dir=/usr \
        --enable-gd-native-ttf \
        --with-ttf \
        --with-t1lib \
		--enable-cli
	
	make -j 10
}

# Affiche la liste des versions de PHP disponibles
# ---
function List
{
	echo "Versions disponibles : "
	# pour chaque version, on installe
	for version in $versioninstall
	do
		echo " - PHP version $version";
	done
	echo "Si vous souhaitez ajouter des versions, vous devez simplement éditer la variable versioninstall"
}

# Fonction qui permet de switcher de version de PHP
# ---
function Switch
{
	i=1
	echo "Versions disponibles : "
	for version in $versioninstall
	do
		tab[$i]="$version"
		echo " $i/ PHP version $version";
		i=$(($i + 1))
	done
	echo " - Quelle version de PHP souhaitez-vous utiliser ?"
	read item
	echo " - vous avez choisi d'utilsier : ${tab[$item]}";
	
	version=${tab[$item]}
	cd /usr/lib/apache2/modules
	if [ "$version" = "zend-ce" ]; then
		# PHP version Zend
		sudo rm libphp5.so && sudo ln -s ../../../local/zend/lib/php/libphp5.so libphp5.so
	else
		# PHP version compilé 5.2.5
		sudo rm libphp5.so && sudo ln -s $compildir/$version/libs/libphp5.so
	fi
	sudo apache2ctl restart
}

# Procédure d'installation de PHP
# ---
function InstallPhp
{
	while :
	do
		version=$1
		echo " - voulez-vous installer PHP (version : $version) ? (0/N)"
		read OK
		case $OK in
			"O") 	sudo make install-cli
					sudo make install-pear
					sudo make install-programs
					sudo make install-programs
					sudo make install-build
					sudo make install-headers
					#installation de apc et xdebug
					cd "$installdir/$version/bin"
					sudo ./pear update-channels
					sudo ./pear upgrade-all
					sudo ./pecl install pecl/apc
					sudo ./pecl install pecl/xdebug
					#création du fichier php.ini par défaut
					sudo touch $installdir/$version/etc/php.ini
					sudo chmod 777 $installdir/$version/etc/php.ini
					sudo echo -e "extension=apc.so\nextension=xdebug.so" > $installdir/$version/etc/php.ini
					break;;
			"N") echo "Cette version ne sera pas installée."; break;;
			*) echo " /!\ Veuillez répondre par O ou N !";;
		esac
	done
}

# Fonction générale de lancement de l'installation de PHP
function Install
{
	# création de l'environnement
	CreateEnv

	# pour chaque version, on installe
	for version in $versioninstall
	do
		# on installe pas zend-ce
		if [ $version = "zend-ce" ]; then
			continue;
		fi
		Download $version
		Unzip $version
		Compil $version
		InstallPhp $version
	done;
}

# -------------------------------------------------------------------------------
# ---- début du script ----------------------------------------------------------
# -------------------------------------------------------------------------------

if [ ! $# -eq 1 ]
then
        Usage
        exit 0;
else
	action=$1
	case $action in
        "list") List;;
        "install") Install;;
		"switch") Switch;;
        *) echo " /!\ Mauvaise utilisation"; Usage; exit 1; ;;
    esac	
fi
  1. Editer le script avec les versions de PHP que vous souhaitez installer. La variable à modifier est versioninstall. Chaque version doit être séparée par un espace. Le nom de la version doit respecter la syntaxe php-X.Y.Z.
  2. Exécuter ce script.

./compil-php.sh

Par défaut, ce script va vous afficher les commandes disponibles. Vous avez 3 options :

  • install : va installer les versions de PHP dans /usr/local/php-X.Y.Z
  • list : afficher la liste des versions de PHP configurées dans le script
  • switch : lorsque les versions de PHP ont été installées, permet de switcher d'une version de PHP à l'autre.

Par défaut, ce script va compiler les PHP dans le répertoire /opt/compil-php. Cette variable peut être modifiée dans le script.

Les binaires seront installés dans /usr/local/php-X.Y.Z. Le fichier de configuration php.ini se trouvera dans /usr/local/php-X.Y.Z/etc/php.ini (il est donc possible d'avoir un fichier php.ini par installation de PHP).

C'est un script brut. Des modifications pourraient être apportéees :

  • mise en oeuvre des contrôles d'erreurs
  • installation automatique de Zend Server
  • installation de HipHop
  • ...

Zend Server 5 et Oracle

Zend Server vient de sortir en version 5. Zend Server est le remplaçant de la Zend Platform.

Par défaut, Zend Server est fourni avec le client Oracle Instant Client Lite qui ne prend pas en charge les bases de données Oracle avec des encodages un peu exotique (WE8ISO8859P15, par exemple) :

ZS is shipped with the OCI library Lite version which only supports OCI and OCCI for US locales only. You may download the full version from Oracle's site and replace the current libraries shipped with ZendServer with those, they are API and ABI compatible so you should have no issues.

Si comme moi, vous disposez de bases Oracle dans ce type d'encodage, il est nécessaire d'installer un client Oracle Basic et d'indiquer à Zend Server le chemin vers ce client Oracle.

Voici la procédure :

  • Téléchanger instantclient-sdk-linux32-11.2.0.1.zip and instantclient-basic-linux32-11.2.0.1.zip
  • Décompressez les 2 archives. Cela va créer un répertoire : instantclient_11_2
  • Copier le répertorie dans /usr/local/oracle/
  • Créer un lien symbolique ln -s instantclient_11_2/ instantclient
  • Ajouter dans le fichier /etc/apache2/envvars

export LD_LIBRARY_PATH=/usr/local/oracle/instantclient:/usr/local/zend/lib
export ORACLE_HOME=/usr/local/oracle/instantclient

  • Redémarrer Apache.

Cela devrait fonctionner.

à propos :: Mots-clés :: archives :: RSS :: Mail