PHP, clusters et sessions

    13:05 5 03 2006

Un des principaux problèmes que l’on peut rencontrer lorsque l’on utilise une architecture LAMP dans le cadre d’un site à fort trafic est l’utilisation des sessions sur un cluster de serveurs. En effet, par défaut, chaque serveur gère ses propres sessions sur son disque, l’utilisateur se verra donc attribuer une session différente à chaque fois qu’il sera redirigé par le répartiteur de charge sur un serveur différent du cluster. Plusieurs solutions plus ou moins efficaces permettent de résoudre ce problème. Sans être un expert de ce genre de problématiques, j’ai pu rencontrer plusieurs cas lors de mes différentes missions qui comportent toutes des avantages et des inconvénients.

La première consiste à lier un utilisateur à un serveur donné du cluster. Pour cela, lors de la première page affichée, le système de répartition de charge envoie un cookie à l’utilisateur afin de garder une trace du serveur vers lequel il a été redirigé. Lors des requêtes suivantes, l’utilisateur sera toujours redirigé vers le même serveur et conservera donc sa session. Cette solution bien que très facile à mettre en oeuvre pose plusieurs problèmes.
Premièrement, elle ne fonctionne bien sûr pas si l’utilisateur a désactivé les cookies. En même temps, les sessions ne devraient pas non plus fonctionner sans cookies à moins d’activer le use_trans_sid mais chacun sait que, par défaut, cela entraîne d’importantes failles de sécurité.
Le deuxième vient de la haute disponibilité. En effet, si le serveur sur lequel l’utilisateur a sa session tombe, il sera redirigé vers un autre serveur par le système de répartition de charge et perdra donc toutes les données de sa session courante ce qui peut être très problématique dans le cadre d’un site de vente en ligne par exemple.

Une autre solution va consister à redéfinir le handler (gestionnaire) de sessions afin de le rediriger vers un espace de stockage mutualisé pour les différents serveurs du cluster. Deux grandes possibilités sont généralement utilisées :
–le partage NFS – cette solution consiste à utiliser un serveur accessible en partage réseau et de stocker les sessions de tous les serveurs dessus. Elle est efficace pour de petits clusters mais, à ce que j’ai pu voir, les montées en charge entraînent rapidement des problèmes de lecture sur disque et donc des ralentissements importants de l’application.
– le stockage des sessions en base de données – le principe est très similaire sauf que les sessions sont stockées en base de données. Pour que cette solution soit efficace, il est primordial de dédier ce serveur de base de données uniquement au stockage des sessions. Une telle solution est généralement moins rapide que les sessions natives à cause du temps nécessaire à établir la connexion avec la base de données.

La dernière solution rencontrée est la solution propriétaire proposée par Zend au travers de sa Zend Paltform. Celle-ci dispose d’un module de cluster de sessions qui vient remplacer les sessions natives de PHP et permet aux différents serveurs du cluster de partager leurs sessions. De ce que j’ai pu voir, cette solution est plutôt efficace et stable, le partage des sessions n’induit pas spécialement de différences de temps de réponse avec les sessions natives. Elle est également très facile à mettre en oeuvre, il suffit d’installer la PlatForm, tout est géré automatiquement. Solution la plus professionnelle, elle a malheureusement aussi ses inconvénients.
D’abord le coût de licence de la PlatForm. Celui-ci n’est pas très élevé en regard des services qu’elle fournit mais il s’agit tout de même d’une somme non négligeable. Cette solution très complète de pilotage d’architecture PHP ne peut donc convenir qu’à des projets commerciaux d’une certaine envergure et ne peut pas être utilisée dans le cadre de projets communautaires ou à faibles revenus.
Ensuite, le système de cluster de session n’offre pas de redondance des données (hic!). Pour le moment, les sessions ne sont toujours stockées que sur leur serveur d’origine et partagées au moment de leur appel, donc si un serveur tombe, les sessions qui sont dessus ne sont plus disponibles. D’après une conversation que j’ai eu récemment avec Zeev, des fonctionnalités de redondance devraient rapidement être introduites dans les prochaines versions de la Platform ce qui permettra de résoudre ce problème. Quoi qu’il en soit, il apparaît que cette solution est pour le moment la plus efficace et je pense qu’on devrait rapidement la retrouver sur de nombreux systèmes.

Pour finir, je dirais simplement qu’il est peut être temps que la communauté se penche serieusement sur cette problématique. Si l’on souhaite que PHP s’impose en environnement professionnel, il faut lui en donner les moyens. A ceux qui me diront « Bah t’as qu’à le faire! », je répondrais simplement « J’aimerais bien, mais je n’en ai ni le temps, ni les compétences » :D



Metro, boulot, boulot, boulot…

    16:05 3 03 2006

Voilà, trois mois que je n’ai pas posté sur ce blog, trois mois complètement débordé par mon travail et ma vie personnelle; je viens enfin de refaire surface ce matin et de respirer une grande bouffée d’air, ouf…

Comme certains d’entre vous le savent peut être déjà, ZEND a décidé de profiter de cette année 2006 pour s’installer en France. Pour cela, ils ont choisi Anaska/Kaptive comme partenaire pour les formations et les missions de consulting/développement. Pour cela, Guillaume Ponçon, l’auteur du livre Best Practices PHP5 à rejoint notre équipe, ou plutôt va rejoindre notre équipe dés que sa période de préavis sera terminée chez son précèdent employeur.

En attendant, je me suis donc retrouvé à gérer les premières missions ZEND/ANASKA en même temps que mon travail courant, deux audits complets (environnement de dev, environnement de prod, best practices, architecture, infrastructure…) pour deux grands sites Français très connus (je suis toujours en attente de l’accord de ces sociétés pour les citer).

Ces deux missions ont été très enrichissantes pour moi.
D’abord par les intervenants avec lesquels j’ai été amené à travailler : Zeev Suraski, Chuck Hagenbuch (créateur de horde) ou encore Shahar Evron (spécialiste des produits Zend) .

Ensuite par les différents environnements de production que j’ai pu voir; d’un côté, un niveau professionnel très élevé avec plus de 70 serveurs en production, des procédures pointues de gestion et de maintenance; d’un autre côté, un environnement beaucoup plus artisanal avec une équipe obligée de s’adapter à de fortes contraintes budgétaires et n’ayant pas le temps de mettre en oeuvre des procédures évoluées de gestion.
Au final, deux environnements très différents mais permettant dans les deux cas de maintenir un site professionnel de services à destination des internautes soutenant une charge très élevée.
Nous avons émis, lors des deux missions, de nombreuses recommandations leur permettant d’atteindre un niveau d’excellence (quoi mes chevilles?) dans l’environnement de développement et de production PHP.

A part cela, nous avons été invités, Cyril (mon associé) et moi par Microsoft à l’International Technology Summit qui se déroulera à Redmond en Avril. L’occasion pour l’éditeur d’échanger avec des acteurs importants de la communauté Open Source sur leurs positions sous la forme de discussions interactives. Je vous ferai bien sûr un retour sur ce déplacement dés mon retour.

Voilà, il me reste quelques heures de répit avant de repartir en apnée, j’en profite donc pour ranger mon bureau, régler les affaires courantes et si j’ai le temps, mettre à jour WAMP ;-)



Communiquer avec PHP en CLI (ligne de commande)

    21:57 30 11 2005

J’ai dernièrement ajouté des fonctionnalités de gestion des extensions PHP à WAMP5. Pour cela, j’ai créé quelques scripts PHP en CLI appelés par le gestionnaire de WAMP. Mais comment communiquer avec PHP, lui passer des paramètres ou encore interagir avec l’utilisateur?

Je me suis donc penché sur la question et voici mes conclusions.

Passer des paramètres à un script CLI :

Pour cela , il suffit de fournir ces paramètres lors de l’appel au script. Attention, on a l’habitude de les passer grâce à la syntaxe HTTP. Quelque chose du genre :

« php index.php?toto=valeur »

Cela ne fonctionnera pas en CLI, cette syntaxe est liée au protocole HTTP (méthode GET), PHP cherchera un fichier s’appelant « index.php?toto=valeur ». en ligne de commande, il suffira d’ajouter ces paramètres à la suite de l’appel au script :

« php index.php valeur »

On pourra alors accéder aux paramètres grâce aux tableaux $_SERVER['argv'] et $_SERVER['argc']. argc permettra de connaître le nombre de variables passées à PHP, argv permettra d’accéder à ces paramètres. Dans l’exemple précèdent

$_SERVER['argv'][0] vaudra « index.php »
$_SERVER['argv'][1] vaudra « valeur »

Interagir avec l’utilisateur lors de l’exécution du script :

Il peut arriver que l’on ait besoin de poser des question à l’utilisateur, récupérer des variables. Dans le cas de WAMP5, un des scripts permet d’ajouter une extension dans le php.ini, il faut donc que l’utilisateur puisse taper le nom de cette extension. Pour cela, il suffit d’utiliser l’entrée standard STDIN.

La commande

$newext_name = trim(fgets(STDIN));

permet de lire ce qui arrive de STDIN jusqu’à ce qu’il y ait un retour chariot. Concrètement, cela permet à l’utilisateur de taper tout ce qu’il veut jusqu’à ce qu’il tapes sur la touche Entrer. le contenu tapé est alors récupéré dans la variable $newext_name.
Un petit echo avant cette commande permettra de poser une question à l’utilisateur. Par exemple :

echo ‘Veuillez taper quelque chose :’;
$newext_name = trim(fgets(STDIN));

Le contenu tapé par l’utilisateur sera récupéré dans la variable $newext_name.

En conclusion, si vous voulez des exemples pratiques de ces méthodes, téléchargez la dernière version de WAMP5 (1.5.0 à l’heure où j’écris ce post) et regardez ce qui se trouve dans le répertoire scripts ;-)



PHP 5.1 sous windows : où est passé sqlite?

    11:25 26 11 2005

J’ai passé une partie de ma journée d’hier à préparer et compiler WAMP5 1.4.6 avec la dernière release de PHP, la très attendue 5.1.

Au départ, tout me semblait normal, une mise à jour sans problèmes jusqu’à ce que je teste SQLitemanager et là, page banche!
Que se passe t’il? La dernière version de cette application (1.1.3) serait-elle bugée? Je mets donc le nez dans le code et là, je me rends compte qu’il ne s’agit pas d’un problème de SQLitemanager mais que tout simplement le support de SQLite n’est plus activé dans PHP 5.1.

Après un coup d’oeil à l’annonce de la sortie de PHP 5.1, je vois un lien vers un guide de mise à jour proposé sur le site php.net.

C’est dans ce guide que je découvre que le support natif de SQLite n’est plus activé par défaut et se base maintenant sur PDO :

http://www.php.net/README_UPGRADE_51.php#db3

Pour réactiver le support de SQLite natif, il faut donc activer PDO (qui bizarrement n’est plus activé par défaut dans cette version Windows alors qu’elle l’était dans les versions RC), activer le support SQlite de PDO puis activer l’extension php_pdo :

extension=php_pdo.dll
extension=php_pdo_sqlite.dll
extension=php_sqlite.dll

A noter que le driver SQLite est donc maintenant passé en version 3.



Premier point sur PHP6 par le PHP Group

    14:56 23 11 2005

Suite à la réunion d’une partie du PHP Group lors du forum PHP 2005 qui se déroulait à Paris (à noter que le PHP Group ne s’était pas réuni comme cela depuis 2000), une liste des fonctionnalités à prévoir pour PHP6 a été publiée par Derick :

compte rendu

Je n’ai pas encore eu le temps de tout lire, mais certains points semblent très intéressants… à suivre.



L’url rewriting sans mod_rewrite

    22:25 21 11 2005

Une des fonctionnalités puissantes du serveur web Apache est l’URL rewriting. Cela permet de remplacer des URL complexes du genre

mapage.php?var1=toto&var2=titi

par quelque chose de plus compréhensible pour les moteurs de recherche comme

toto_et_titi.php

L’intérêt principal est d’optimiser son référencement et donc d’avoir des pages mieux placées dans les résultats de recherches. Pour pouvoir utiliser ces fonctionnalités, il faut disposer du module mod_rewrite dans Apache.

Je disais donc, c’est très puissant, mais malheureusement, ce module n’est pas toujours disponible, et si vous n’êtes pas root du serveur, vous n’aurez sûrement pas la possibilité de l’installer.

Plusieurs astuces permettent toutefois d’avoir le même comportement sans pour autant utiliser le mod_rewrite.

Une des solutions consiste à se baser sur la directive FilesMatch d’Apache. Cette directive peut être utilisée localement dans un répertoire grâce à un fichier ‘.htaccess’. Elle permet d’associer un comportement particulier en fonction d’une contrainte définie grâce à une expression régulière. Oulla, par très clair tout ça. Pour simplifier,

« Si l’URL demandée correspond à cette contrainte alors appliquer ce comportement ».

L’idée est de rediriger l’appel vers un script php si un répertoire se trouve dans l’URL. En fait ce répertoire n’existe pas, par contre un fichier portant le même nom existe lui et contient du code PHP à exécuter.

Mmm, toujours pas clair? Bon passons aux travaux pratiques ce sera peut être mieux :

Je créé un fichier ‘.htaccess’ à la racine de mon site. Dedans je mets :

<filesmatch « ^formations$ »>
ForceType application/x-httpd-php
</filesmatch>

Maintenant, je créé un fichier formation (sans extension) et je mets du code PHP dedans. On pourra, par exemple, analyser l’url courante ($_SERVER['REQUEST_URI']) et faire un include en fonction de celle-ci.

Lorsque j’appellerais l’url http://monsite/formations/toto.php, c’est en fait le fichier formations qui sera exécuté en tant que PHP. Voilà, le tour est joué!

Vous n’avez toujours rien compris??? Mais vous êtes nuls! Je rigole bien sûr. Bon, je viens de trouver une page sur developpez.com qui explique la même chose (et bien d’autres choses) mais en mieux :D :

Solution en clair

J’utilise personnellement cette solution sur un serveur où je n’ai pas la main, ça marche très bien et me permet d’avoir de très bons résultats sur Google.



BONGA Power!

    21:13 20 11 2005

Ce week end, mon pote Florian a fêté ses 29 ans. Pour cette occasion, il a invité une dizaine de personnes (dont moi et Sandrine, ma copine) au concert de BONGA, un artiste angolais, qui se déroulait au Bataclan.

Ne connaissant pas cet artiste, je me suis dit que ce serait sympa mais que j’aurais sûrement un peu de mal à suivre et à rentrer dans l’ambiance. Que nenni mes amis, ce fut un de mes meilleurs concerts, un artiste bourré d’énergie, simple et très marrant; une musique pleine de bonne humeur; une ambiance de folie dans laquelle on ne peut qu’entrer et faire la fête! Je le recommande à tous, que du bonheur!

Au passage, deux des copines qui étaient avec nous sont montées sur scène pour souhaiter un bon anniv à mon pote, il savait plus où se mettre ;-)

Sinon, c’était aussi notre première nuit sans Adam qu’on avait confié à mes parents… ça fait bizarre et ça ne m’a pas empêché de me reveiller tout de même à 6h30. Quand on prends des habitudes…



Marre de Free!

    00:40 19 11 2005

C’est pas possible d’avoir une qualité de service aussi minable!
Après avoir suivi les péripéties de mes parents qui, suite à leur dégroupage total de Free se sont retrouvés pendant deux mois sans Internet ni téléphone (en fait jusqu’à leur souscription chez Wanadoo), j’ai tout de même décidé de courir le risque d’y passer à mon tour en septembre.
Le dégroupage se passe super bien, aucune coupure de service, sauf…
Bah oui, il faut bien qu’il y ait un ‘sauf’ ; après quelques vérifications, je me rend compte que mes débits sont passés de 100 Ko/s à moins de 40 Ko/s alors que j’étais sensé passer à quelque chose entre 250 et 400 Ko/s. Au passage, je perd le service télé pour cause de débits pas assez élevés…
que se passe t’il? Une maintenance du réseau? Attendons un peu.

Après quelques jours puis semaines d’attente, rien de nouveau, mes débits en upload sont toujours plus élevés qu’en download. Après un tentative d’appel (sans conviction) à la hotline aboutissant sur un message me disant de rappeler ultérieurement, je décide d’envoyer un mail au service technique en expliquant clairement mon problème. Deux jours après, je reçoit un mail type me disant de vérifier mon installation. Je décide donc de réécrire en leur précisant qu’avant le dégroupage tout allait bien, et donc qu’il ne pouvait s’agir d’un problème venant de chez moi, j’attends de nouveau deux jours et en retour…toujours le même message type sauf que maintenant j’ai consommé mon quota de messages et je ne peut plus leur écrire.

Mais qu’est ce que c’est que ce service clientèle de M….? Je trouve cela absolument intolérable. Quelle société traite ses clients de la sorte!
Je sais qu’il doit s’agir du 3 000 000eme message de ce type sur Free posté sur Internet, mais il fallait que le je fasse, juste pour me libérer.

Pour conclure, je crois que je vais aller chez la concurrence, plus chère, mais plus sérieuse. Juste par principe, je ne peut pas continuer à faire gagner de l’argent à une société aussi minable.



Windows au pays des Timestamps

    00:44 18 11 2005

Beaucoup de personnes pensent, à tort, que tous les développements PHP (ne faisant pas d’appels système) s’executent de façon identique sur Unix ou Windows. Un exemple des légères différences que l’on peut rencontrer est la getion des timestamps Unix.

Un timestamp Unix est une unité de mesure du temps. Il s’agit du nombre de secondes écoulées depuis le 1er Janvier 1970 à 0h00. Ce format à été crée, au début de Unix, afin de palier aux problèmes de mémoire qui, bien avant que l’on ait des pc avec 1 Go de RAM, était très limitée (à l’époque, la mémoire se mesurait en octets). Ainsi, les dates consommaient des espaces mèmoire très réduits en sachant pertinement que plus on avancerait dans le temps et plus l’espace necessaire grandirait mais également que la mémoire disponible sur les machines serait de plus en plus importante.

En partant de ce concept, on en déduit rapidement qu’il n’est pas possible d’exprimer une date antérieure à 1970 avec un timestamp à moins d’utiliser une valeur négative.

Or Unix (ou Linux) sait très bien gérer ces valeurs négatives. un exemple simple :

<?php

echo mktime(0,0,0,1,1,1969);

?>

Ce petit script, qui génère le timestamp du 1er Janvier 1969 à 0h00, sous Unix vous affichera

-31539600

Maintenant testez ce même script sous Windows. Voilà l’affichage que vous aurez :

Warning: mktime() [function.mktime]: Windows does not support negative values for this function in c:\wamp\www\test\timestamp.php on line 3
-1

Windows ne sait pas gérer les valeurs négatives de timestamps! Et ceci peut entrainer de très grosses incohérences sur vos développements.

Conclusion : si vous souhaitez faire des développements multi plateformes, pensez à tester régulièrement votre travail sur toutes les plateformes que vous souhaitez supporter afin d’éviter de mauvaises surprises de dernière minute.



Les short open tags

    09:13 14 11 2005

Une des options disponible dans le ficher de configuration de PHP, bien connu sous le nom de php.ini, est la possibilité d’activer (ou de desactiver) les short open tags :

short_open_tags = On (ou Off)

Les shorts open tags ont au départ été prévus…bah pour pas grand chose, tout simplement ouvrir son code PHP avec la balise <? au lieu d’utiliser la balise <?php. En soi, on pourrait se dire que cela est pratique, mais dans les faits l’utilisation des short open tags pose des problèmes.

En effet, les normes évoluent, le HTML est mort, vive le XHTML! Et avec cette nouvelle norme basée sur du XML, sont apparues de nouvelles balises. Il faudra nottament maintenant utiliser la balise <?xml version= »1.0″ …. pour ouvrir son document. Et c’est là que les short open tags viennent poser problème.
Avec les short open tags activés, un telle balise va être interprétée comme une ouverture de PHP, le code ‘xml version= »1.0″‘ va donc être parsé et générer une « syntax error ». Il ne sera donc pas possible de faire tourner des scripts au format XHTML sur un serveur ayant les short_open_tags activés.

La solution pour un code compatible va consister à utiliser les open tags traditionnels <?php et d’intégrer vos balises d’ouverture de fichier XHTML directement dans votre PHP sous la forme d’un echo :

<?php
echo ‘<?xml version= »1.0″ …..>’;
?>

De cette façon, votre code pourra tourner quelque soit la configuration de votre serveur :-)

J’en profite pour signaler que la dernière version de WAMP5 (1.4.5) est passée en short_open_tags à Off, ce qui a entrainé de nombreux posts sur le forum du site.