drupal

Debian és Ubuntu szervereken a Drupal sessions tábla túl nagyra nő

Probléma: Ha Debian vagy Ubuntu szerveren futtatsz Drupal-t és a session kezeléssel kapcsolatos beállításokat nem állítottad át a php.ini-ben, akkor a Drupal sessions tábla soha nem lesz ürítve, ezért túl nagyra fog duzzadni, napról napra egyre jobban lelassítva a weboldaladat.

Megoldás: A Drupal settings.php-be szúrd be ezt a két sort:

<?php
ini_set
('session.gc_probability',   5);
ini_set('session.gc_divisor',       100);
?>

és esetleg finomhangold ezt a sort:
<?php
ini_set
('session.gc_maxlifetime',   200000);
?>

Egy másik megoldás, ha a .htaccess fájlba vagy az Apache virtualhost definícióba szúrod be ezt a két sort:
php_value 'session.gc_probability' 5
php_value 'session.gc_divisor' 100

Miért csak Debian alapú szervereken?

Nade mit is csinál ez a két sor és miért kell ezzel külön foglalkozni a Debian alapú szervereken?

Ahhoz, hogy megértsük a problémát, bele kell kicsit mélyednünk a Drupal lelkivilágába.

Nem csak az asztali gépemen fut Ubuntu, hanem szervernek is szívesen használom. Így vettem észre, hogy az f1vilag.hu oldalon, ami egy elég forgalmas site, a session táblában nagyon sok bejegyzés van. Hamar kiderült, hogy a táblából soha nem kerülnek ki a régi sorok, mindig csak az újak kerülnek beszúrásra.

Utánanéztem, hogy ez hogyan lehetséges, és egy kis keresgélés után kiderült, hogy a Drupal a sess_gc nevű függvényében ürítené a táblát. Az is hamar kiderült, hogy ezt a függvényt nem közvetlenül hívja meg a Drupal, hanem indirekt módon, a PHP-t kéri meg, hogy néha hívogassa ezt a függvényt, amikor a PHP azt jónak látja. Ezt egyébként úgy éri el a Drupal, hogy a session_set_save_handler függvény 6. paramétereként megadja visszahívandó callback függvényként a 'sess_gc'-t.

A PHP egy véletlen sorsolással dönt arról, hogy mikor kell meghívni a munkamenet szemétgyűjtőt, ismertebb nevén a session garbage collectort. A fent beállított értékek esetén, minden 100 oldalletöltés esetén átlagosan 5 alkalommal fog végrehajtódni a takarítás.

Ez mint szép és jó, de miért nem teszi ezt meg magától a PHP Debian alatt és miért teszi meg más rendszerek alatt? A választ megkapjuk, ha bepillantunk a php.ini ide vonatkozó részébe egy Ubuntu vagy Debian alatt:

; Define the probability that the 'garbage collection' process is started
; on every session initialization.
; The probability is calculated by using gc_probability/gc_divisor,
; e.g. 1/100 means there is a 1% chance that the GC process starts
; on each request.

; This is disabled in the Debian packages, due to the strict permissions
; on /var/lib/php5.  Instead of setting this here, see the cronjob at
; /etc/cron.d/php5, which uses the session.gc_maxlifetime setting below.
; php scripts using their own session.save_path should make sure garbage
; collection is enabled by setting session.gc_probability
;session.gc_probability = 0
session.gc_divisor     = 100

Debian alatt tehát ki van kapcsolva a php beépített session garbage collection funkciója, és helyettesítve van egy ütemezett feladattal (cronjob). Ami viszont csak annyit tesz, hogy a php session fájljait törölgeti félóránként. Ezért nem lesz soha meghívva a drupal sess_gc függvénye és ezért nő a sessions tábla a végtelenségig. A php.ini-ben, mint fent olvashattuk, nem is érdemes visszakapcsolni ezt a funkciót. Inkább a Drupal-ban állítsuk vissza ezt a funkciót, amelynek hatására már rendszeresen meg fog hívódni a sess_gc függvény és nem nő a végtelenségig a sessions tábla.

Subversion adattár böngésző WebSVN-nel és Drupal szintaxis kiemeléssel.

Drupal szintaxis kiemelés WebSVN alattBár a Drupal projekt CVS-ről GIT-re vált, azért még így is elég sokan vagyunk, akik verziókezelésre Subversiont használunk, a Drupal közösségen belül és kívül egyaránt.

Egy verziókezelő használata során nekem mindig szükségem volt valamilyen eszközre, amely vizuálisan ábrázolja a különböző verziók, branch-ek közötti eltéréseket, vagy egyszerűen csak böngészni lehet vele a verziókezelőben tárolt adatokat, azaz a repository-t.

A WebSVN egy jól bevált Subversion böngésző, amelyet most Drupal szintaxis kiegészítéssel fogunk fűszerezni.

Hozzávalók

Elkészítés

Bizonyosodjunk meg róla, hogy a telepített subversion szerver és a http szerver (pl. Apache) működik.

Töltsük le a subversion verzióhoz megfelelő WebSVN verziót. 1.4-es SVN felett már használható a legfrissebb, 2.3-as WebSVN. A subversion verziószámát így deríthetjük ki:

# svnadmin --version

WebSVN telepítés

A WebSVN telepítése gyerekjáték. Csomagoljuk ki a letöltött fájlt egy könyvtárba, ahonnan a webszerver majd ki fogja szolgálni. Majd kövessük a doc/install.html utasításait. Ez mindössze annyit fog jelenteni, hogy az include/distconfig.php fájlt le kell másolnunk include/config.php néven, majd ezt a fájl értelemszerűen szerkesztenünk kell.

A config.php fájlban meg kell mutatni a WebSVN-nek, hogy hol találja az svn repositorykat. Ehhez a $config->addRepository() vagy a $config->parentPath() megfelelő beállítása szükséges. A beállításhoz minden szükséges információ rendelkezésre áll a config.php fájlban megjegyzés formájában.

A WebSVN a repositorykat az svn és az svnlook parancsok segítségével fogja olvasni, úgyhogy ezek elérhetőek kell legyenek a path-ban webszerver felhasználó számára. Ha mégsem, akkor a config fájlban a parancsok pontos helye is beállítható.

A WebSVN futtatásához nem szükséges adatbázis. Ha eddig mindent jól csináltunk, akkor van egy működő WebSVN-ünk, próbáljuk ki!

Drupal syntax highlight

Az utolsó lépés a legérdekesebb, Drupal szintaxis kiemelőt fogunk beállítani a WebSVN-hez. Ehhez a Drupal GeSHi filter modulból fogjuk kölcsönvenni azt a fájlt, amelyik a Drupal függvények és konstansok definícióját tartalmazza.

Töltsük le és csomagoljuk ki a Drupal GeSHi filter modult. Mindegy hova, most épp nincs szükség telepített Drupal-ra. Keressük meg a geshifilter/geshi-extra/drupal6.php nevű fájlt (ha drupal 5 szintaxis kiegészítést szeretnénk, akkor a drupal5.php fájlt használjuk) és másoljuk át a fájlt a már telepített WebSVN lib/gheshi nevű könyvtárába. Ebben a könyvtárban vannak a programozási nyelvek leírói. Itt fogjuk megtalálni a perl.php-t, a php.php és 156 másik nyelv leíróját.

Legutolsó lépésként már csak azt kell elmagyarázni a WebSVN-nek, hogy mely fájlok esetén szeretnénk drupal szintaxis kiemelést látni. Ehhez nyissuk meg újra az include/config.php fájlt és bizonyosodjunk meg arról, hogy a $config->useGeshi() parancs nincs megjegyzésbe téve. Illetve szúrjuk be még ezt a sort:

<?php
$extGeshi
['drupal6'] = array('module','inc','install','profile','test');
?>

Ezzel elértük, hogy a module, inc, stb. kiterjesztésű fájlokat a drupal 6 nyelvűnek értelmezi a WebSVN és ennek megfelelő szintaxis kiemelést alkalmaz majd.

Ha mindent jól csináltunk, és megjelenítjük például egy drupal modul forráskódját (*.module) a WebSVN-ben, akkor a Drupal mag függvényei és konstansai kiemelten jelennek meg és link-ként viselkednek, amelyek az api.drupal.org-ra mutatnak. Emellett természetesen megmarad a PHP szintaxis kiemelés is, amely linkek viszont a php.net-re mutatnak.

A bejegyzés megírásához ezeket a verziókat használtam:
Subversion: 1.6.6 (r40053)
WebSVN: 2.3.1
GeSHi filter: 6.x-1.3

Az eredeti receptre Wim Leers blogján akadtam rá: http://wimleers.com/article/run-your...drupal-syntax-highlighting, köszönet érte!

Boost modul: a Drupal esete a statikus html oldalakkal.

A múlt heti bejegyzésben arról írtam, hogy egy gyors weboldal miért jelent versenyelőnyt a konkurenciával szemben. Kétféle sebesség probléma lehet, a kliens oldalon akkor van gond, ha a böngésző program nehezen vagy lassan jeleníti meg az oldalt. Szerver oldalon pedig akkor van gond, ha a böngészőnek indokolatlanul sokat kell várnia a szerverek válaszára.

A Drupal boost modul egy szerver oldali megoldás: az anonim felhasználók oldalletöltéseit teszi villámgyorssá.

Tisztán emlékszem a 2. Magyar PHP konferenciára, ott hallottam először a Drupalról. Abban az időben nagyon foglalkoztatott a weboldalak sebességének optimalizálása, azon belül is az előre legenerált statikus html oldalak kiszolgálásának voltam nagy rajongója. Fel is tettem a kérdést az előadónak, hogy a Drupal tud-e ilyet. Ha jól emlékszem, valami olyasmit válaszolt Goba, hogy az alap rendszer nem tudja, de biztosan készíthető hozzá ilyen modul.

Nos, hölgyeim és uraim, a Drupal boost modul egészen pontosan ezt csinálja: előre legyártott statikus html fájlokat szolgál ki az anonim felhasználóknak. Ezáltal teljes egészében kihagyva a buliból a PHP, Drupal, SQL stacket.

Ez a megoldás villámgyors oldal kiszolgálást eredményez, és egyben hatalmas tehertől szabadítja meg a webszervert. Persze vannak hátrányai is a megoldásnak, de előbb nézzük röviden hogyan működik.

A Boost modul működése

Először telepíteni kell magát a modult. Ez fog gondoskodni a statikus html fájlok mentéséről. Létre kell hozni egy „cache” nevű könyvtárat a Drupal telepítés gyökerében, ide fognak kerülni a html fájlok. Végül pedig a .htaccess fájlba be kell másolni egy nagy adag kódot, itt történik a varázslat: ez gondoskodik a html fájlok kiszolgálásáról.

A .htaccess fájlba másolt kód több különböző feltételt figyel, és ha mindegyik teljesül, akkor a Drupal index.php helyett az elmentett statikus fájl kerül kiszolgálásra. Ilyen feltétel például, hogy nem létezik a DRUPAL_UID nevű cookie, azaz hogy nem bejelentkezett felhasználó nézi az oldalt, vagy hogy GET kérésről beszélünk, és nem POST-ról.

Az eredmény: villámgyors oldal kiszolgálás az anonymous látogatók számára.

A cache fájlok érvénytelenítése

Ha egyszer elkészült egy oldalhoz egy statikus gyorstár fájl, és a fent említett feltételek teljesülnek, akkor az bizony ki lesz szolgálva. A kiszolgálás pillanatában ugyanis nincs lehetőségünk mérlegelni, hiszen nem fut le semmilyen Drupal vagy PHP kód. Éppen ezért alaposan oda kell figyelni, hogy mikor kerül érvénytelenítésre egy oldal gyorstár változata.

Először is, van egy beállítható felső idő határ. Ha ennél régebbi a cache fájl, akkor a boost törli az időzített feladatok (cron) segítségével.

Ha egy node oldalról beszélünk, akkor a node módosításakor is törli a cachet. Ha hozzászólás érkezett a node-hoz, szintén megy a cache a kukába. Ha egy node megkapja a „Promoted to front page”, azaz címlapra helyezés státuszt, akkor meg a kezdőlap lesz törölve. Persze ez csak a Drupal alapértelmezett kezdőlapjával működik. Ha saját kezdőlap megoldásunk van, és használni akarjuk a boost-ot, akkor nekünk kell gondoskodni a címlapi gyorstár törléséről.

A taxonómia lista oldalak fájljait is helyesen üríti a modul, amikor kell. Sőt elvileg CCK tartalomra hivatkozás mező használata esetén, ha változik a hivatkozás, akkor is helyesen törlődnek a megfelelő node gyorstárak.

Mindezeken felül persze lehet, hogy szükségünk lesz saját érvénytelenítő kódot is írni. Ha egyedi címlapot használunk, akkor mindenképpen.

Hátrányok

Az egyik hátránya a modulnak, hogy csak az Apache kiszolgálót támogatja teljes egészében. Márpedig maga az Apache is egy elég komoly lassító tényező, mint ahogy múlt héten egy hozzászólásban is írták. Elvileg nginx, lighthttpd és IIS7 használata is megoldható, többé kevésbé. Én ezeket nem próbáltam még.

A másik gond magából a módszerből adódik: mivel kikerüljük a Drupal-t, ezért az alaprendszerbe épített statisztika modul, illetve hasonló analitika megoldások egyáltalán nem fognak működni. Jelenleg egy nagyon izgalmas, saját fejlesztésű modulon dolgozom, amely azonban épít a Drupal mag statisztika megoldására. Ezért sajnos a kettő együtt nem működik.

Szintén a technológiából adódik, hogy a weboldal jobb és bal sávjaiban elhelyezett dobozok tartalma nem mindig frissül, és ezért Boost használata esetén néha furcsán inkonzisztens adatok jelennek meg. Illetve a véletlenszerűen változó dobozok, például 5 véletlenül kiválasztott fórum téma az elmúlt 1 hétből, sem úgy működik, mint ahogy kellene neki.

Mikor megnéztem a forráskódot, megdöbbenéssel tapasztaltam, hogy a Boost modul hatalmas! 280 KB-nál nagyobb a PHP kód mérete. Egyrészt azért ilyen nagy, mert sok kód kell az különböző cache fájl érvénytelenítési esetek kezelésére. Másrészt sok extra dolgot tud, talán feleslegesen is (lásd lent). És elég sok beállítási lehetősége is van. Egyszóval nagy és bonyolult modul, jobban örültem volna, valami egyszerű és nagyszerű megoldásnak.

Egyéb érdekességek

A Boost modul favorizálja a tömörített (gzip) kiszolgálást, méghozzá elég agresszíven. Állítólag némely proxy szerver felülírja a böngésző által küldött HTTP fejlécét, hogy ne fogadjob GZIP tömörített adatot. A modul egy trükkel (IFRAME-ben meghívott GZIP-pel tömörített oldalban lévő javascripttel beállít egy cookiet) megpróbálja kideríteni hogy az aktuális böngésző támogat-e gzip tömörítést, és ha igen, akkor az Accept-Encoding fejléctől függetlenül GZIP-el küldi az adatot.

Van egy beépített web robot is a Boost-ban. Annyit tesz, hogy cron futás alkalmával bejárja az oldalunkat (konfigurálható, hogy ezt hogyan tegye), ezzel előmelegítve a gyorstárat. Mikor van erre szükség? Ha olyan weblapot készítünk, amire várhatóan kevés oldalletöltés érkezik. Ekkor ugyanis a cache általában túl régi lesz, azaz a látogatók többnyire gyorstárazás nélküli oldallal találkoznak majd.

Konklúzió

Nagyszerű modul, ha az ember együtt tud élni a kötöttségekkel: Apache kiszolgáló, nem mindig frissülő dobozok és az anonim látogatói statisztika hiánya a Drupalban. Utóbbi miatt jelenleg én sajnos egyetlen oldalon sem használom. Persze ha egy szerverem nem bírná már a terhelést, akkor nyilván feltenném: inkább lássák a látogatók az oldalt és nekem ne legyen látogatottsági adatom, mint hogy ne is lássák :)

HtmlBox + Resizable Body - a sitebuilder barát WYSIWYG szerkesztő

A WYSIWYG szerkesztők a Drupalban egy örök téma. Több megoldás is van, de különbözőek az igények, különbözőek a funkciólisták és különbözőek az egyes megoldásokkal járó bug halmazok is :)

Aki esetleg nem lenne tisztában a fogalommal: a WYSIWYG a "What You See Is What You Get" rövidítése, és egyszerűen fogalmazva, ezek ügyes kis javascript eszközök, melyek segítségével úgy lehet szöveget (HTML-t) szerkeszteni egy böngészőben, mint pl. a Word-ben.

Személy szerint szeretek a HTML felett teljes uralommal lenni, ezért több kipróbált modul után, úgy döntöttem hogy, nem használok ilyen eszközt. Valahogy túl nagyok és böszmék voltak. Az volt az érzésem, mintha azt hinnék, nálam is jobban tudják hogy én mit akarok. Egyszóval nem volt jó az összkép. Egy Drupal felhasználói találkozón, még a corvintetőn, CHX ajánlott egy modult amit a NowPublic-kal közösen fejlesztettek ki.

A modul neve HtmlBox, hasonlóan a JavaScript eszközhöz, amin alapul. Anno kipróbáltam, de nem ment, nem tudom miért. Ma viszont adtam neki egy második esélyt és működik, ráadásul első ránézésre bíztató: egyszerű, nincs túlzsúfolva minden funkcióval, gyors, és teljes kontrollt ad a generált HTML kódon. Igaz ez utóbbit a többi hasonló megoldás is tudja, viszont nekem úgy tűnt (2 használat után!) hogy tisztább kódot generál. Elkezdtem hazsnálni, majd elválik mennyire jó.

Egy gondom volt vele: az alapesetben átméretezhető szövegdoboz már nem az, ha használjuk a HtmlBox-ot. Ez viszont nem jó, mert van aki szereti ha sok szöveget lát egyszerre. Pl. én.

De szerencsére erre van egy egyszerű megoldás a Resizable Body modul képében. Pofonegyszerű amit nyújt: meg lehet határozni hogy a node  szerkesztő oldalakon a body szövegdoboz hány sorból álljon. Ennyi.

A fenti két modul kombinációja  hasznos eszköz lehet egy sitebuilder kezében, vagy olyan szerkesztőnek aki nem fut anyuhoz sírva, ha meglát egy kis HTML kódot.

form_set_warning()

Vigyázat, ez az aktuális világmegváltó agyszüleményem! A Drupal Forms API előtt használtam néhány másis űrlap generáló rendszert is, de volt egy funkció, amivel soha nem találkoztam, pedig szerintem sok különböző weboldal hasznát venné.

Miután egy felhasználó kitöltöti, és a szervernek visszaküldi az űrlapot, ne csak azt lehessen eldönteni, hogy a kitöltés helye-e vagy sem, hanem legyen egy figyelmezetető, megerősítő funkció is. Úgy tudom elképzelni ezt a legjobban, hogy ha hiba helyett csak figyelmeztetést adunk ki egy mezőre, akkor az űrlap ugyanúgy megjelenik mint hiba esetén, kiemelve a problémás elemeket, de alul a submit mellett, lenne egy Igen, biztos ezt akarom checkbox. Ezt bepipálva már lefutna az űrlap _submit függvénye.

Miért van erre szükség? Azért, mert a hibás- nem hibás eldöntése túl nagy felelősség. Néha vannak veszélyes (vagy szinte bíztosan rossz) űrlap kitöltések, amelyeket nem szabad rögtön feldolgozni, de teljesen elvenni sem lehet egy ilyen kitöltésnek a lehetőségét.

Tengernyi konkrét példát tudnék mondani amikor erre szükség van:

  • Használtautó kereskedő oldal, az árat ezer forintban kell megadni. Erre a felhasználó beírja, hogy 150000. Persze lehet, hogy ez egy 150 milliót érő használt autó, de azért elég valószínűtlen. Jó lenne erre figyelmeztetni.
  • Klasszikus példa, és drupal-ban is számtalan helyen van, a törlés megerősítés (delete_confirm fg.) Ha lenne form_set_warning(), nem kellene plussz egy űrlapot definiálni minden egyes törlés funkcióhoz.
  • Linkeket akarunk tárolni. A http://www.example.com már bent van a rendszerben, mikor valaki hozzá akarja adni a http://example.com–ot, vagy a http://www.example.com/index.php-t.

Persze, most is el lehet érni ezt a funkcionalitást Drupal-ban (lásd delete_confirm), de csak hegesztéssel, egy form_set_warning-al sokkal elegánsabban meg lehetne oldani ezeket a helyzeteket. Ráadásul, amennyire ismerem a Forms API lelkivilágát, ezt nem is lenne túl nehéz beleimplementálni jól.

Kiváncsi vagyok a véleményetekre, nálatok is felmerültek már ilyen igények?

Oldalak

Feliratkozás RSS - drupal csatornájára