Serveur Web Raspberry Pi – Raspberry Pi Cluster – Serveur d’impression
Une utilisation courante des ordinateurs Raspberry Pi consiste à créer des grappes. Les tartes aux framboises sont petites et peu coûteuses; il est donc plus facile de les utiliser pour créer un cluster que ce ne serait le cas avec les PC. Une grappe de tartes aux framboises devrait être assez grosse pour concurrencer un seul PC; vous aurez probablement besoin d'environ 20 Pies pour produire un cluster avec autant de puissance de calcul qu'un PC. Même si un cluster Pi n'est peut-être pas aussi puissant, c'est une excellente opportunité pour en apprendre davantage sur l'informatique distribuée.
Il existe différents types d’ordinateurs distribués qui peuvent être utilisés à des fins différentes. Il existe des super-ordinateurs utilisés pour résoudre des problèmes mathématiques tels que la modélisation des conditions météorologiques ou la simulation de réactions chimiques. Ces systèmes utilisent souvent l'interface MPI (Message Passing Interface). Une équipe de l’Université de Southampton a construit un superordinateur basé sur MPI à 64 nœuds. Ce système est utilisé pour enseigner aux élèves la superinformatique.
Hadoop est une autre technologie souvent utilisée dans l'informatique distribuée. Elle permet de distribuer des données sur plusieurs nœuds. Hadoop est souvent utilisé pour le traitement de grands ensembles de données et l'exploration de données. Un ingénieur chez Nvidia a construit un petit cluster Hadoop en utilisant des tartes aux framboises. Il utilise son cluster pour expérimenter et tester des idées avant de les déployer sur des systèmes plus puissants.
Sommaire
Utilisation d'un cluster Raspberry Pi en tant que serveur Web
Les clusters peuvent être utilisés comme serveurs Web. De nombreux sites Web génèrent trop de trafic pour s'exécuter sur un seul serveur, de sorte que plusieurs serveurs doivent être utilisés. Les demandes des navigateurs Web sont reçues par un nœud appelé équilibreur de charge, qui transmet les demandes aux serveurs de travail. L'équilibreur de charge transmet ensuite les réponses des serveurs aux clients.
Ce site est maintenant hébergé sur un cluster Raspberry Pi. Les nœuds de travail sont des serveurs Web standard ayant un contenu identique. Je viens d'installer Apache sur eux et de copier mon site sur chaque nœud.
J'utilise un Raspberry Pi supplémentaire pour héberger une copie de développement de ce site et pour contrôler le cluster. Ce Pi est connecté à mon réseau local via wifi, afin que je puisse accéder à la copie de développement de mon site depuis mon ordinateur portable.
Le Pi supplémentaire dispose également d’une connexion Ethernet au cluster Pi. Lorsque je souhaite mettre à jour mon site, je peux transférer les modifications du site de développement vers le site actif du cluster. Les mises à jour du site sont placées dans des fichiers .tar.gz que les nœuds de travail téléchargent automatiquement à partir du site de développement. Une fois téléchargées, les mises à jour sont ensuite décompressées dans le système de fichiers local.
Configuration des serveurs Raspberry Pi
Toutes les tartes dans ce système sont sans tête. Je peux me connecter au Pi avec le site de développement en utilisant le protocole Remote Desktop, et à partir de ce Pi, je peux me connecter aux travailleurs Pies en utilisant SSH.
Tous les Pies du cluster utilisent une adresse IP statique. Dans un cluster plus grand, il serait probablement préférable de configurer un serveur DHCP sur l'équilibreur de charge. Les adresses IP utilisées dans le cluster se trouvent sur le sous-réseau 192.168.1.xxx.
Pour chaque travailleur Pi, j'ai configuré une carte SD de 4 Go en utilisant la dernière version de Raspbian. Dans raspi-config, je définis les options suivantes:
- développer fs
- définir le nom d'hôte
- définir le mot de passe
- définir la mémoire partagée à 16 Mo pour le GPU
- overclocker le processeur à 800 MHz
- activer ssh
Sur chaque carte, j'ai installé Apache et certaines bibliothèques requises par mon CMS, libxml2 et python-libxml2. J'ai utilisé cette commande pour activer le mod rewrite, qui est également requis par mon CMS:
$ sudo a2enmod rewrite
Enfin, j'ai copié sur chaque carte SD des scripts qui permettent à chaque Pi de synchroniser son contenu avec le développement Pi. Dans un cluster plus grand, il serait intéressant de créer une image de carte SD avec toutes ces modifications effectuées à l’avance.
Construire un équilibreur de charge
L'équilibreur de charge doit avoir deux interfaces réseau, une pour recevoir les demandes d'un routeur et une autre interface réseau pour transmettre les demandes au cluster de serveurs. Les nœuds du cluster se trouvent sur un sous-réseau différent du reste du réseau. L'adresse IP de la deuxième interface de l'équilibreur de charge doit donc se trouver sur le même sous-réseau que le reste du cluster. La première interface de l'équilibreur de charge a l'adresse IP 192.168.0.3, tandis que l'adresse IP de la deuxième interface est 192.168.1.1. Tous les Pies du cluster ont des adresses IP sur le sous-réseau 192.168.1.xxx.
J'ai construit mon équilibreur de charge en utilisant un ancien PC doté de 512 Mo de RAM et d'un processeur x86 à 2,7 GHz. J'ai ajouté une deuxième carte Ethernet PCI et installé Lubuntu, une version allégée d'Ubuntu. J'allais installer Ubuntu, mais ce PC est assez ancien, donc Lubuntu est probablement un meilleur choix. J'ai utilisé un PC parce que je ne savais pas si un seul Pi serait assez puissant pour jouer le rôle d'équilibreur de charge, et un Pi ne dispose que d'une seule connexion Ethernet. Je souhaite que les deux connexions réseau de mon équilibreur de charge soient Ethernet afin d'améliorer les performances et la stabilité.
Notez que le transfert IP n'est pas activé. L'équilibreur de charge n'est pas un routeur, il ne doit transmettre que les requêtes HTTP et pas tous les paquets IP qu'il reçoit.
Configuration du logiciel d'équilibrage de charge
Il existe de nombreuses implémentations logicielles d'équilibrage de charge. J'ai utilisé le module d'équilibrage de charge d'Apache car il est facile à configurer. Tout d'abord, je me suis assuré que le système d'exploitation de mon PC était à jour:
sudo apt-get update
sudo apt-get upgrade
Puis j'ai installé Apache:
sudo apt-get install apache2
Ces modules Apache doivent être activés:
proxy sudo a2enmod
sudo a2enmod proxy_http
sudo a2enmod proxy_balancer
L'étape suivante consiste à modifier / etc / apache2 / sites-available / default afin de configurer l'équilibreur de charge. Le module proxy est nécessaire pour le transfert HTTP, mais il est préférable de ne pas permettre à votre serveur de se comporter comme un proxy. Les spammeurs et les pirates informatiques utilisent souvent les serveurs proxy d'autres personnes pour masquer leur adresse IP. Il est donc important de désactiver cette fonctionnalité en ajoutant cette ligne:
ProxyRequests off
Bien que les demandes de proxy soient désactivées, le module de proxy est toujours activé et agit en tant que proxy inverse. Ensuite, définissez le cluster et ses membres en ajoutant ce code:
BalancerMember http://192.168.1.2:80 BalancerMember http://192.168.1.3:80 BalancerMember http://192.168.1.4:80 BalancerMember http://192.168.1.5:80 AllowOverride None Ordre permettre, refuser permettre à tous ProxySet lbmethod = byrequests
Interface du gestionnaire d'équilibrage
Le module d'équilibrage dispose d'une interface Web permettant de surveiller l'état des serveurs principaux et de configurer leurs paramètres. Vous pouvez activer l'interface Web en ajoutant ce code à / etc / apache2 / sites-available / default:
SetHandler balancer-manager Ordre permettre, refuser autoriser à partir de 192.168.0
Il est également nécessaire de demander à Apache de gérer localement les demandes adressées à la page / balancer-manager au lieu de les transférer à un serveur de travail. Toutes les autres demandes sont transférées au cluster défini ci-dessus.
ProxyPass / balancer-manager! ProxyPass / balancer: // rpicluster /
Une fois ces modifications enregistrées, Apache doit être redémarré avec cette commande:
$ sudo /etc/init.d/apache2 restart
lorsque j'ouvre un navigateur et que je visite http://192.168.0.3, je vois la page d'accueil de mon site Web. Si je vais à http://192.168.0.3/balancer-manager, je vois cette page dans l'image à droite.
La dernière étape pour mettre le cluster en ligne consiste à ajuster les paramètres de redirection de port dans mon routeur. Je devais juste configurer une règle pour transférer les paquets HTTP vers http://192.168.0.3.
Voici l'intégralité de / etc / apache2 / sites-available / default pour l'équilibreur de charge:
Webmaster ServerAdmin @ localhost DocumentRoot / var / www Options FollowSymLinks AllowOverride All Options Index FollowSymLinks MultiViews AllowOverride All Ordre permettre, refuser permettre à tous ScriptAlias / cgi-bin / / usr / lib / cgi-bin / AllowOverride None Options + ExecCGI -MultiViews + SymLinksIfOwnerMatch AddHandler cgi-script .py Ordre permettre, refuser Autoriser de tous ProxyRequests OffBalancerMember http://192.168.1.2:80 BalancerMember http://192.168.1.3:80 BalancerMember http://192.168.1.4:80 BalancerMember http://192.168.1.5:80 AllowOverride None Ordre permettre, refuser permettre à tous ProxySet lbmethod = byrequests SetHandler balancer-manager Ordre permettre, refuser autoriser à partir de 192.168.0 ProxyPass / balancer-manager! ProxyPass / balancer: // rpicluster / ErrorLog $ APACHE_LOG_DIR /error.log # Les valeurs possibles incluent: debug, info, notice, avertir, erreur, crit, # alerte, émergent. LogLevel avertir CustomLog $ APACHE_LOG_DIR /access.log combiné
commentaires
Maintenant que j'ai construit un simple cluster de serveurs Raspberry Pi, il serait intéressant de voir combien de trafic il peut gérer par rapport à un seul Pi. Il existe de nombreux outils d'analyse comparative de serveur disponibles. Je vais utiliser le siège.
Utiliser Siege pour tester les temps de réponse du serveur
Siege est un programme qui peut être utilisé pour envoyer un grand nombre de demandes à un serveur Web. L’utilisation de la commande suivante enverra des requêtes HTTP à un serveur de mon réseau local:
siège -d10 -c10 -t1m http://192.168.0.10/spec.html
L'option -c spécifie qu'il doit y avoir 10 utilisateurs simultanés à la fois. L'option -d spécifie le délai maximum entre les demandes. Le délai réel est aléatoire, mais le sera dans le délai utilisé avec l'option -d. L'option -t indique au siège combien de temps le test devrait durer – 1 minute dans ce cas.
Dans chacun des tests que j'ai effectués, j'ai utilisé un délai maximum de 10 secondes et une durée totale de test de 1 minute. Tous les tests utilisaient le siège pour faire des demandes sur mon réseau local, pas via Internet.
Test de l'équilibreur de charge avec un seul Raspberry Pi
Je voulais voir comment un seul Raspberry Pi gère le trafic avec et sans l'équilibreur de charge. Je soupçonnais que l'équilibreur de charge introduirait un léger retard, mais en réalité, un seul Pi semble fonctionner plus efficacement lorsqu'il est derrière un équilibreur de charge. Il semble que les demandes soient mises en mémoire tampon avant d’atteindre le Pi. Ce graphique montre les temps de réponse moyens pour différents nombres d'utilisateurs simultanés, avec et sans l'équilibreur de charge:
Voir comment les performances s'améliorent avec plus de nœuds
Le test suivant que j'ai effectué a consisté à vérifier l'évolution des performances en fonction de l'ajout de nœuds au cluster. J'ai effectué des tests avec un nombre variable d'utilisateurs simultanés, mais pour des raisons de simplicité, je ne montrerai que les résultats des tests effectués avec 10 utilisateurs simultanés.
Ce graphique indique les temps de réponse maximum et minimum moyens pour un nombre croissant de noeuds de travail:
Comme vous pouvez le constater, le temps de réponse minimum ne s’améliore pas réellement car plusieurs nœuds sont ajoutés, ce qui est logique. Le temps de réponse minimum est aussi rapide que l'un des nœuds du cluster, et l'ajout de nœuds ne changera rien.
Le temps de réponse maximal s'est considérablement amélioré avec l'ajout de nouveaux noeuds. L'utilisation d'un cluster a nettement augmenté la capacité de mon serveur.
En savoir plus sur le siège.
commentaires
Dans mon dernier article sur les performances des grappes, je trouvais qu'une grappe fonctionnait mieux qu'un simple Pi, mais il restait encore beaucoup à faire. J'ai modifié les fichiers de configuration d'Apache et modifié le mode de fonctionnement de la mise en cache des pages dans mon CMS.
Déplacer le cache de la page
Le CMS que j'ai écrit peut générer des pages de manière dynamique et peut mettre en cache des pages afin qu'elles puissent être servies instantanément sans être assemblées. Seules les pages composées de HTML statique peuvent être mises en cache. Les pages contenant du contenu dynamique généré par des scripts exécutables ne sont pas mises en cache.
Le cache de pages se trouvait dans / usr / share / cms / cache. L'interpréteur Python devait être chargé pour servir les pages en cache à partir de / usr / share / cms / cache. Désormais, le répertoire racine du cache de pages est / var / www. Apache peut donc servir les pages en cache sans appeler Python pour exécuter le script CMS.
Un inconvénient est que le CMS ne peut plus compter le trafic de piste. Lorsque le CMS s'exécutait chaque fois qu'une page était demandée, une fonction était appelée pour incrémenter un nombre dans un fichier de données. Cela ne fonctionne pas maintenant que les pages peuvent être servies sans l'exécution du CMS.
Décharger les modules inutilisés
L'un des meilleurs moyens d'améliorer les performances d'Apache consiste à décharger des modules inutiles. Tout d'abord, vous devez répertorier tous les modules actuellement chargés à l'aide de cette commande:
apache2ctl -M
Il peut être difficile de déterminer quels modules sont utilisés. Cela dépend vraiment des directives utilisées dans les fichiers .htaccess et les fichiers hôtes virtuels. Par exemple, si vous désactivez authz_host_module, les directives Allow, Order et Deny ne fonctionneront pas. Chaque fois que vous désactivez un module, redémarrez Apache avec les commandes suivantes:
$ sudo service apache2 stop $ sudo service apache2 start
Vous pouvez utiliser 'redémarrer' au lieu de 'démarrer' et 'arrêter', mais certaines variables nécessitent l'arrêt d'Apache avant de pouvoir être mises à jour. Il est judicieux de tester votre site avant de désactiver d'autres modules. J'ai désactivé ces modules:
$ sudo a2dismod autoindex $ sudo a2dismod auth_basic statut sudo a2dismod $ sudo a2dismod dégonfler $ sudo a2dismod ssl $ sudo a2dismod authz_default
Si vous trouvez qu'un module est requis, vous pouvez le réactiver avec la commande a2enmod comme ceci:
$ sudo a2enmod authz_host
Réduire le délai d'attente
Je règle le délai d'attente dans /etc/apache2/apache2.conf sur 30. Cela évite que des requêtes simultanées n'occupent de la mémoire pendant de longues périodes et réduise l'utilisation de la mémoire.
Ajuster les processus Apache
Apache a plusieurs modèles de multitraitement différents. Ils utilisent chacun un nombre de processus serveur et de fils enfants pour gérer les requêtes HTTP.
MPM worker est la configuration la plus moderne. MPM prefork était auparavant la norme, mais MPM Worker offre de meilleures performances et une meilleure utilisation de la mémoire. Utilisez cette commande pour vérifier le mode dans lequel se trouve Apache:
$ sudo apache2 -V
Une partie de la sortie ressemblera à ceci:
Serveur MPM: Travailleur fileté: oui (nombre de threads fixe) forké: oui (nombre de processus variable)
Voici les paramètres par défaut pour MPM Worker:
StartServers 5 MinSpareThreads 25 MaxSpareThreads 75 ThreadLimit 64 ThreadsPerChild 25 MaxClients 150 MaxRequestsPerChild 0
La taille des processus Apache varie en fonction du contenu servi et des scripts éventuellement en cours d'exécution. Cette commande indique le nombre de processus Apache et leur taille:
ps aux | grep 'apache2'
La 6ème colonne contient la quantité de mémoire utilisée par chaque processus. En divisant la quantité de mémoire de secours par la taille du processus Apache moyen, vous obtenez une indication approximative du nombre maximal de processus serveur que vous pouvez exécuter. Chaque Pi de mon cluster a environ 280 Mo de RAM libre, et la taille moyenne des processus Apache est d’environ 7 Mo. 280 divisé par 7 donne 40.
StartServers est le nombre de threads de serveur créés par Apache au démarrage. La création de nouveaux processus de serveur peut prendre beaucoup de temps. Je souhaite donc qu'Apache démarre beaucoup de processus de serveur au démarrage. Cela signifie qu'il n'aura pas à passer du temps à créer plus de processus alors qu'il est occupé à traiter beaucoup de trafic. J'ai mis StartServers à 40.
Je ne veux pas qu'Apache puisse créer trop de processus, car mon Pi risque de manquer de mémoire, j'ai donc défini ServerLimit sur 40.
Chaque processus serveur peut avoir un nombre variable de threads. Ce sont les threads qui traitent réellement les demandes. J'ai fixé le nombre de threads par enfant à 8 par défaut. Je n'ai pas calculé cela, j'ai simplement essayé plusieurs nombres et effectué de nombreux tests avec siege jusqu'à ce que je trouve la valeur optimale.
Le nombre total de threads est le nombre de processus serveur multiplié par ThreadsPerChild, ce qui correspond à 320 avec mes paramètres. J'ai défini MaxClients sur 320 pour empêcher Apache de créer des threads supplémentaires.
Ces paramètres obligeront Apache à créer de nombreux processus et threads qui ne seront pas utilisés immédiatement. Afin d'empêcher Apache de les supprimer, j'ai défini MaxSpareThreads sur 320.
MaxRequestsPerChild est le nombre de demandes qu'un processus doit gérer avant d'être tué et qu'un processus de remplacement ne soit démarré. Ceci est fait pour empêcher les fuites de mémoire d'accumuler de grandes quantités de mémoire. Il doit être défini sur le nombre de hits qu'un serveur reçoit par jour afin que les processus soient redémarrés une fois par jour.
Les paramètres de MPM Worker sont maintenant
StartServers 40 ServerLimit 40 MinSpareThreads 25 MaxSpareThreads 320 ThreadLimit 64 ThreadsPerChild 8 MaxClients 320 MaxRequestsPerChild 2000
Avant de modifier le système de mise en cache, un test de siège avec seulement 25 utilisateurs simultanés a permis d'obtenir les résultats suivants:
Lever le siège du serveur ... c'est fait. Transactions: 30 hits Disponibilité: 100.00% Temps écoulé: 59.79 secondes Données transférées: 0,08 Mo Temps de réponse: 26.07 secondes Taux de transaction: 0.50 trans / sec Débit: 0.00 Mo / sec Accès simultané: 13.08 Transactions réussies: 30 Transactions échouées: 0 La plus longue transaction: 29.32 Opération la plus courte: 14.03
Après avoir amélioré le système de mise en cache, j'ai testé un seul nœud avec 200 utilisateurs simultanés à l'aide de cette commande:
$ siege -d1 -c200 -t1m http://192.168.0.4/specs.html
Les résultats ont été
Lever le siège du serveur ... c'est fait. Transactions: 6492 hits Disponibilité: 100.00% Temps écoulé: 59.28 secondes Données transférées: 38,86 MB Temps de réponse: 1,29 secondes Taux de transaction: 109,51 trans / s Débit: 0.66 Mo / sec Accès simultané: 141,10 Transactions réussies: 6492 Transactions échouées: 0 La transaction la plus longue: 11.23 Opération la plus courte: 0,32
Après avoir redémarré Apache avec les modifications de configuration et exécuté à nouveau le même test, j'ai obtenu les résultats suivants:
Lever le siège du serveur ... c'est fait. Transactions: 6449 visites Disponibilité: 100.00% Temps écoulé: 59.53 secondes Données transférées: 38,60 MB Temps de réponse: 1,31 seconde Taux de transaction: 108.33 trans / sec Débit: 0.65 MB / sec Accès simultané: 142.32 Transactions réussies: 6449 Transactions échouées: 0 La transaction la plus longue: 4.16 Opération la plus courte: 0.01
Après avoir optimisé la mise en cache des pages, supprimé les modules inutilisés d’Apache et optimisé le processus du serveur, le nombre de transactions par seconde pour un seul nœud est passé de 0,5 à plus de cent. Le nombre de demandes de connexion pouvant être traitées a été multiplié par 8.
Le réglage des processus Apache a entraîné une très légère diminution du nombre de transactions par seconde, mais le temps de transaction le plus long a considérablement diminué.
Tester l'ensemble du cluster
Une fois satisfait de mes nouveaux paramètres, je les ai transférés dans l'ensemble du cluster. J'ai fait plus de tests avec siege, d'abord avec 200 utilisateurs simultanés:
Lever le siège du serveur ... c'est fait. Transactions: 23218 hits Disponibilité: 100.00% Temps écoulé: 59.26 secondes Données transférées: 48,44 Mo Temps de réponse: 0.01 sec Taux de transaction: 391.80 trans / s Débit: 0.82 Mo / sec Accès simultané: 3,90 Transactions réussies: 23218 Transactions échouées: 0 La transaction la plus longue: 0,66 La transaction la plus courte: 0.00
… et ensuite avec 800 utilisateurs simultanés:
Lever le siège du serveur ... c'est fait. Transactions: 56899 visites Disponibilité: 100.00% Temps écoulé: 60.05 secondes Données transférées: 118,59 Mo Temps de réponse: 0.34 sec Taux de transaction: 947,53 trans / s Débit: 1,97 Mo / sec Accès simultané: 317.44 Transactions réussies: 56899 Transactions échouées: 0 La transaction la plus longue: 9.71 La transaction la plus courte: 0.00
Avant de paramétrer Apache, le cluster pouvait gérer 350 demandes simultanées et le taux de transaction maximal était de 460 transactions par seconde. Le nombre maximal d'utilisateurs simultanés avec un taux de réussite de 100% est désormais de 800. Le nombre maximal de transactions par seconde est maintenant de 947.
Je surveillerai attentivement la quantité de mémoire disponible au cours des prochains jours. Si le niveau commence à devenir trop bas, je vais réduire certains de ces paramètres.
L'utilisation du siège n'est pas complètement réaliste. Une demande émanant d'un navigateur impose au serveur une charge beaucoup plus importante qu'une demande émanant d'un siège, et la synchronisation des tests en état de siège diffère de celle du trafic réel. Les tests effectués en utilisant le siège ne prédisent pas le nombre de requêtes qu'un serveur peut gérer. Des tests comme ceux-ci fournissent une base de comparaison des différentes configurations de serveur. Je ne pense pas que mon cluster puisse gérer 947 visiteurs réels par seconde, mais je suis convaincu que les performances de mon serveur sont meilleures que celles enregistrées auparavant.
commentaires
Les temps de chargement des pages sont importants pour une bonne expérience utilisateur. Les gens sont plus impliqués avec les sites qui se chargent rapidement et visitent généralement plus de pages.
Pour que les pages se chargent rapidement, il ne suffit pas de rendre les serveurs Web plus rapides. Lorsque les navigateurs chargent des pages, ils doivent d’abord la télécharger à partir d’un serveur Web. Si la page fait référence à d'autres fichiers, tels que CSS, Javascript et images, le navigateur doit également récupérer ces fichiers. Une fois que tous les fichiers ont été téléchargés, le navigateur doit rendre la page. Les pages peuvent être optimisées pour que les navigateurs puissent les charger rapidement et efficacement.
Ce type d’optimisation ne concerne pas le réglage du serveur, mais l’optimisation des pages de votre site afin que les navigateurs puissent les charger facilement. Cela implique de passer du temps à ajuster le modèle HTML d'un site.
Google PageSpeed Insights est un bon endroit pour trouver des idées sur la façon d'optimiser votre site. Vous pouvez utiliser PageSpeed Insights pour analyser les pages d'un site et déterminer des moyens d'améliorer les temps de chargement des pages. PageSpeed Insights donne des suggestions détaillées sur la manière d'améliorer les performances. Un score de classement des pages est attribué à votre site, ce qui s’améliore à mesure que vous parcourez la liste des problèmes.
CSS en ligne
J'avais l'habitude de garder le code CSS pour mon site dans un fichier séparé dans /var/www/default_theme.css. Il a été référencé dans la section head de mon modèle HTML avec cette ligne:
Lorsque les navigateurs chargeaient les pages de mon site, ceux-ci ne pouvaient plus afficher cette page tant qu'ils n'avaient pas fait une nouvelle demande à mon serveur et téléchargé le fichier CSS. J'ai éliminé ce délai en incluant le code CSS directement dans la section head de mon modèle HTML. J'ai ajouté les balises suivantes à la section d'en-tête de mon modèle, puis ai collé le contenu de mon fichier CSS entre elles:
Cela agrandit chaque page Web, mais réduit le nombre de demandes que mon serveur doit traiter. Cela signifie également que les navigateurs peuvent rendre la page plus efficacement.
Javascript différé Chargement
Il est assez courant de référencer les fichiers source javascript dans la section head d'une page Web. J'avais l'habitude d'avoir la balise suivante dans la tête de mon site afin que les images puissent être visionnées à l'aide du plugin Javascript Lightbox:
Le problème, c'est que lorsqu'une page est téléchargée, le navigateur doit suspendre le traitement de la page pour télécharger le fichier Javascript. Cela interrompt le navigateur avant qu'il puisse commencer à afficher la page.
La solution consiste à déplacer les références aux fichiers Javascript "en dessous du pli". J'ai mis à jour mon modèle HTML pour inclure cette ligne juste après le pied de page plutôt que dans la section head. Lorsque les pages de mon site sont chargées dans un navigateur, la plupart des pages sont rendues avant que le navigateur ne doive obtenir le fichier Javascript.
Boutons de partage Javascript asynchrones
Les boutons de partage sont un excellent moyen d'augmenter le trafic sur votre site. Les visiteurs cliquent sur les boutons de partage pour partager votre site avec leurs amis et leurs abonnés sur les réseaux sociaux, augmentant ainsi le trafic généré par votre site à partir des réseaux sociaux. Il existe de nombreuses sociétés fournissant des plugins pouvant être ajoutés à un site. L'inconvénient de certains plugins de partage est qu'ils peuvent réduire la vitesse de chargement de la page en raison de problèmes liés à Javascript.
Au lieu d'utiliser un seul plug-in pour afficher les boutons de partage, vous pouvez utiliser des boutons de différents sites. Chaque réseau social possède ses propres boutons de partage que vous pouvez utiliser pour mettre des boutons de partage sur votre site. La plupart d'entre eux sont asynchrones (mais pas Reddit au moment de la rédaction). Les boutons asynchrones sont chargés après le rendu de la page, ce qui accélère son chargement.
Depuis que j'ai supprimé le plug-in de partage et que je l'ai remplacé par des boutons de partage individuels, les temps de chargement des pages affichés dans Google Analytics sont devenus beaucoup plus cohérents et beaucoup plus courts.
Minify CSS et Javascript
Les fichiers CSS et Javascript contiennent souvent beaucoup d'espaces, tels que des espaces et des caractères de nouvelle ligne. L'utilisation d'espaces permet de rendre le code plus lisible, mais ajoute également à la taille des fichiers. La suppression de caractères blancs rend le code illisible, mais peut considérablement réduire la charge de votre serveur. J'ai décidé de ne pas minifier mon code CSS car je veux pouvoir le lire, mais j'ai supprimé beaucoup d'espaces, tout en préservant un formatage de base. Voici à quoi ressemblait mon code CSS:
.navbar li affichage: en ligne; bordure gauche: noir 1px solide; padding-left: 6px; premier frontière gauche: aucune; .navbar li: premier enfant bordure: aucune;
Voici à quoi cela ressemble avec quelques espaces blancs supprimés:
.navbar li affichage: en ligne; bordure gauche: noir 1px solide; padding-left: 6px; premier frontière gauche: aucune; .navbar li: premier enfant bordure: aucune;
Le code Javascript peut également être minifié. Je n'ai pas l'intention de modifier le code Javascript, je l'ai donc complètement minifié. Il existe deux fichiers JavaScript que les navigateurs téléchargent sur mon site chaque fois qu'ils chargent une page, /js/lightbox.js, pour afficher des images, et /js/jquery-1.7.2.min.js. Le fichier jQuery est déjà minifié.
Le code de la visionneuse n’est pas minifié par défaut, je suis donc allé à cet outil de minifier Javascipt et
a collé le code de lightbox.js dans la zone de saisie et a appuyé sur le bouton d'envoi. J'ai créé un nouveau fichier dans / var / www / js appelé lightbox.min.js et ai collé la sortie de l'outil Minifier dans le fichier. J'ai modifié le modèle HTML de mon site afin de référencer ce nouveau fichier au lieu de la version non modifiée d'origine. La version non décomposée de ce fichier était de 11,6 Ko et la version agrandie de 6,2 Ko.
Tirer parti de la mise en cache du navigateur
Les navigateurs Web peuvent mettre en cache les pages de sorte qu'elles ne doivent plus être téléchargées si un utilisateur revient à une page déjà visitée. Vous pouvez indiquer aux navigateurs de mettre en cache des pages en envoyant un en-tête de contrôle avant que la page soit envoyée par le serveur. Cela nécessite quelques modifications à la configuration d'Apache. Tout d'abord, le module d'en-têtes doit être installé:
$ sudo a2enmod headers
Ensuite, le code suivant doit être collé quelque part dans /etc/apache2/apache2.conf:
Ensemble d'en-têtes Cache-control "public, max-age = 2592000" Ensemble d'en-têtes Cache-control "public, max-age = 604800"
Cela indique à Apache que tout fichier avec une terminaison .ico, .png, .gif, .jpg ou .js doit être mis en cache pendant 2592000 secondes (30 jours) et les fichiers avec une fin .html doivent être mis en cache pendant 604800 secondes (7 jours). . La dernière étape consiste à redémarrer Apache:
$ sudo service apache2 restart
J'ai exécuté cette commande sur un autre ordinateur pour m'assurer que la mise en cache fonctionnait correctement:
$ wget --save-headers http://raspberrywebserver.com/feed-icon-14x14.png
Lorsque j'ai ouvert le fichier téléchargé dans un éditeur de texte, ces en-têtes HTTP se trouvaient en haut:
HTTP / 1.1 200 OK Date: dim. 13 oct. 2013 à 01:24:25 GMT Serveur: Apache / 2.2.22 (Debian) Dernière mise à jour: mar. 01 oct 2013 à 03:40:50 GMT ETag: "226f0-2b1-4e7a5b80cb907" Accept-Ranges: octets Longueur du contenu: 689 Cache-control: public, max-age = 259200 Keep-Alive: délai d'attente = 5, max = 100 Connexion: Keep-Alive Type de contenu: image / png
L'en-tête de contrôle du cache est maintenant visible parmi les autres en-têtes HTTP.
Affichage de la synchronisation des pages Google Analytics
La capture d'écran de Google Analytics à droite montre comment les temps de chargement des pages se sont améliorés. Les temps de chargement des pages ont beaucoup fluctué lorsque j'utilisais un plug-in de partage, mais se sont stabilisés dès que je m'en suis débarrassé le 10 octobre. Au cours des prochains jours, le temps de chargement de la page a été réduit encore plus à mesure que je minifiais CSS et Javascript.
commentaires
Mon cluster de serveurs Raspberry Pi fonctionne depuis trois mois et dessert maintenant 45 000 pages vues par mois. La quantité de trafic
atteindre mon site est en augmentation constante et il existe parfois de fortes pics de trafic sur les sites de réseaux sociaux.
Au fur et à mesure que la charge sur le serveur augmente, il est important de vous assurer qu'elle dispose de suffisamment de capacité. J'ai donc décidé d'augmenter sa puissance de calcul en ajoutant quatre nœuds de serveur Raspberry Pi supplémentaires au cluster.
J'ai construit deux nouveaux racks, chacun contenant quatre serveurs Raspberry Pi. J'ai connecté en série deux commutateurs Ethernet, avec quatre serveurs Pi connectés à chaque commutateur.
J'ai cloné une carte SD à partir de l'un des nœuds Pi et mis en place quatre cartes SD presque identiques. La seule différence entre eux est l'adresse IP dans / etc / network / interfaces. J'ai fait une sauvegarde de mon site à partir du tableau de bord de mon CMS et ai utilisé un script pour synchroniser le contenu de tous les nœuds de travail.
L'étape suivante consistait à modifier les paramètres de l'équilibreur de charge pour pouvoir utiliser les nouveaux nœuds. Sur l'équilibreur de charge, il fallait mettre à jour / etc / apache2 / sites-available / default pour inclure les nouveaux nœuds dans la déclaration de cluster:
BalancerMember http://192.168.1.2:80 BalancerMember http://192.168.1.3:80 BalancerMember http://192.168.1.4:80 BalancerMember http://192.168.1.5:80 BalancerMember http://192.168.1.6:80 BalancerMember http://192.168.1.7:80 BalancerMember http://192.168.1.8:80 BalancerMember http://192.168.1.9:80 AllowOverride None Ordre permettre, refuser permettre à tous ProxySet lbmethod = byrequests
Une fois les modifications apportées, j'ai exécuté cette commande pour les charger dans Apache:
$ sudo /etc/init.d/apache2 reload
Cela indique à Apache de recharger ses fichiers de configuration sans redémarrer. Je suis allé à l'interface du gestionnaire d'équilibrage à l'adresse 192.168.0.3/balancer-manager pour m'assurer que les nouveaux nœuds avaient été ajoutés:
Essai
J'ai testé le nouveau cluster à huit Pi en utilisant les mêmes tests que lorsque je n'utilisais que quatre serveurs Pi. D'abord, j'ai utilisé seige pour générer 200 demandes simultanées en une minute:
$ siege -d1 -c200 -t1m http://192.168.0.3/specs.html Lever le siège du serveur ... c'est fait. Transactions: 23492 hits Disponibilité: 100.00% Temps écoulé: 59.81 secondes Données transférées: 48,93 Mo Temps de réponse: 0.01 sec Taux de transaction: 392,78 trans / s Débit: 0.82 Mo / sec Accès simultané: 3,81 Transactions réussies: 23492 Transactions échouées: 0 La transaction la plus longue: 0,63 La transaction la plus courte: 0.00
Le résultat est très similaire à celui obtenu pour le même test sur le cluster avec seulement quatre nœuds (voir 'Test du cluster entier').
Améliorer les performances du cluster en ajustant Apache).
Ensuite, j'ai lancé le siège avec 800 demandes simultanées:
Lever le siège du serveur ... c'est fait. Transactions: 76510 hits Disponibilité: 100.00% Temps écoulé: 59.76 secondes Données transférées: 159,39 MB Temps de réponse: 0,12 seconde Taux de transaction: 1280.29 trans / s Débit: 2,67 Mo / sec Accès simultané: 148.45 Transactions réussies: 76510 Transactions échouées: 0 La transaction la plus longue: 13.04 La transaction la plus courte: 0.00
Le temps de transaction le plus long a augmenté, mais le débit et le nombre de transactions par seconde ont également augmenté.
Les performances avec un faible nombre de demandes simultanées n'ont pas vraiment changé, mais les performances se sont améliorées pour un nombre accru de demandes simultanées.
demandes. Cela est prévisible, car l'ajout de nouveaux nœuds ne rend pas un cluster plus rapide, mais vise à augmenter la capacité du cluster.
J'ai été surpris que le temps pour la plus longue transaction a augmenté. La plupart des demandes sont traitées en 20 ms ou moins, et malheureusement, le siège ne fonctionne pas
enregistrer le temps de réponse moyen.
Les tests avec Apache Bench, ab, montrent que le temps de transaction le plus long était de 5,111 secondes, mais que le temps moyen de transaction était de 0,214 seconde.
L'augmentation du temps de transaction le plus long ne signifie pas que la performance globale est pire, mais c'est une source de préoccupation. Je me suis connecté à la charge
l’équilibreur à l’aide de ssh et a relancé les tests sur mon cluster. J'ai exécuté la commande uptime suivie de free sur l'équilibreur de charge:
$ disponibilité 13:30:04 up 1 day, 5:20, 1 user, load average: 9.27, 3.52, 1.33 $ free total used free shared buffers cached Mem: 498268 487188 11080 0 37328 299752 -/+ buffers/cache: 150108 348160 Swap: 513020 20 513000
The load average figures for the load balancer are much higher than for the servers. The load balancer only has 11MB of RAM left and has
started to use swap. When web servers start to use swap space, they slow down dramatically, so I need to look into the performance and memory
usage of my load balancer. Using siege to test with 800 concurrent users is testing for the worst case. At the moment my site isn't getting
that much traffic, so the performance issues with the load balancer aren't an immediate problem, but it's something I need to look at.
I still don't know how much traffic this system can actually handle because serving real traffic is not the same as testing with siege. je fais
know that my server can handle at least 45,000 hits a month, and probably a lot more now that I have added more nodes.
commentaires
Ever since I built my cluster people have been asking me why I used Apache and not Nginx. I started using Apache because I was just used to it. People say it's slow and takes up too much memory, but I find that with a little tuning it can perform quite well.
Still, Nginx does have a reputation for being fast. I wanted to see which web server would be best for my cluster, so I installed Apache on one Pi and Nginx on another.
I used two Raspberry Pi model B servers, each with identical Sandisk 4GB class 4 SD cards. In raspi-config, I overclocked each Pi to 800MHz, and allocated 16MB of memory to the GPU. I used the same version of Raspbian (released on 2013-09-25) on both servers. I used exactly the same test data and scripts on each Pi.
Follow this link to see how I set up Nginx and uWSGI.
I tuned Apache by removing modules and increasing the number of server processes. These tuning techniques don't apply to Nginx.
I tested each server with three different types of request: a static HTML file, a simple CGI script, and a complex CGI script. The HTML file is a cached page in my Content Management System (the CMS doesn't need to execute for cached pages to be served, they can be served by Apache as normal HTML files). The simple script just prints an HTTP header, prints "Hello World!" and exits.
The complex script used in these tests was the CMS that this site is built on. I disabled page caching on both Pi servers, so that pages had to be generated dynamically by the CMS. When a page is served, the CMS script has to parse two XML files to get meta data, read several snippets of HTML from the file system, and print them to a socket.
Requests were generated with Apache Bench using a command like this:
ab -n 1000 -c 250 http://192.168.0.21/spec.html
where 1000 is the number of requests to issue, and 250 is the number of concurrent users.
The Raspberry Pi running Nginx had IP address 192.168.0.21, and the Pi running Apache had 192.168.0.22. I tested each server over a range of concurrent users for each type of request.
Static files
Static files are easy to serve, so I used a range of 50 to 250 concurrent users in these tests. Apache handled 220 connections per second, while Nginx handled around 300 connections per second.
Nginx came out ahead on these tests.
Dynamic content tests
Simple script
In these tests I used ab to request this URL: http://192.168.0.21/cgi-bin/hello.py. I set the number of request to 100, and tested over a range of 10 to 50 concurrent users.
Apache handled 4.78 connections per second, and Nginx handled 4.65 connections per second, but the results showed that the mean transaction time was lower for Nginx than Apache, so Apache was slower in this test. The difference was not very pronounced under a low load, but it increased as the load increased.
Complex script
The URL used in these test was http://192.168.0.21/spec.html. This test is the most CPU intensive so I used from 5 to 25 concurrent users in these tests.
Under a low load, Apache's performance was slightly better than Nginx, but only by a very slim margin. With 25 concurrent users, Apache was slower than Nginx. The difference under a low load is negligible, but with 25 concurrent users, Nginx was noticeably faster than Apache.
Conclusions
There are many variables involved in server performance. These tests don't definitively determine which server is 'better', they just helped me decide which one is best for my specific needs.
Most of the pages on my site are static, and Nginx is faster when it comes to static pages. It looks like Nginx is a better choice for me.
commentaires
Commentaires
Laisser un commentaire