in unserem Shop werden bestimmte Aufrufe nicht vom Shopware-HTTP-Cache gecached. Ruft man beispielsweise eine Kategorieseite namens /natur/ auf, so erhält man in den Headern dieses Aufrufs auch bei mehrmaligem Aufruf hintereinander immer wieder folgende Debug-Information:
X-Symfony-Cache: GET /natur/: miss, store; GET /?action=shopMenu&controller=index&idSL=131&module=widgets&naSL=sCategory&vpSL=cat: fresh; GET /?action=info&controller=checkout&module=widgets: fresh
Es werden also zwar einige ESI-Aufrufe gecached. Der Cache funktioniert also grundsätzlich. Der Haupt-Aufruf wird jedoch nicht gecached. Entsprechend ändert sich auch der X-Content-Digest-Header bei jedem Aufruf.
Ich vermute, dass der Cache für den Haupt-Aufruf ständig invalidiert wird. Wie kann ich herausfinden, warum das geschieht?
Du könntest hier (shopware/Bootstrap.php at 5.5 · shopware/shopware · GitHub) ein kleines Logging einbauen Testweise. Um zu wissen welche Entitäten immer geleert wird und evtl. sogar direkt den debug_backtrace dumpen. Dann weißst du woher es kommt
um ein Log aller Cache-Invalidierungen zu erzeugen, habe ich inzwischen die Funktion invalidate() in der Datei /engine/Shopware/Plugins/Default/Core/HttpCache/Bootstrap.php wie folgt geändert:
/**
* Will send BAN requests to all configured reverse proxies. If cacheId is provided,
* the corresponding headers will be set.
*
* @param string $cacheId If set, only pages including these cacheIds will be invalidated
*
* @return bool True will be returned, if *all* operations succeeded
*/
private function invalidate($cacheId = null)
{
$logfile = "/htdocs/engine/Shopware/Plugins/Default/Core/HttpCache/logs/i".time();
if($cacheId)
$logfile .= "-".$cacheId;
$logfile .= ".txt";
$data = debug_backtrace();
$data = json_encode($data);
$data = stripslashes($data);
file_put_contents($logfile, $data);
$proxyUrl = trim($this->Config()->get('proxy'));
if (!empty($proxyUrl)) {
return $this->invalidateWithBANRequest($proxyUrl, $cacheId);
}
if ($this->get('service_container')->has('httpCache')) {
return $this->invalidateWithStore($cacheId);
}
// if no explicit proxy was configured + no host is configured
$proxyUrl = $this->getProxyUrl($this->request);
if ($proxyUrl !== null) {
return $this->invalidateWithBANRequest($proxyUrl, $cacheId);
}
return false;
}
Neu sind die ersten acht Zeilen am Anfang der Funktion. Da print_r u.ä. an dieser Stelle vermutlich wegen Output Buffering nicht funktionieren (vgl. PHP-Manual für print_r), lasse ich mir den debug_backtrace von json_decode in einen String umwandeln. Besonders gut lesbar ist das nicht, stripslashes entfernt zumindest die nervigen Backslashes. Es reicht allerdings, um zu erkennen, was genau den Cache invalidiert. (Bei uns war es ein selbstgeschriebenes Plugin, welches wir jetzt erstmal deinstalliert haben.) Vielleicht hilft dies ja in Zukunft nochmal jemandem.