Considérez le scénario suivant: Nous avons une instance de travail AWS (basée sur SQS) qui ouvre des connexions MySQL persistantes à notre RDS.

$this->connectRegistry[ $host ][ 'connect' ] = mysqli_connect(
    "p:" . $host ,
    $this->hostCredentials[ $host ][ 'username' ] ,
    $this->hostCredentials[ $host ][ 'password' ]
);

Maintenant parfois - pas sur une base régulière - cet appel génère l'avertissement suivant:

Avertissement PHP: mysqli_connect (): le serveur MySQL a disparu

Étant donné que les instances de travail AWS traitent les demandes avec un serveur Web, la configuration est fondamentalement identique à une instance habituelle qui sert un site Web. Nous utilisons la même classe dans plusieurs projets, mais dans pas un seul site Web, cette erreur ne s'est même produite une seule fois.

Pour avoir une idée de l'origine de ces avertissements, nous avons essayé d'imprimer une trace de pile si une erreur de connexion se produit mais - et maintenant la chose gênante commence à arriver - il n'y a pas d'erreur de connexion. Veuillez jeter un œil à l'ensemble de la fonction de connexion:

private function connect ( $host )
{
    $this->connectRegistry[ $host ][ 'connect' ] = mysqli_connect(
        "p:" . $host ,
        $this->hostCredentials[ $host ][ 'username' ] ,
        $this->hostCredentials[ $host ][ 'password' ]
    );
    $error = mysqli_connect_error();
    if( $error ) {
        $this->raiseError( "Connect (" . mysqli_connect_errno() . ") " . $error );
        return false;
    }
    return true;
}

La méthode raiseError génère un message d'erreur complet avec une trace de pile et ainsi de suite, puis appelle trigger_error. Cependant, cette méthode n'est pas appelée si l'avertissement mentionné ci-dessus est déclenché.

Notre premier objectif est de savoir dans quels cronjobs ces avertissements sont déclenchés - peut-être y a-t-il des requêtes peu performantes.

0
viamuli 26 août 2020 à 10:27

2 réponses

Meilleure réponse

Il n'y aurait pas d'erreur de connexion si vous obtenez

mysqli_connect (): le serveur MySQL est parti

Ce message signifie que la connexion existante n'est plus utilisable. Quelque chose doit s'être produit et la connexion a été fermée par le serveur MySQL. Il peut y avoir plusieurs raisons à cela. Le plus courant est d'appeler mysqli_close() ailleurs dans votre code, mais comme vous utilisez des connexions persistantes ici, la cause principale pourrait être quelque chose de complètement différent. Vous devez déboguer la cause de la suppression de la connexion.

Cependant, Je recommande vivement de cesser complètement d'utiliser les connexions persistantes . Il est très peu probable que vous ayez une raison technique valable de les utiliser et leur débogage peut être très problématique.

1
Dharman 26 août 2020 à 10:24

J'ai eu ce genre de problème avec les démons php: lorsque vous démarrez votre démon, la connexion php est établie et s'il n'y a pas de requête pendant un certain temps, la connexion à la base de données s'éteint.

Dans le passé, j'ai trouvé deux solutions

  1. Pour maintenir la connexion active, effectuez une simple requête rapide toutes les n secondes
  2. Créez la connexion au moment de l'exécution, pas au démarrage du démon mais au moment où le démon fait le travail.

Je conseille le deuxième choix.

La connexion "persistante" ne signifie pas que la connexion vivra éternellement, elle est simplement réutilisée si vous utilisez le même nom d'utilisateur, mot de passe, etc. (doc), cela peut aider si vous utilisez la méthode 2)

0
Sergio Rinaudo 26 août 2020 à 09:00