WARNING: LE PROJET EST ABANDONNE DEPUIS 2008
Lyceum est un projet dérivé de WordPress. C'est un concurrent direct à WordPressMU.
Il permet de créer un portail de blogs à partir d'une seule installation de code PHP et d'une seule base de données.
A la différence de WPMU qui crée un jeu de tables pour chaque blog, Lyceum a revu la gestion de la BDD pour garder un seul jeu de tables.
Pour pouvoir monter en charge avec des centaines, des milliers et même des centaines de milliers de blogs, il a fallu ré-écrire et optimiser la gestion des requêtes à la BDD MySQL.
WARNING
Dans Lyceum, les dossiers /uploads/ sont créés directement en sous-dossiers de /wp-content/blogs/BLOG_ID/uploads/
On a donc une limitation directe du filesystem à 32.000 sous-dossiers
L'avantage avec un seul jeu de tables, c'est d'éviter les limitations du système d'exploitation.
En effet, avec Linux, pour un dossier, le nombre de sous-dossiers est limité à 32768. Le nombre de fichiers contenus dans un fichier est théoriquement illimité (10 puissance je ne sais plus combien ? 30 ou 40 ?). En pratique, les performances du hash du système d'exploitation donnent un seuil pratique autour de 30.000 aussi.
En quoi est-ce cela impacte une application comme Lyceum ou WPMU ?
L'explication vient de MySQL: c'est une base de données qui construit un dossier par database et dans ce dossier, il y aura 3 fichiers par table.
Chaque database est dans un simple répertoire: ce qui limite le nombre de databases à 32768.
Un blog WPMU utilise une dizaine de table.
Pour WPMU, on tombe ainsi dans une limite pratique de 1.000 blogs, car cela créera autour de 10.000 tables et ainsi 30.000 fichiers dans le dossier de la database!
En n'utilisant qu'un seul jeu de tables pour tous les blogs, Lyceum va augmenter la taille des fichiers de manière énorme. Mais cet aspect est depuis longtemps bien géré par les systèmes d'exploitation. On n'a donc pas à s'en faire sur ce point.
Par contre, en mélangeant tous les blogs ensemble, le temps de recherche à chauqe requête devient trop long si on doit lire toute la table à chaque fois. Il faut donc utiliser des Index (en fait des tables de hachage) qui vont accélérer les accès aux données. Sur cet aspect, MySQL est bien armé pour gérer des tables avec des millions d'entrées. On reste donc dans le cadre d'une utilisation standard de MySQL.
Lyceum peut donc gérer des centaines de milliers de blogs sans buter sur les limites du système d'exploitation.
Au delà, il faut bien voir que pour un portail avec plus d'un millier de sites, ce seront les capacités du serveur en espace disque et en mémoire vive qui vont en prendre un coup. Il faudra alors de toutes façons migrer sur un système multi-serveurs. Dans cette optique, il y a alors des architectures à choisir dès le départ pour que la migration en soit pas trop douloureuse!
Pour tester un peu l'application, j'ai commencé par l'installer sur un PC…
En dézippant le source, on est assez surpris car la structure est plus complexe que WP. Il y a une structure de fichiers autour des fichiers WP habituels.
Il ne faut pas tout utiliser: il y a une partie de code pour le développement.
Il faut copier le dossier src et tous ses sous-répertoires.
Ensuite il faut trouver le fichier config/wp-config.php et le paramétrer. C'est un peu plus compliqué qu'avec WPMU…
Il faut bien sur renseigner les informations classiques pour MySQL.
Ensuite, il faut renseigner le dossier pour arriver à Lyceum depuis le nom de domaine.
En local, je change le nom de domaine à 127.0.0.1
Comme recommandé, je mets les logs à False pour éviter les erreurs en écriture.
Sur un PC, il faut écrire les noms de chemins avec un double \\ . Par exemple: C:\\tmp\\toto.txt
Ensuite, il faut ouvrir la page http://127.0.0.1/src/lyceum/wp-admin/install.php
J'ai une erreur … doit avoir les droits en écriture… Mais sans nom ? Bon, un tour dans le fichier install.php pour changer en clair le nom du fichier… C'est le répertoire wp-content/blogs/ qui doit avoir les accès en écriture! Mais ce dossier n'existe pas… Allez on le crée et puis voilà, le reste de l'installation passe tout seul: un titre et un mail et puis la base de données s'initialise toute seule.
Bon ça l'air prêt… PAF… impossible de se loguer ou d'accéder à la partie admin… une erreur 500 Internal Server Error se produit ? Il doit manquer une config pour Apache dans un .htaccess ou quelques chose comme ça avec les Rewrite Rules…
Je jette un coup d'oeil au fichier src/lyceum/.htaccess. Il est bien plus compliqué que celui de WPMU.
Il y a une redirection de /src/lyceum/login sur le wp-login.php
Ca doit être un problème de Rewrite Rules… En effet, j'utilise WampServer et le mod_rewrite n'était pas activé… Activation du mod_rewrite et re-démarrage de Apache…
Voilà! je peux me loguer et accéder à la partie admin! Youpi!
Le user admin n'a pas l'air de compter pour un user de lyceum.
Je dis ça parce que Lyceum dit qu'il faut créer un user avant de pouvoir créer un blog.
Et le seul moyen dans la partie admin est par un fichier batch. C'est super, mais pas d'interface pour une création un par un ?
Bon, je me délogue et j'essaie de créer un autre user avec un blog!
Bonne surprise, il y a un appel AJAX pour vérifier la disponiblité du nom de login. Je coche de me créer un blog en même temps. Et j'envoie! … Et Lyceum m'envoie aussi le mot de passe par mail! Comme d'habitude en local, il n'y a pas de serveur mail… Et Lyceum n'affiche pas le mot de passe…
On va ruser…
Les mails sont envoyés avec la fonction wp_mail. Il suffit de rajouter une trace pour garder le contenu du message dans un fichier.
Dans le fichier wp-includes/pluggable-functions, on trouve le code de la fonction wp_mail.
if ( !function_exists('wp_mail') ) : function wp_mail($to, $subject, $message, $headers = '') {
Il suffit de rajouter ces 2 lignes pour que chaque mail soit écrit dans un fichier.
if ( !function_exists('wp_mail') ) : function wp_mail($to, $subject, $message, $headers = '') { $toto="C:\\tmp\\toto.txt"; file_put_contents($toto, $message);
Ce code est très simple: le contenu du fichier est écrasé à chaque nouveau mail. Il est simple de l'améliorer pour conserver tous les mails envoyés…
if ( !function_exists('wp_mail') ) : function wp_mail($to, $subject, $message, $headers = '') { $toto="C:\\tmp\\toto.txt"; $past=file_get_contents($toto); file_put_contents($toto, $message.$past);
C'est pas complètement évident… Mais il y a des très bons points…
Quand on se logue, on arrive sur son profil général… Il faut se souvenir de son blog principal pour y aller et puis enfin accéder à la partie admin. De là, on a un lien vers tous les autres blogs qu'on possède…
Sur la page du portail, il y a les derniers articles et la liste des blogs du portail… C'est l'avantage d'avoir une seule base de données, ces informations sont naturellement accessibles!
A noter, pour se protéger des spams, Lyceum propose de changer le nom du fichier wp-comments-post.php en y ajoutant un suffixe crypté en md5. Ca donne alors quelque chose comme
wp-comments-post_c8930ca80ce74cec3a6822270883704e.php
Oui, c'est terrible comme je me mets vite à modifier les codes sources maintenant…
Le fichier system-admin/createusers.php est utilisé pour créer des utilisateurs à partir d'un fichier.
C'est très facile à modifier pour créer des boucles de création d'utilisateurs et de blogs.
Ca permet de tester la montée en charge de Lyceum…
Pour chaque blog créé, un répertoire d'uploads est créé dans le chemin
./wp-content/blogs/NUMERO_BLOG/uploads/
Malheureusement, sous Linux, le nombre de sous-dossiers dans un dossier est limité à 32768! (Dans mon cas, ça a été 32002 ?..)
L'erreur est situé dans ce fichier, ligne 232:
./src/lyceum/wp-admin/upgrade-schema.php
Au delà, les blogs sont bien créés, mais ils n'ont pas de dossiers pour leurs uploads de documents!
Il faudrait créer un hashage pour le nom des dossiers et créer une structure de sous-dossiers plus efficace…
le fichier /portal.php affiche par défaut tous les blogs.
Au dessus de 10.000 blogs, la page HTML retournée devient trop lourde à charger… Il faut alors limiter le nombre de blogs affichés.
Au delà de 50.000 blogs, c'est la requête MYSQL qui part en vrille… La page ne s'affiche alors plus du tout!
Il faut changer la requête:
$blogs = $wpdb->get_results("SELECT DISTINCT(id), slug, blogname, status FROM bloginfo ORDER BY blogname ASC");
en une requête plus simple et moins lourde:
$blogs = $wpdb->get_results("SELECT DISTINCT(id) FROM bloginfo");
Puisqu'on a moins d'informations, il faut aussi ensuite enlever la génération de code HTML pour l'affichage des liens vers les blogs.