Bonjour,

Je recontre un problème avec OPcache en local.
Voici ma configuration :

Serveur local EasyPHP 16.1.1 (dernière version)
PHP : 7.0.7 (dernière version stable)
OPcache :

zend_extension=php_opcache.dll
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.validate_timestamps=1
opcache.revalidate_freq=60
opcache.fast_shutdown=1
opcache.enable_cli=1

Quand je charge une page en local avec un appel à la base de données elle met un peu plus de 1s à charger, déjà cela je ne trouve pas sa normal mais j'ai vu que tout le monde a le même problème donc ce n'est pas le sujet.

OPcache est activé sur mon serveur (voir les paramètres de configuration au-dessus) et mon administration de OPcache (OPcache GUI) me dit que tous les fichiers de mon site sont bien mis en cache. Et je précise que les fichiers restent toujours en cache alors qu'ils sont censer être supprimé au bout de 1 minute.

Quand je réactualise mes pages le temps de chargement reste le même et quand j'ajoute un article depuis l'administration l'article apparaît bien alors qu'il ne devrait pas vu que le cache se recharge une fois toutes les minutes.

76 réponses


Huggy
Réponse acceptée

Si c'est uniquement un pb avec Mysql, configure Mysql pour écouter toutes les adresses IPV4 et IPV6 de ta machine
If the address is ::, the server accepts TCP/IP connections on all server host IPv4 and IPv6 interfaces. Use this address to permit both IPv4 and IPv6 connections on all server interfaces.
dans le my.ini rajoute bind-adress=::
ou bien
bind-address = 127.0.0.1
bind-address = ::1

http://superuser.com/questions/733571/bind-address-1-however-netstat-shows-0-0-0-03306-listening

je teste dès que j'ai un windows sous la main

Les fichiers sont revalidés toutes les minutes mais ils restent en cache, pourquoi veux tu qu'ils soient supprimés
le cache s'il est plein , sera purgé en supprimant les plus anciens
Tu ne dois pas confondre le cache d'Opcode (php) et le cache des données (tes articles)
le php n'est pas censé bouger en prod

D'accord mais cela devrait charger les pages plus rapidement, ce qui n'est pas le cas

C'est pour cela que je voudrais savoir pourquoi les performances sont les mêmes en local

dans Opcache GUI , quel est ton taux de hits ?
Les améliorations dues au cache sont surtout perceptibles sur de gros projets avec beaucoup de lignes de php.
Un projet qui fait des appels long à la BD sera moins impacté par le cache
Pour savoir ce qui coince, met des microtime() pour afficher les temps

Le taux de hits est de 94%, mes fichiers en PHP sont assez courts. Par contre est ce qu'il y a un intérêt de coupler le cache OPcode et le cache fichier en prenant par exemple memcached ?

Tu peux aussi utiliser le cache de requêtes de Mysql , il suffit de mettre SQL_CACHE après le SELECT
ça peut être intéressant pour les requêtes répétitives (liste des catégories, liste des articles ...)
SELECT SQL_CACHE * FROM categories;
en général une requête SQL simple qui ne ramène qu'un seul enregistrement s'exécute en 1ms

Par contre est-ce que tu sais pourquoi les requêtes SQL sont longues en local avec EasyPHP 1s pour afficher la page et en ligne c'est très très rapide ?

Tout dépend de la requête
si c'est une requête qui fait des regroupements sur des tables lourdes, il faut augmenter la taille des buffers.
il est aussi intéressant d'analyser les requêtes avec Explain
Explain select * from categories WHERE name='chouxfleur'
ça te dira si la requête utilise un index ou pas, si elle fait un scan complet (mauvais) ou quelles sont les clés possible pour la requête

La plupart du temps, c'est des requêtes SQL basiques SELECT ^^

Il n'y a pas grand chose dans la base de données, cela est juste pour faire des tests

à tester dans phpmyadmin
peut être aussi refaire les statistiques sur les tables
OPTIMIZE TABLE categories;

En fesant un OPTIMIZE je suis toujours a 1s1 pour charger en local et 100 ms sur un serveur mutualisé en ligne

Sans OPcache sur le serveur mutualisé car il ne me permet pas

Es-tu sûr que c'est Mysql ?

Oui je gère ma base de données avec PHPMyAdmin

Et les temps sous phpmyadmin sont mauvais ?

SELECT * FROM posts

Traitement en 0.0004 secondes.

Autant dire quasi instantané

fait la même chose en PDO et regarde le temps
quelle est ta chaine de connexion ?

Mon site web fonctionne avec PDO, qu'est-ce que tu appelles une chaine de connexion ?

la chaine de connexion c'est "mysql:host=localhost;dbname=mabase"
suivant que tu utilises localhost ou 127.0.01 le protocole ne sera pas le même

"mysql:dbname=$this->db_name; host=$this->db_host; charset=utf8", "$this->db_user", "$this->db_pass"

Dans le settings, tu dois savoir si c'est localhost ou autre chose

host c'est bien localhost si c'est ce que tu veux savoir

Je te conseille de faire une simple page qui interroge la db
et tu calcules les temps avec microtime
regarde ce qui coince, ça peut être la connection ou la requête en elle même
difficile de te dire sans voir exactement ce que tu fais

Le code est exactement le même en local que en ligne j'utilise dploy pour déployer sur mon site web.
Le temps avec la fonction microtime() change pas mal.
0.73432100 1466365612 ou des fois 0.07475000 1466365647

Le temps reste long sur une page vierge

<?php

$pdo = new PDO("mysql:dbname=alexisgarnier; host=localhost; charset=utf8", "root", "");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$req = $pdo->query("SELECT * FROM posts");
$datas = $req->fetchAll();

foreach ($datas as $data) {
    echo $data["title"]."<br/>";
}
echo microtime();

?>

tu dois afficher une différence de temps


$t0 = microtime(true);
....
echo "duree=" . (microtime(true) - t0);

duree=9.5367431640625E-7

J'obtiens cela

c'est inférieur à la précision de microtime, c'est très bon
lorsque tu dis atteindre 1s , comment le mesure tu (outils de dev du navigateur ?)

L'onglet Network de Google Chrome

La page met toujours 1s a charger avec le script

Donc selon toi c'est autre chose en local qui ralentirait la page ? Si je n'utilise pas la base de données le chargement des pages est très rapide.

as-tu apache bench (ab.exe situé dans les bin d'apache) ?
si tu l'as

>ab -n10 -c1 http://localhost/mapage.php

Si c'est un pb Apache, tu peux utiliser le serveur interne de php pour tester
php -S0.0.0.0

voir la dernière video de Graphikart sur le sujet

J'ai bien le fichier ab.exe ta commande s'éxécute en ligne de commande (cmd) ou php ?

oui ab, c'est en ligne de cde

'-n10' n’est pas reconnu en tant que commande interne

J'a oublier d'enlever le > ^^

Benchmarking localhost (be patient)...
Test aborted after 10 failures

apr_socket_connect(): Aucune connexion nÆa pu Ûtre Útablie car lÆordinateur cible lÆa expressÚment refusÚe. (730061)

Sa n'a pas l'air très bon à ce que je voit ^^

avec -n10 tu fais 10 requêtes http
et -c1 tu n'en fais qu'une à la fois (concurrency)
tu devrais avoir le temps total (à diviser par 10 pour avoir le temps moyen par requête)

Il me dit qu'il a fail 10 fois

J'ai refait le test et même résultat

Tu testes bien sur la page basique ?
si tu arrives dans le navigateur, tu devrais pouvoir l'interroger avec ab.exe

ha ok il faut être dans le dossier du fichier ?

Je suis dans le dossier où il y a ab.exe
C:\Program Files (x86)\EasyPHP-Devserver-16.1\eds-binaries\httpserver\apache2418vc11x86x160615141441\bin>

oui ça devrait marcher

C:\Program Files (x86)\EasyPHP-Devserver-16.1\eds-www>ab -n10 -c1 http://localhost/test.php
'ab' n’est pas reconnu en tant que commande interne
ou externe, un programme exécutable ou un fichier de commandes.

il ne connaît pas ab.exe du coup

En faites cela marche en remplaçant localhost par 127.0.0.1

C:\Program Files (x86)\EasyPHP-Devserver-16.1\eds-binaries\httpserver\apache2418vc11x86x160615141441\bin>ab -n10 -c1 http://127.0.0.1/test.php
This is ApacheBench, Version 2.3 <$Revision: 1706008 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient).....done

Server Software: Apache/2.4.18
Server Hostname: 127.0.0.1
Server Port: 80

Document Path: /test.php
Document Length: 201 bytes

Concurrency Level: 1
Time taken for tests: 10.306 seconds
Complete requests: 10
Failed requests: 0
Total transferred: 4030 bytes
HTML transferred: 2010 bytes
Requests per second: 0.97 [#/sec] (mean)
Time per request: 1030.608 [ms] (mean)
Time per request: 1030.608 [ms] (mean, across all concurrent requests)
Transfer rate: 0.38 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 1016 1031 14.9 1031 1063
Waiting: 1016 1031 14.9 1031 1063
Total: 1016 1031 14.9 1031 1063

Percentage of the requests served within a certain time (ms)
50% 1031
66% 1031
75% 1031
80% 1047
90% 1063
95% 1063
98% 1063
99% 1063
100% 1063 (longest request)

Ha je crois avoir trouvé mon problème en remplaçant localhost par 127.0.0.1 dans le nom d'hôte le chargement de la page est quasi instantanée 50ms

Ok c'est mauvais
Si tu copie/colle le résultat html de ta page, dans une nouvelle page statique test.html, (donc identique mais sans php)
quest ce que ça donne ?

Il faut regarder si cela vient d'Apache
peut être une config compliquée , un .htaccess

En tout cas en mettant 127.0.0.1 au lieu de localhost le chargement des pages est très rapide.

C:\Program Files (x86)\EasyPHP-Devserver-16.1\eds-binaries\httpserver\apache2418vc11x86x160615141441\bin>ab -n10 -c1 http://127.0.0.1/test.html
This is ApacheBench, Version 2.3 <$Revision: 1706008 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient).....done

Server Software: Apache/2.4.18
Server Hostname: 127.0.0.1
Server Port: 80

Document Path: /test.html
Document Length: 188 bytes

Concurrency Level: 1
Time taken for tests: 0.016 seconds
Complete requests: 10
Failed requests: 0
Total transferred: 4440 bytes
HTML transferred: 1880 bytes
Requests per second: 640.00 [#/sec] (mean)
Time per request: 1.563 [ms] (mean)
Time per request: 1.563 [ms] (mean, across all concurrent requests)
Transfer rate: 277.50 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 2 4.9 0 16
Processing: 0 0 0.0 0 0
Waiting: 0 0 0.0 0 0
Total: 0 2 4.9 0 16

Percentage of the requests served within a certain time (ms)
50% 0
66% 0
75% 0
80% 0
90% 16
95% 16
98% 16
99% 16
100% 16 (longest request)

avec PHP il me donne cela maintenant :

C:\Program Files (x86)\EasyPHP-Devserver-16.1\eds-binaries\httpserver\apache2418vc11x86x160615141441\bin>ab -n10 -c1 http://127.0.0.1/test.php
This is ApacheBench, Version 2.3 <$Revision: 1706008 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient).....done

Server Software: Apache/2.4.18
Server Hostname: 127.0.0.1
Server Port: 80

Document Path: /test.php
Document Length: 184 bytes

Concurrency Level: 1
Time taken for tests: 0.016 seconds
Complete requests: 10
Failed requests: 3
(Connect: 0, Receive: 0, Length: 3, Exceptions: 0)
Total transferred: 3911 bytes
HTML transferred: 1891 bytes
Requests per second: 640.00 [#/sec] (mean)
Time per request: 1.563 [ms] (mean)
Time per request: 1.563 [ms] (mean, across all concurrent requests)
Transfer rate: 244.44 [Kbytes/sec] received

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 0 2 4.9 0 16
Waiting: 0 2 4.9 0 16
Total: 0 2 4.9 0 16

Percentage of the requests served within a certain time (ms)
50% 0
66% 0
75% 0
80% 0
90% 16
95% 16
98% 16
99% 16
100% 16 (longest request)

c'est clair
maintenant si tu changes l'extension .html en .php

Sa donne cela je remarque que quand il y a que du html il y a 0 failed requests et un fichier php il y en a toujours 3 au minimum sur 10

C:\Program Files (x86)\EasyPHP-Devserver-16.1\eds-binaries\httpserver\apache2418vc11x86x160615141441\bin>ab -n10 -c1 http://127.0.0.1/test2.php
This is ApacheBench, Version 2.3 <$Revision: 1706008 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient).....done

Server Software: Apache/2.4.18
Server Hostname: 127.0.0.1
Server Port: 80

Document Path: /test2.php
Document Length: 188 bytes

Concurrency Level: 1
Time taken for tests: 0.000 seconds
Complete requests: 10
Failed requests: 0
Total transferred: 3900 bytes
HTML transferred: 1880 bytes

Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 0 0 0.0 0 0
Waiting: 0 0 0.0 0 0
Total: 0 0 0.0 0 0

Percentage of the requests served within a certain time (ms)
50% 0
66% 0
75% 0
80% 0
90% 0
95% 0
98% 0
99% 0
100% 0 (longest request)

les temps sont à 0 ?
Sinon pour la première page php, essaye de remplacer localhost par 127.0.0.1
c'est peut être ton localhost qui est mal configuré ?
que donne ping localhost (quelle ip)

Oui les temps sont bien a 0 c'est instantané ^^
C'est la configuration je pense mais comment le changer

C:\Program Files (x86)\EasyPHP-Devserver-16.1\eds-binaries\httpserver\apache2418vc11x86x160615141441\bin>ping localhost

Envoi d’une requête 'ping' sur ALEX-PC-FIXE [::1] avec 32 octets de données :
Réponse de ::1 : temps<1ms
Réponse de ::1 : temps<1ms
Réponse de ::1 : temps<1ms
Réponse de ::1 : temps<1ms

Statistiques Ping pour ::1:
Paquets : envoyés = 4, reçus = 4, perdus = 0 (perte 0%),
Durée approximative des boucles en millisecondes :
Minimum = 0ms, Maximum = 0ms, Moyenne = 0ms

ton localhost pointe sur une ipV6, c'est peut être ce qui gène Mysql
Sous Windows, si la connexion Mysql utilise le nom 'localhost' alors mysql n'utilisera pas tcp/ip mais les pipes nommés de Windows parcontre si tu mets une IP (même 127.0.0.1) alors la connexion se fera par le réseau tcp/ip (légèrement plus lent)

Et je peux changer ses paramètres comment ?

Modifie ta page de test.php en remplacant host=localhost par host=127.0.0.1 dans la chaine de connexion
Sinon tu devais éditer ton fichier hosts
et remplacer
::1 localhost
par
127.0.0.1 localhost
attention pour éditer le fichier \windows\system32\drivers\etc\hosts il faut les droits administrateur
donc ouvrir son éditeur en faisant "clic droit' executer en tant qu'administrateur

Il ne me laisse pas modifier le fichier en lançant Atom ou Notepad++ en mode administrateur

c'est l'ouverture ou l'enregistrement qui coince ?
avec Notepad, on ne voit pas le dossier etc
il faut taper etc\hosts

C'est l'enregistrement j'ai réussi à le modifier en fesant un chmod 777 au fichier mais la page remet 1s a charger "test.php"

Le ping fait la même chose :

C:\WINDOWS\system32>ping localhost

Envoi d’une requête 'ping' sur ALEX-PC-FIXE [::1] avec 32 octets de données :
Réponse de ::1 : temps<1ms
Réponse de ::1 : temps<1ms
Réponse de ::1 : temps<1ms
Réponse de ::1 : temps<1ms

Statistiques Ping pour ::1:
Paquets : envoyés = 4, reçus = 4, perdus = 0 (perte 0%),
Durée approximative des boucles en millisecondes :
Minimum = 0ms, Maximum = 0ms, Moyenne = 0ms

Il faut redémarrer le PC ?

As-tu essayé comme je te l'ai dis de modifier la chaine de connexion et passer par 127.0.0.1 ?

Le fichier par default contient :

# localhost name resolution is handled within DNS itself.
#   127.0.0.1       localhost
#   ::1             localhost

J'ai changer et mis cela :

# localhost name resolution is handled within DNS itself.
#   127.0.0.1       localhost
#   127.0.0.1       localhost

si tu ne retires pas les # les lignes restent en commentaire
tu n'as rien changé

Ba par default il y avait des commentaires et en les enlevant j'ai le même résultat

Je ne vois aucun changement en décommentant les lignes comment puis-je faire ?

Comment passer de l'IPV6 à l'IPV4 mon adresse locale (localhost) ?

Avec cette modification dans le fichier "my.ini", cela a l'air de fonctionner correctement.
URL : 127.0.0.1/mon-projet/ ou localhost/mon-projet/
Merci pour ces précieux renseignements et ta réactivité.

Par contre pour la connexion à la base de données il est indispensable de préciser que le nom d'hôte est localhost et non 127.0.0.1 sinon j'obtiens une erreur de la part de mon Controller Database.
Mais les sites en local fonctionnent bien en 127.0.0.1 comme en localhost