Автор Тема: PHP и сокети  (Прочетена 1837 пъти)

runtime

  • Участник
  • *****
  • Публикации: 805
  • Distribution: Ubuntu 14.04
  • Window Manager: Unity
  • LZ1DOT
    • Профил
    • WWW
PHP и сокети
« -: Май 20, 2015, 10:14 »
Здравейте,

Една консултация малка....

Та правя си една WEB система на PHP за отдаличен мониторинг на няколко (около 20) мои отдаличени услуги, която се връзва през сокети към тях, обаче всеки път при презареждане се изгражда нова свързаност, а поради лаг-а,  зареждането на страницата се забавя (20 услуги по 50 мс на услуга си е време, а ако някоя отпадне се бави още повече заради таймаута). Тъй като пиша ОО, се чудя дали да не нахакам обекта за връзка с отдаличените сървъри да се запише в сесията и а го чета от там? По този начин дори и при смяна/презареждане на страницата няма да се свързва наново към отдаличените машини.

Та някой правил ли е нещо подобно да даде малко акъл, кои са добрите практики в случая?
« Последна редакция: Май 20, 2015, 10:40 от runtime »
Активен

gat3way

  • Участник
  • *****
  • Публикации: 6050
  • Relentless troll
    • Профил
    • WWW
Re: PHP и сокети
« Отговор #1 -: Май 20, 2015, 11:29 »
Тези сокети не бива да ги отваряш от уеб приложението - ще си имаш огромни проблеми с такъв подход към нещата. Вместо това, изкарай всичко това да се прави в отделен демон, който не се изпълнява в контекста на уеб сървъра, а като отделен процес. Резултатите от проверките ги пиши в някаква база, а уеб приложението чете от базата и така. Ще си спестиш много главоболия така.

Сега демона пак може да си е написан на PHP, единствено трябва да се демонизира правилно - което не е ужасно сложно, но може да създаде малко главоболия, особено ако не знаеш добре какво става. Има няколко неща, които трябва да се направят - първата е да се форк-неш и в родителския процес да викнеш exit()  . Така child-а "осиротява" и започва да се води като "дете" на init процеса. След това викаш setsid() за да му създадеш нова сесия с неговата си процесна група. Ако искаш да пазиш логове от стандартен изход/стандартна грешка във файл - отвори файла за писане и с dup2() го "клонирай" върху stdout или stderr дескрипторите. Това е горе-долу базовото, другите неща колкото и да са културни, не са задължителни. Но е добра идея и да вземеш pid-а и да го запишеш в някакъв текстов файл - с идеята ако имаш initscript дето пуска/спира демона, да стават нещата по-лесно.


За всички тези неща има PHP функции, макар не много "популярни".

Алтернативно, може да не го демонизираш сам, а да ползваш nohup, но това е по-грозно според мен.
Активен

"Knowledge is power" - France is Bacon

runtime

  • Участник
  • *****
  • Публикации: 805
  • Distribution: Ubuntu 14.04
  • Window Manager: Unity
  • LZ1DOT
    • Профил
    • WWW
Re: PHP и сокети
« Отговор #2 -: Май 20, 2015, 11:49 »
Ами и аз си го помислих като вариант, но ще си има и възможност за управление на отдаличените услуги, та затова... Принципно ползвам Laravel 5 фреймуорка и ам има възможност да ползвам cron и services ама се позачудих как да стане... Е щом казваш може да се позамиля да го изведа на отделно приложение и да му направя някое restfull api през което php да се връзва и чете/изпраща.
Активен

gat3way

  • Участник
  • *****
  • Публикации: 6050
  • Relentless troll
    • Профил
    • WWW
Re: PHP и сокети
« Отговор #3 -: Май 20, 2015, 12:28 »
Мммхм, вече как ще си "комуникират" е според как на теб би ти било най-лесно. RESTful API за демона обаче няма да е толкова просто начинание според мен - понеже ще трябва в този случай да функционира като уебсървър. Уеб съръвър да си напишеш на php няма да е много лесна работа. Аз лично бих ги оставил да си "говорят" през базата - демона пише вътре, уеб приложението съответно чете, просто защото е доста по-лесно. Но пък знам ли, всичко е относително в крайна сметка.
Активен

"Knowledge is power" - France is Bacon

d0ni

  • Участник
  • *****
  • Публикации: 183
    • Профил
Re: PHP и сокети
« Отговор #4 -: Май 20, 2015, 17:38 »
PHP има вграден уеб сървър, макар че е по-скоро за тестове (http://php.net/manual/en/features.commandline.webserver.php)

Цитат
  -S <addr>:<port> Run with built-in web server.


ПС. може би ще ти е най-просто да направиш 20те ти connection-а неблокиращи и после да ги poll-неш докато не ти репортнат, че са ок или докато не мине някакъв таймаут (1 секунда, например). Така връзките ти няма да вървят серийно, а паралелно - т.е. ще отнемат в идеалния случай общо 50 мс за проверките, а не 20х50. А при недостъпност на някоя услуга ще се забави само 1 секунда (или колкото ти е там таймаута на poll-а).
Активен

gat3way

  • Участник
  • *****
  • Публикации: 6050
  • Relentless troll
    • Профил
    • WWW
Re: PHP и сокети
« Отговор #5 -: Май 20, 2015, 17:54 »
Не, дори да са неблокиращи е лоша идея да се прави от уеб приложението, поради ред причини. Като например единственият прозорец от време за което знаеш дали мониторираните услуги работят или не е докато достъпеаш уеб приложението, през останалото време дали работят или не е божа работа. Демонът може да ги логва такива събития в реално време, да праща нотификации по желание и всякакви подобни неща. Друг е момента, че това не е особено скалируемо решение - като нарасне бройката на мониторираните услуги, рано или късно пак ще стане тегаво да го правиш така, дори с non-blocking сокети и poll/select/нещоотсорта върху тях. И накрая, при достатъчно голям брой мониторирани неща се отваря прилично поле за изява на елементарни DoS атаки - от сорта на някой идиот да тръгне да набива F5 като изоглавен, резултатът ще е доста неприятен.
Активен

"Knowledge is power" - France is Bacon

runtime

  • Участник
  • *****
  • Публикации: 805
  • Distribution: Ubuntu 14.04
  • Window Manager: Unity
  • LZ1DOT
    • Профил
    • WWW
Re: PHP и сокети
« Отговор #6 -: Май 21, 2015, 00:41 »
Еми спрях се на варианта с трислойната архитектура :)  MySQL БД <=>  Python демон  <=> PHP Front-end
Или инак казано почнах така както го и мислих първоначално, но не ми се правеха три неща :) Но от друга страна ще ми улеснят животеца... Инак става дума за отдаличен мониторинг на няколко микротика и изпращането на две-три команди през API-то :)

Благодарско за отговорите.  [_]3
« Последна редакция: Май 21, 2015, 00:43 от runtime »
Активен

edmon

  • Гост
Re: PHP и сокети
« Отговор #7 -: Май 21, 2015, 08:54 »
Колко е най-малкото време, за което се очакват промяна в изследваните параметри?
Тоя демон дет ше го напющиш на колко време ще запитва микротиците ?
Щот видях кой туй МикротикАПИ и ако мислиш да следиш стойности на интервали над 1 мин .
Можеш наистина да направиш от ПХП-то без демони.
Само ще си записваш в куки последното време на рефреш така , че дори некой да натиска F5 до безкрай да не става ненужните заявки към микротиците, ако не ти е дошло времето. т.е. в куки мое запишеш времето на последната успешна заявка и да броиш ако това време не е това, което ти се иска да не се изпълняват запитванията по портовете на микроиците :))
А ако времето е около 5мин може пък в крон да сложиш дори и пхп скрипт, който да ги обхожда, да събира информацията и там вече си знаеш.
Овчо взето демон ти трябва , ако времената на запитванията е по-малко от минута.
« Последна редакция: Май 21, 2015, 08:56 от edmon »
Активен

gat3way

  • Участник
  • *****
  • Публикации: 6050
  • Relentless troll
    • Профил
    • WWW
Re: PHP и сокети
« Отговор #8 -: Май 21, 2015, 10:02 »
Може и с cronjob, дам, единственият проблем е че логиката малко се усложнява и евентуално ще имаш повече драми с базата.

Причината е че скрипта дето се вика периодично не знае за състоянието от предишното изпълнение. Тук има няколко варианта - най-тъпият е на всяко изпълнение да записва състоянието в базата. Това обаче създава повече грижи за уеб приложението, което трябва да обработва информацията - особено ако трябва да вадиш исторически справки кога нещо е работило и кога не е. И таблиците рано или късно ще станат прилично големи. Малко по-умен вариант е на всяко изпълнение да проверяваш състоянието в базата досега и да записваш само ако има промени. Обаче и това не е прекрасно, защото базата ще ти е обвързана с наличните хостове за мониториране, добавянето на нов хост или премахването му ще означава че трябва най-малкото да се правят ръчни манипулации по нея, за да са ти консистентни нещата между отделните изпълнения на cronjob-а.

От част от тези неща няма да избягаш ако имаш демон обаче, в зависимост от заданието. Примерно ако е наистина културен демона, трябва да имаш някаква логика, която да се изпълнява при рестарт така че да не репортва още веднъж че някой хост не работи (това важи особено ако пращаш нотификации - при рестарт на демона не е желателно да си ги получаваш още веднъж) - ако трябва да се бориш с този проблем, то тогава cronjob-а няма да е особено по-комплексен за реализиране, но пък ще спести усилията по демонизирането.

Активен

"Knowledge is power" - France is Bacon