Maison >développement back-end >tutoriel php >Comment dépanner HTTP 500 : erreur de serveur interne avec php+redis dans les projets réels

Comment dépanner HTTP 500 : erreur de serveur interne avec php+redis dans les projets réels

墨辰丷
墨辰丷original
2018-05-26 15:17:051889parcourir

Le nombre d'utilisateurs a augmenté rapidement et le nombre de visites a doublé en peu de temps. Grâce à une bonne planification précoce des capacités, les ressources matérielles peuvent le prendre en charge, mais il y a un gros problème dans le système logiciel. : 40 % des requêtes renverront HTTP 500 : erreur de serveur interne

Description du problème
Le nombre d'utilisateurs a augmenté rapidement et le nombre de visites a doublé en une courte période de temps. En raison d'une bonne planification précoce des capacités, les ressources matérielles peuvent le prendre en charge, mais le système logiciel Un gros problème est survenu :
40 % des requêtes renverront HTTP 500 : erreur de serveur interne
En regardant les journaux, il a été constaté que l'erreur était dans le traitement de la connexion de PHP Redis
Gestion du débogage

La première fois
La racine la cause n'a pas été trouvée au début, nous n'avons donc pu essayer que diverses méthodes liées aux erreurs, telles que :
Ajouter un numéro de connexion PHP et augmenter le délai d'attente de 500 ms à 2,5 s
Désactiver default_socket_timeout dans les paramètres PHP
Désactivez les cookies SYN dans le système hôte
Vérifiez le nombre de descripteurs de fichiers dans Redis et les serveurs Web
Augmentez l'hôte Le mbuffer du système
Ajustez le nombre de retards TCP
...

J'ai essayé de nombreuses méthodes, mais toutes sont inefficaces

La deuxième fois
Je veux le faire à l'avance. J'ai essayé de reproduire ce problème dans l'environnement de publication, mais malheureusement, il a toujours échoué. Cela devrait être dû au fait que le trafic n'est pas assez important pour se reproduire

La troisième fois
Se pourrait-il que Redis ne soit pas fermé dans le code ?
Normalement, PHP fermera automatiquement la connexion aux ressources à la fin de l'exécution, mais il y aura des fuites de mémoire dans les anciennes versions. Par mesure de sécurité, modifiez le code et fermez la connexion manuellement
Le résultat est. toujours invalide

La 4ème fois
Cible suspecte : bibliothèque client phpredis
Faites des tests A/B, remplacez la bibliothèque predis et déployez-la auprès de 20 % des utilisateurs dans le centre de données
Grâce à la bonne structure du code, le travail de remplacement a été terminé rapidement
Mais le résultat est toujours invalide, mais il y a aussi un bon côté, qui peut prouver que phpredis est OK

La 5ème fois
J'ai vérifié la version de Redis et c'était la v2.6. La dernière version à l'époque était la v2.8.9
Essayez de mettre à niveau Redis, cela ne fonctionne toujours pas après. mise à niveau.
C'est bon. Restez optimiste. Ce n'est pas pratique. Mise à niveau de la version Redis vers la dernière

La 6ème fois
En recherchant beaucoup de documents, j'ai trouvé. une bonne méthode de débogage dans les documents officiels : Redis Software Watchdog, ouvrez-le et exécutez :

$ redis-cli --latency -p 6380 -h 1.2.3.4
min: 0, max: 463, avg: 2.03 (19443 samples)

Voir le journal Redis :

...
[20398] 22 May 09:20:55.351 * 10000 changes in 60 seconds. Saving...
[20398] 22 May 09:20:55.759 * Background saving started by pid 41941
[41941] 22 May 09:22:48.197 * DB saved on disk
[20398] 22 May 09:22:49.321 * Background saving terminated with success
[20398] 22 May 09:25:23.299 * 10000 changes in 60 seconds. Saving...
[20398] 22 May 09:25:23.644 * Background saving started by pid 42027
...

Problème détecté :
Enregistrez les données sur le disque dur toutes les quelques minutes, pourquoi faut-il environ 400 ms pour créer un stockage en arrière-plan (vous pouvez voir à partir du moment où des 1er et 2ème journaux ci-dessus)

Ici, enfin, la cause première du problème a été trouvée. Comme il y a une grande quantité de données dans l'instance Redis, il faut beaucoup de temps pour exécuter le processus en arrière-plan. à chaque fois que l'opération de persistance est effectuée. De plus, les clés sont souvent modifiées dans leur activité, ce qui entraîne des déclenchements de persistance fréquents, ce qui signifie que l'opération de persistance est souvent déclenchée. Blocage de Redis

Solution : utilisez un autre. esclave pour la persistance

Cet esclave ne gère pas les demandes de trafic réelles. Sa seule fonction est de gérer la persistance et de télécharger l'instance Redis précédente. L'opération de persistance est transférée à cet esclave

L'effet est très. évident et le problème est fondamentalement résolu, mais parfois une erreur est toujours signalée

La 7ème fois
Possibilité de dépannage En bloquant la requête lente de Redis, on constate que des clés sont utilisées quelque part *

Comme il y a de plus en plus de données dans Redis, cette commande provoquera naturellement de sérieux blocages

Vous pouvez utiliser scan pour la remplacer

La 8ème fois
Après les ajustements précédents, le problème a été résolu dans les mois suivants, même si le trafic a continué à croître, il a pu y résister

Mais ils ont réalisé qu'il y a un nouveau problème :

La méthode actuelle consiste à créer une connexion Redis lorsqu'une requête arrive, à exécuter quelques commandes, puis à déconnecter la connexion. Lorsque le volume de la requête est important, cette méthode produit de graves problèmes de performances, plus de la moitié. des commandes sont utilisées pour traiter les opérations de connexion, ce qui dépasse le traitement de la logique métier et ralentit Redis

Solution : introduisez le proxy, ils ont choisi le twemproxy de Twitter, il suffit d'installer un proxy sur chaque serveur Web, et twemproxy est responsable des connexions persistantes avec les instances Redis, ce qui réduit considérablement les opérations de connexion

twemproxy possède également deux fonctionnalités pratiques :

Prend en charge memcached
Peut bloquer les commandes très chronophages ou dangereuses, telles que les clés , flushall
L'effet est naturellement parfait, et vous n'avez plus à vous soucier des erreurs de connexion précédentes

La 9ème fois
Poursuivre l'optimisation grâce au partage de données :

Diviser et isoler les données dans différents contextes
Hacher de manière cohérente les données des fragments dans le même contexte
Effet :

Réduit Les requêtes et les charges sur chaque machine
améliorent la fiabilité du cache, et il n'y a pas lieu de s'inquiéter de la défaillance d'un nœud

Ce qui précède est l'intégralité du contenu de cet article, j'espère qu'il sera utile à l'apprentissage de chacun.


Recommandations associées :

Méthode PHP pour obtenir un nombre aléatoire à 6 chiffres qui n'existe pas dans redis

PHP implémente redisMéthode de publication de la file d'attente de messages Weibo

Opération du framework CI (CodeIgniter)redis Étape analyse

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn