Linux демон на php5
Добър ден, днес ще опиша един доста забавен задача, на малко поле, пряко свързани с уеб-програмиране, а по-скоро създаването на демон в PHP. Ясно е, че на първия въпрос е: "Защо е необходимо?" Е, ние ще се занимава последователно.
Тя ще изглежда в действителност рядък перверзия пишат програми от този тип в езици като PHP, но това, ако е необходимо непрекъснато да следи процеса или продължително или редовен процес, и се нуждаят от малко skriptik. Като общо правило, на една ръка разстояние, не е компетентен професионален способен не се стреля в крака с C ++, или не, за да отреже крака си с помощта на C, добре, или просто един добър програмист приложение. В тези случаи, всеки върти, колкото можете и след това има голямо разнообразие на химери и хибриди, като използвате скриптове, за да set_time_limit параметър (0). скриптове, изстрелвани от работа Cron всеки втори (да, видях и т.н.) и други, не по-малко от шип неща.
Всъщност на формулирането на проблема. В хода на проекта е имало нужда от интеграция със софтуера комплекс на трета страна. Единственият начин да общува с programmulina - комуникация с помощта на собствената си протокол по мрежов порт, в очакване на началото на събитието, анализ на отговора, процес, запишете в базата данни. Тя ще изглежда, нищо сложно, пише skriptik с безкраен цикъл, във вътрешността на който ще се случи с всички необходими магията и готово! В началото, аз говорих за същото, но скоро става ясно, че този подход има голям недостатък, един от които е неверни данни, се появяват по време на смъртта на скрипта. рестартира сървъра и базата данни са данни, които не разполагат с време, нито процес или изтриване. Това е неприятно, много неприятно.
Е, нека се справят, ние имаме един класически LAMP на CentOS, едностранно softina и силно желание да не се връзвам всички други инструменти или така "дай Боже програмиране на С». Мислех, че ще бъде не е лошо, ако оригиналния сценарий може да се научи да разпознава сигналите, работещи в системата, така че да се изпълни своята задача коректно. За тези, които не знаят, в общи линии, Linux управлява процесите с помощта на сигнали, които разказват на процеса на това как той трябва да се държи. При получаване на такъв процес на сигнала трябва да променят поведението си и да направи нищо, ако тя не е необходима за неговото действие. Лично за мен, най-интересното сигнал SIGTERM. Този сигнал се посочва, че процесът трябва да приключи своята работа. Списък на всички съществуващи сигнали може да видите тук:
UNIX сигнали
Както има и друга функция, всеки процес в Linux, така или иначе, свързана с терминала, от която е стартирана и от едни и същи наследява потоци I / O на този, веднага след като затвори на терминала, който стартира скрипта той веднага допълва неговото изпълнение. За да се избегне подобна ситуация, е необходимо да се създаде процес на децата, за да стане основен и развързвам процес убие майка от останалите входове / изходи, в която е бил стартиран. Съгласен съм, че звучи сложно, объркващо и не е ясно, но на практика е много по-лесно, отколкото изглежда.
Това, което трябва да се работи? По принцип, не толкова, всъщност самата PHP, в моя случай, PHP5.6 и няколко подобрения:
Сега, когато имаме всичко, което ние трябва да се свежда до писане на код.
Както бе споменато по-горе, за да стартирате нашата демон, в съответствие с правилата на тези програми работят на Linux, е необходимо да се разграничи от терминала, където тя започва да направите това, използвайте функцията pcntl_fork (). тя създава едно дете копие на текущия процес и се връща своя цифров идентификатор в случай на успех. И разбира се убие процеса родител.
По този начин, операционната система ще знаят, че ние сме в състояние да определи собственото си поведение и да PID нашия процес в място за сигнали на системата.
Сега ние сме в очакване на най-интересните - трябва да се определи точно как работим и да си взаимодействат с операционната система. Реших да направя тази функционалност в отделен клас, в случай, че все още е необходимо на този код. Нека започнем, първо трябва да се определи, че този клас трябва да бъде в състояние да направи.
Получава и обработва сигнали на операционната система;
Бъдете в състояние да разберат дали демонът работи или не;
Изпълни задачата, колкото е необходимо за демонизиране;
Знайте кога да спре;
За постигането на тези цели е да се разбере функции, които да се окажат полезни. pcntl_signal () функция. Трябва да зададете функция на манипулатор за сигнала. Тя като свои аргументи: сигналът за който определя процесора и метод функция или клас е отговорен за обработка на сигнали. getmypid () функция. която връща ПИ на текущия процес. Накрая posix_kill () функция. изпраща сигнал към указания процес отнема два аргумента: PID на процеса, който искате да изпратите сигнал и към самия сигнал, който трябва да бъде изпратен.
За да се контролира състоянието на собствения си процес, ние се нуждаем от флаг, който ще се определи времето за прекратяване на процеса, или не. Като има някои тънкости, за да спестят ресурси на процесора, е необходимо да направите пауза, по време на която заявлението просто ще чакам за следващата итерация на цикъла, като по този начин не се отразява на система за постоянно заявката. Трябва да се определят тези параметри, като полета на класа.
Както можете да видите на метода приема като аргумент сигнал, който е изпратен до него, както и в зависимост от това, което се изпраща сигнал до демона извършва определени действия.
Сега трябва да разберете точно дали ни демон работи или не. Как ще го правим добре, защото демонът може да се стартира от друг терминал или няколко пъти. Ако няколко копия на един и същ скрипт ще се опитат да едновременно да отваряте едни и същи ресурси, мисля, че ще бъде изключително неприятно. За да се избегне тази ситуация, можем да използваме както старите, начина, по хълмове, в хода на програмата, за да създадете файл на едно място с записана програма за PID на процеса и го отстранете всеки път, когато нашата молба е затворен. По този начин се проверява за наличието на този файл, можем да знаем дали има течаща копие на заявлението. За да се реши този проблем, ние определяме метода на нашия клас.
Тук ние тестваме всички възможни сценарии, дали има файл, ако е така, какво процес, създаден, проверете дали има такъв процес, ако процесът е да създадете файл не съществува, тъй като процесът завърши неочаквано, опитайте да изтриете файла.
Това е време да се мисли, но как да всъщност prodelyvat същите тези операции, за които е замислена и всички? Има много варианти. В моя случай е било необходимо да се изчакат резултатите от услугите на трети страни, които не са произведени без тези данни процесът е безполезна и не се предприемат действия по съществуващите данни или ресурси, така че изпълнява всички обработката на функцията, която е получила или не е получила на услуга от данни на трети страни. Ако данните не е функция трябва да предизвиква толкова дълго, тъй като те не се появяват. Така написана Клас I метод, който реализира на полезния товар зависи от два параметъра: вътрешното състояние на демона и резултатите от функцията на обработка на данни от услуга на трета страна.
Така че аз имам две условно безкраен цикъл, интериор, който изчаква, докато функцията се изпълнява и външното, което чака, докато демонът за промяна на състоянието. Никой не казва, че изпълнението ми е най-правилното, прилагането на метода могат да се предефинират, тъй като е удобно, да не забравяме, за да следите дали времето на процеса, или не, за да завършите.
Сега идва кулминацията, трябва да изравни заедно и тичам, аз мисля, че е време да се напише конструктор за нашия клас.
Проверете дали е стартиран процеса с помощта на файла или не, ако използвате това показва предупреждение, задаване на закъснение, да възложат сигнални указатели (в този случай само един), създаване на файл и запис във PID, да знаят останалите копия на процеса знаят, че ние вече работим. С класа сме готови.
Сега ние се върнем към писането на демона скрипт. Останахме на завършени всички препарати за стартиране на обслужващата.
Свързваме всички библиотеки, които трябва, включително файл с нашия клас Daemon.php, описва функцията, която ще носи полезен товар, създаване на копие на демона клас с желаните параметри, губи стандартния вход / изход от сегашната терминал и пренасочване на тяхното да / сътрудничество / нула (ако би го направил и преди, тя е застрашена не, за да видите съобщенията за грешки по време на изпълнение на скрипта), peredaom тече Daemon метод клас, нашата функция, за да се извършва от демон.
Това е всичко. Нашата демон работи добре и комуникира с операционната система. Всички добре и късмет.