Apache + RewriteMap + phpmap = egy idő után összekevert URL-ek

Fórumok

Hi,

OS: Ubuntu 14.04.x LTS
Apache: 2.4.7 később 2.4.17
App: saját felesztésű CMS + sok domain

Az a helyzet, hogy a CMS nem kezeli a redirect-eket (belső redirect: /akarmi --> /cucc, külső: egyik domain --> másik domainre), ezért erre anno írtak egy rewrite.php-t amit használ az Apache RewriteMap-pal.

Virtualhost config az Apache-ban:

<VirtualHost *:80>
...
RewriteMap phpmap prg:/path/to/rewrite.php
...
RewriteBase /
...
RewriteCond ${phpmap:%{HTTP_HOST}$%{REQUEST_URI}$%{QUERY_STRING}$%{HTTP_USER_AGENT}|NULL} !^(NULL|)$
RewriteRule .* ${phpmap:%{HTTP_HOST}$%{REQUEST_URI}$%{QUERY_STRING}$%{HTTP_USER_AGENT}|%{REQUEST_URI}} [R=301,L,NE]
...
</VirtualHost>

Igen, tudom, erre PHP-t használni nem a legjobb ötlet, de ez van. Készül már az új rendszer, azaz a mostanit nem fogják átírni, de addig valahogy ki kell húzni (legalább egy év).

A helyzet a következő:
Egy idő után (fél óra, 1 óra 2 óra, mikor hogy szerintem requestek számától függően) az Apache elkezdi összekeverni az oldalakat. Kattintgat a látogató a domain1.hu -n, de egyszer csak az egyik kattintásnál bejön a domain2.hu (az oldalletöltések kb 0,01%-a érintett) és ilyenkor a belső átirányítások sem mennek: domain1.hu/regioldal --> domain1.hu/ujoldal, viszont ha nyomok egy "sudo service apache reload" -ot, akkor egyből megjavul minden újra 0,5-1-2 óráig.

A hiba az Apache logban is látszik, a virtualhost oszlopban látszik a domain2.hu a referer oszlopban pedig a domain1.hu pedig nem vezet link a domain1.hu-ról a domain2.hu-ra. És az átirányítandó URL-nél 200-as HTTP-kód kerül a logba a 301 helyett, azaz valahogy nem illeszkedik a RewriteRule-ra.

A bejövő kéréseket a rewrite.php csekkolja egy adatbázisban és visszaadja az Apache-nak, hogy mit kellene vele kezdeni. Át kell irányítani valahova vagy kiszolgálni, esetleg már nem létezik. Ezt a php-t átnéztem, debuggoltam, stb, a lényeg, hogy 100%, hogy minden kérésre a megfelelő választ adja vissza az Apache-nek, ami úgy néz ki, mintha összekevernél az URL párokat (visitor kérés - rewrite.php válasz).

Második gondolatom az Apache lock volt, hátha nincs bekapcsolva, de ezzel is minden rendben látszik:
$ sudo apachectl -S | grep -i mutex
Mutex watchdog-callback: using_defaults
Mutex rewrite-map: dir="/var/lock/apache2" mechanism=fcntl
Mutex default: dir="/var/lock/apache2" mechanism=fcntl
Mutex mpm-accept: using_defaults

Eddig egyedül az apache reload-ot találtam megoldásnak, de azért elég ratyi dolog 5 percenként reload-olni az Apache-t :)

Olyan gondolatom támadt, hogy csinálok egy másik rewrite.php, ami percenként generál egy text alapú fájlt, ami tartalmazza a pár ezer redirect párt és azt adom be az Apache-nek (RewriteMap examplemap "txt:/path/to/file/map.txt" vagy RewriteMap examplemap "dbm:/path/to/file/map.dbm"), hátha az a baj az Apache-nek, hogy több milisec-et kell várnia, mint akarna és ez okozza a gondot, és hátha a text vagy dbm alapú megoldásnál ez nem jelentkezne.

1 hétig gyűjtöttem "LogLevel alert rewrite:trace5"-tel a rewrite logot, hátha abból kiderül valami is, de hiába gyűlt össze 5TB log, nem találtam benne hibát.

Valaki találkozott már ilyen problémával? Mit lenne még érdemes megnézni?

Előre is köszönöm az ötleteket! :)

Hozzászólások

Szia,

mindenképpen érdemes lenne prg RewriteMap-et kicserélni sima txt-re vagy dbm-re (legalább átmenetileg), hogy egyértelműen meg tudd állapítani, hogy az okozza-e a hibát.
Első körben az adott időközönként újragenerálás teljesen jó megoldás lehet, éredemes talán a dbm-et választani, mivel az helyben frissíti a fájl: "If the output file already exists, it will not be truncated. New keys will be added and existing keys will be updated."
Ha kiderült, hogy valóban ez okozza a hibát, akkor több lehetséges megoldás is van a finomításra, pl. egy INSERT/UPDATE adatbázis triggerel meg tudod oldani azt is, hogy valóban csak akkor generálódjon újra a fájl ha szükség van rá.
Illetve az Apache talán maga is ki tudja olvasni adatbázisból, amit kell: https://httpd.apache.org/docs/2.4/rewrite/rewritemap.html#dbd

Aztán ha ragaszkodsz a prg RevriteMap-hez, akkor miután sikerült izolálni, hogy valóban az okozza a gondot meg lehet keresni a programban a hibát.
A dokumentáció (https://httpd.apache.org/docs/2.4/rewrite/rewritemap.html#prg) elég jól leírja, hogy az Apache hogyan használja a fájlt és, hogy mire kell ügyelni.

♲♻♲