2017-10-12 15 views
0

J'ai un problème assez particulier. J'ai un site web qui fonctionne sur un serveur ubuntu sous Apache2.4. Le site est écrit en PHP et utilise MySQL comme base de données. J'ai réalisé "stockage de fichiers" pour les petits fichiers dans la base de données MySQL comme longblobs.Le serveur/site Web Apache2 ne répond plus pendant le téléchargement

Lorsque je veux télécharger un fichier blob/fichier à partir de la base de données MySQL, j'ouvre une connexion PDO à la base de données.

$sql = $pdoData->prepare("SELECT * FROM fileblob WHERE ID = ?"); 
$sql->execute(array($blobID)); 
$row = $sql->fetch(); 
$content = $row['data']; 

via "echo $ content" Je transmets ensuite le fichier au navigateur. Tout cela fonctionne parfaitement. Toutefois. Pendant le téléchargement, l'ensemble du site ne répond plus, chaque nouvelle requête est expirée. Le téléchargement se poursuit correctement.

Lorsque le téléchargement atteint 4 Mo, le site Web redémarre, mais très lentement. Quand c'est fini, le site est complètement de retour à la normale.

La base de données MySQL utilise un back-end InnoDB, a un maximum de 500 connexions simultanées, etc.

Pendant le temps du téléchargement, il n'y a que 6 connexions SQL ouvertes. L'utilisation du disque est au maximum d'environ 20%, l'utilisation du processeur inférieure à 10% Apache est également configuré pour gérer 1k connexions simultanées (10 threads avec 100 enfants au maximum). Le serveur est connecté via une ligne 1Mbps non mesurée. Je ne peux pas penser à un goulot d'étranglement matériel.

Qu'est-ce qui me manque? Je suis heureux de répondre à toutes les questions ...

+0

Quelle est votre réglage de mise en mémoire tampon de sortie? Utilisez-vous des sessions PHP dans vos scripts? – CBroe

+0

@CBroe Oui, j'utilise des sessions PHP littéralement partout. Le tampon de sortie est réglé sur 4096 – user3829915

+0

_ "Le tampon de sortie est réglé sur 4096" _ - bien cela pourrait expliquer pourquoi vous voyez l'effet changer autour de 4MB ... essayez de le désactiver pour cette requête/partie du script. En outre, utilisez session_write_close dès que vous avez terminé la session. Dans le cas contraire, le verrouillage de fichier sur le fichier de données de session peut également maintenir les requêtes simultanées "suspendues". – CBroe

Répondre

0

Lorsque vous utilisez le mécanisme de session basé sur les fichiers par défaut de PHP, PHP verrouille le fichier de données de session pendant l'exécution de tout script accédant à cette session spécifique. Alors que votre téléchargement est en cours, le fichier de données de session est toujours ouvert et tous les autres scripts ne peuvent pas accéder à la même session - ils devront simplement attendre jusqu'à ce que le verrou du fichier soit à nouveau libéré. Pour éviter cela, session_write_close peut être utilisé. Il indique à PHP que le script actuel est fait avec la manipulation des données de session, de sorte que le contenu de la session peut être écrit dans le fichier de données maintenant, et le verrou de fichier libéré, afin que les autres scripts puissent y accéder à nouveau.

(Vous devez évidemment faire avec votre manipulation de données de session à ce stade;. Vous ne pouvez pas changer de nouveau contenu de la session dans le même scénario après)