Lecza István (Isu)

My developer life, CV and others...

július 26 20:53:49, 2010

Ez a cikk a PEAR System_Daemon csomagjáról szól, ami egy már régóta (2008 május) létező, nagyon hasznos megoldás azokra a problémákra, amikor már nem elég adatokat időzített feladattal percenként feldolgoznunk, így a szimpla CLI PHP kevésnek bizonyolul, vagy amikor már nincs elég erőforrásunk futásidőbeli feldolgozásra.
Használjátok egészséggel és terjesszétek az igét.

MI az a daemon?

A daemon egy (pl.) Linux program ami a háttérben fut, mint egy szervíz Windows alatt. Végrehajthat olyan feladatokat, amik nem igényelnek közvetlen felhasználói beavatkozást. Az Apache és a MySQL is tulajdonképpen egy daemon.
Daemon-ok nélkül ennek a cikknek az olvasása sem lenne lehetséges. Világos tehát: a daemon egy kiválló megoldás különböző feladatok végrehajtására a legegyszerűbbektől a legbonyolultabbakig.

MIÉRT PHP?

A legtöbb daemon C nyelven íródik, leginkább a sebessége miatt, de ha LAMP környezetben mozogsz leginkább otthonosan, ahogy én is, és rengeteg alkalmazást fejlesztessz ezen a nyelven, akkor daemon írásakor is használhatsz PHP-t.
Érvek, amik a PHP mellett szólnak:
  • újrafelhasználhatóság, létező kód csatlakoztatása
  • gyors alkalmazásfejlesztés
  • a PHP-t mindenki ismeri, a C programozók pedig hamar elsajátíthatják, könnyen tanulható nyelv (ugye?)
Lehetséges felhasználási területek
  • weboldal optimalizáció
  • log parser
  • SMS daemon
  • videó, audio konverter
  • bármilyen adat utólagos feldolgozása
FÜGGŐSÉGEK, TELEPÍTÉS

A legújabb verzió (0.10.3) telepítéséhez minimum 5.1.2 vagy magasabb verziójú PHP szükségeltetik és egy 1.4.0 vagy újabb PEAR Installer. Opcionálisan telepíthető a PEAR Log csomogjának 1.0 vagy újabb verziója is, ami a /var/log -ba való logolást teszi lehetővé.

A telepítés:

pear install -f System_Daemon

EGY KOMPLEX, MAGÁÉRT BESZÉLŐ PÉLDA

#!/usr/bin/php -q
<?php /**
* System_Daemon turns PHP-CLI scripts into daemons.
*
* PHP version 5
*
* @category System
* @package System_Daemon
* @author Kevin <kevin@vanzonneveld.net>
* @copyright 2008 Kevin van Zonneveld
* @license http://www.opensource.org/licenses/bsd-license.php
* @link http://github.com/kvz/system_daemon
*/
  /**
* System_Daemon Example Code
*
* If you run this code successfully, a daemon will be spawned
* but unless have already generated the init.d script, you have
* no real way of killing it yet.
*
* In this case wait 3 runs, which is the maximum for this example.
*
*
* In panic situations, you can always kill you daemon by typing
*
* killall -9 logparser.php
* OR:
* killall -9 php
*
*/
  // Allowed arguments & their defaults $runmode = array( 'no-daemon' => false, 'help' => false, 'write-initd' => false, );   // Scan command line attributes for allowed arguments foreach ($argv as $k=>$arg) { if (substr($arg, 0, 2) == '--' && isset($runmode[substr($arg, 2)])) { $runmode[substr($arg, 2)] = true; } }   // Help mode. Shows allowed argumentents and quit directly if ($runmode['help'] == true) { echo 'Usage: '.$argv[0].' [runmode]' . " "; echo 'Available runmodes:' . " "; foreach ($runmode as $runmod=>$val) { echo ' --'.$runmod . " "; } die(); }   // Make it possible to test in source directory // This is for PEAR developers only ini_set('include_path', ini_get('include_path').':..');   // Include Class error_reporting(E_ALL); require_once 'System/Daemon.php';   // Setup $options = array( 'appName' => 'logparser', 'appDir' => dirname(__FILE__), 'appDescription' => 'Parses vsftpd logfiles and stores them in MySQL', 'authorName' => 'Kevin van Zonneveld', 'authorEmail' => 'kevin@vanzonneveld.net', 'sysMaxExecutionTime' => '0', 'sysMaxInputTime' => '0', 'sysMemoryLimit' => '1024M', 'appRunAsGID' => 1000, 'appRunAsUID' => 1000, );   System_Daemon::setOptions($options);   // This program can also be run in the forground with runmode --no-daemon if (!$runmode['no-daemon']) { // Spawn Daemon System_Daemon::start(); }   // With the runmode --write-initd, this program can automatically write a // system startup file called: 'init.d' // This will make sure your daemon will be started on reboot if (!$runmode['write-initd']) { System_Daemon::info('not writing an init.d script this time'); } else { if (($initd_location = System_Daemon::writeAutoRun()) === false) { System_Daemon::notice('unable to write init.d script'); } else { System_Daemon::info( 'sucessfully written startup script: %s', $initd_location ); } }   // Run your code // Here comes your own actual code   // This variable gives your own code the ability to breakdown the daemon: $runningOkay = true;   // This variable keeps track of how many 'runs' or 'loops' your daemon has // done so far. For example purposes, we're quitting on 3. $cnt = 1;   // While checks on 3 things in this case: // - That the Daemon Class hasn't reported it's dying // - That your own code has been running Okay // - That we're not executing more than 3 runs while (!System_Daemon::isDying() && $runningOkay && $cnt <=3) { // What mode are we in? $mode = '"'.(System_Daemon::isInBackground() ? '' : 'non-' ). 'daemon" mode'; // Log something using the Daemon class's logging facility // Depending on runmode it will either end up: // - In the /var/log/logparser.log // - On screen (in case we're not a daemon yet) System_Daemon::info('{appName} running in %s %s/3', $mode, $cnt ); // In the actuall logparser program, You could replace 'true' // With e.g. a parseLog('vsftpd') function, and have it return // either true on success, or false on failure. $runningOkay = true; //$runningOkay = parseLog('vsftpd'); // Should your parseLog('vsftpd') return false, then // the daemon is automatically shut down. // An extra log entry would be nice, we're using level 3, // which is critical. // Level 4 would be fatal and shuts down the daemon immediately, // which in this case is handled by the while condition. if (!$runningOkay) { System_Daemon::err('parseLog() produced an error, '. 'so this will be my last run'); } // Relax the system by sleeping for a little bit // iterate also clears statcache System_Daemon::iterate(2);   $cnt++; }   // Shut down the daemon nicely // This is ignored if the class is actually running in the foreground System_Daemon::stop();

A KÓD FUTTATÁSA

chmod a+x ./logparser.php
./logparser.php

LOG MEGTEKINTÉSE

tail /var/log/logparser.log



Azt hiszem, ez alapján érthető a működés, ha tévednék, akkor szívesen válaszolok hozzászólásokra is.

HOZZÁSZÓLÁS, VÉLEMÉNYEK

* Név
* E-mail
Weboldal, blog
* Hozzászólás
* Biztonsági kód
* A "Weboldal, blog" mező kivetélével minden mező kitöltése kötelező!