Анкета

Въпрос: Коя конфигурация уеб сървър бихте избрали ?

  • Apache
    - 7 (77.8%)
    Nginx + FastCGI
    - 1 (11.1%)
    Apache + Varnish (http accelerator)
    - 0 (0%)
    Nginix + Varnish (http accelerator)
    - 1 (11.1%)
    Apache + Nginx (proxy reverse)
    - 0 (0%)
    Apache + Nginx (proxy reverse) + Varnish (http accelerator)
    - 0 (0%)

Общ брой гласове: 8

Автор Тема: Конфигурация за уеб сървър  (Прочетена 4330 пъти)

bILLY

  • Напреднали
  • *****
  • Публикации: 159
  • Distribution: Red Hat 7
  • Window Manager: Windows 10
    • Профил
    • WWW
И ако искате може и да коментирате  :)
Активен

"UNIX is like sex: If you don't know it, you don't miss it. But if you know it, you'll need it!"
Lars Eilebrecht

pennywise

  • Гост
Re: Конфигурация за уеб сървър
« Отговор #1 -: Aug 21, 2015, 23:46 »
Трябваше да има опция само Nginx. Поне за php+mysql е най-добрата опция според мен, а със fastcgi можеш да кешираш, също nginx има microcache ама то може да причини малко неудобства. С apache обаче може лесно да добавяш модули, и не е нужно да компилираш всичко отново.

Всичко зависи от ситуацията, но като знам, че питаш за WordPress мисля, че Nginx+phpfastgi е добра комбинация. Ама да знаеш, че има няколко подводни камъка :)
« Последна редакция: Aug 23, 2015, 15:35 от pennywise »
Активен

jet

  • Напреднали
  • *****
  • Публикации: 3473
  • Distribution: debian
  • Window Manager: kde
    • Профил
Re: Конфигурация за уеб сървър
« Отговор #2 -: Aug 22, 2015, 00:53 »
Apache + SSD disk
Активен

..⢀⣴⠾⠻⢶⣦⠀
  ⣾⠁⢠⠒⠀⣿⡁
  ⢿⡄⠘⠷⠚⠋
  ⠈⠳⣄⠀⠀⠀⠀  Debian, the universal operating system.

gat3way

  • Напреднали
  • *****
  • Публикации: 6050
  • Relentless troll
    • Профил
    • WWW
Re: Конфигурация за уеб сървър
« Отговор #3 -: Aug 22, 2015, 02:28 »
Тотално няма значение. Сървърът няма толкова голямо значение, всичко зависи от това какво и как прави приложението. Съвсем извън това, дори и това е ирелевантно, понеже днес скалирането е евтино и лесно и пак опираме до приложението, което може и да не може да се скалира лесно и евтино. Иначе има една стара дилема изкристализирала под формата на драмата с C10K проблема - и случаите и решенията са доволно много и доволно различни за да може отговорът да опре до "ползвам apache+varnish" или "ползваме nginx който reverse-проксира и балансира няколко инстанции на tornado приложение". Апропо където има значение, и в общия случай когато трябва просто да си хостнеш блога някъде, няма никакво значение, но все пак - когато това вече има значение, трябва да си доволно малоумен за да довериш избора на хора, за които всичко опира до сценариите описани в анкетата, без никакви негативни помисли. Така че спокойно, когато такива решения трябва да се вземат, то обикновено последните хора, които биват запитани са същите тези хора, които спорят за дистрибуции, графични среди или уеб сървъри защото нещо им се струвалo по-удобнo и по-приятнo.

Та накратко въпросът е горе-долу от сорта на какъв производител на превозни средства бихте избрали ако искахте да стигнете от София до Лондон - обаче без да се уточнява точно колко и какъв багаж ще се носи, дали има значение колко бързо ще се стигне дотам и дали цената е критерий.
« Последна редакция: Aug 22, 2015, 02:36 от gat3way »
Активен

"Knowledge is power" - France is Bacon

BRADATA

  • Напреднали
  • *****
  • Публикации: 833
  • Distribution: Slackware/Mint/CentOS
  • Window Manager: console/KDE/LXDE
    • Профил
    • WWW
Re: Конфигурация за уеб сървър
« Отговор #4 -: Aug 22, 2015, 07:14 »
Абсолютно некоректно зададен въпрос... Ама гейта е дал уникален пример :). Има и нещо друго - огромно значение има и СУБД дето дава дейтата отзад. Та така...
Активен

NorthBridge

  • Напреднали
  • *****
  • Публикации: 177
  • Distribution: Slackware-current
  • Window Manager: Enlightenment E17
  • Mad Tinkerer
    • Профил
Re: Конфигурация за уеб сървър
« Отговор #5 -: Aug 22, 2015, 15:28 »
Има и нещо друго - огромно значение има и СУБД дето дава дейтата отзад. Та така...

Ъъъ, какво общо има субд-то с уеб сървъра?

Иначе няма голямо значение, имаше един пич дето му беше писнало да обясняват че nginx бил не знам колко пъти по-бърз от Apache, хвана се, направи една камара бенчове и в крайна сметка стигна до извода че двата са на практика с еднакъв performance, с лек превес за nginx при сервиране на статично съдържание. Така че май отговорът е "който те кефи повече".

Аз преди ползвах само Apache. После ми се наложи да свикна с nginx, две седмици го псувах, после ми се видя по-лесно даже и от Apache.

Иначе добавете и lighttpd в отговорите  :)
Активен

I did a 'zcat vmlinuz > /dev/audio' and I think I heard God...

BRADATA

  • Напреднали
  • *****
  • Публикации: 833
  • Distribution: Slackware/Mint/CentOS
  • Window Manager: console/KDE/LXDE
    • Профил
    • WWW
Re: Конфигурация за уеб сървър
« Отговор #6 -: Aug 22, 2015, 15:35 »
Има и нещо друго - огромно значение има и СУБД дето дава дейтата отзад. Та така...

Ъъъ, какво общо има субд-то с уеб сървъра?

...
Ми от контекста на писанките от Били става ясно, че той иска да ползва распбери за да хоства уордпрес сайтове и разни други динамични неща, ползващи СУБД. Та за това има общо...
Активен

gat3way

  • Напреднали
  • *****
  • Публикации: 6050
  • Relentless troll
    • Профил
    • WWW
Re: Конфигурация за уеб сървър
« Отговор #7 -: Aug 22, 2015, 17:21 »
Има грубо три подхода при писане не само на уеб приложение/уеб сървър, но и на какъвто и да е сървър. Най-тривиалният е с pool от worker процеси, всяка клиентска връзка се обслужва от един такъв - това е най-лесният за реализиране, защото се избягват разни криви проблеми. Но от гледна точка на производителност също и най-неоптималния - защото е ресурсоемък и защото има огромен overhead от превключвания на контексти, интерпроцесна комуникация, латентност при форкване на нови процеси когато се налага и т.н. Но това е начина по който се случват в масовия случай нещата с apache/mod_php.

Вторият подход е сходен с първия - само че worker-ите не са процеси, а нишки. Това позволява по-малки разхищения на памет, по-евтино превключване между контексти, споделената памет лесно се използва за бърза комуникация между нишките и като цяло позволява по-висок брой обслужени паралелни заявки за същото време. Обаче това създава и проблеми - уеб приложението трябва да е thread-safe, а специално PHP много дълго време имаше проблеми с това и дори не знам дали към днешно време са решени изцяло. Което е по-криво, проблемите се случват в PHP интерпретатора и не винаги са очевидни. Apache го подържа, просто трябва да се използва друг mpm модел, не mpm_prefork.

Третият подход е радикално различен - там нямаме отделни worker процеси и нишки за всяка заявка, вместо това всички използвани сокети се вкарват в един fd set и се ползва select()/poll()/epoll()/etc за да се poll-ва set-а за събития - когато на някой файлов дескриптор се появи събитие, съответно заявката се обслужва. Това е едновременно и благодат и проклятие - ако всичко е написано като хората, резултатите са с порядъци по-добри от подхода с worker-ите, ако обаче не е - тогава резултатите са плачевни. Проблемът е че това е до известна степен друга парадигма - приложението трябва да се напише така че да работи по този начин и писането на такива приложения е тотално различно и доста досадно. И всичко трябва да е направено с идеята да работи така - например handler-ите за заявките ти може да са асинхронни, но ако правят синхронни заявки към базата, това означава че докато тече тази заявка, сървърът не може да обслужва нищо друго и останалите клиенти стоят и чакат. Така че файловите дескриптори ползвани при достъпване на базата също трябва да се вкарат във fd set-а и да минават през polling механизъма.

Като цяло, PHP като език и като имплементация е тотално непригоден за да се пишат такива приложения и затова при такива случаи се ползват разни по-екзотични неща като node.js или пък tornado. В apache имаше някакъв експериментален event-базиран mpm модел доколкото помня - въпреки че е абсолютно непригоден за използване с PHP приложения изпълнявани през mod_php, просто смисълът се губи.

Асинхронния/event-базиран подход също сам по себе си не е перфектен, защото когато всичко се обслужва в рамките на един процес, сървърът с приложението не може да утилизира многоядрена/многопроцесорна машина. Затова съответно има хибридни изпълнения - няколко worker-а с poll-ване на отделни множества от файлови дескриптори.

И най-накрая, тези неща като цяло в последно време не са толкова важни, откакто се появиха облаците и стана лесно да си вдигнеш като ти кефне нова инстанция. Като цяло това кара хората да се замислят повече за лесното скалиране на приложението, отколкото за оптималното изтискване на ресурсите. Като това не винаги е прост проблем, лесен за решаване.
Активен

"Knowledge is power" - France is Bacon

daniel_vulchev

  • Напреднали
  • *****
  • Публикации: 177
  • Distribution: NetBSD, Slackware, Debian
  • Window Manager: Console/Gnome
    • Профил
    • WWW
Re: Конфигурация за уеб сървър
« Отговор #8 -: Aug 22, 2015, 23:05 »
Мериш с рулетката и преценяш кое да ползваш може и исс сървър да е
Активен

NorthBridge

  • Напреднали
  • *****
  • Публикации: 177
  • Distribution: Slackware-current
  • Window Manager: Enlightenment E17
  • Mad Tinkerer
    • Профил
Re: Конфигурация за уеб сървър
« Отговор #9 -: Aug 23, 2015, 14:21 »
Обаче това създава и проблеми - уеб приложението трябва да е thread-safe, а специално PHP много дълго време имаше проблеми с това и дори не знам дали към днешно време са решени изцяло.

Хм, последно като гледах имаше един списък с 6-7 extensions, които не бяха thread-safe, останалото беше ОК. Едни колеги бяха тръгнали да пишат нещо по този тертип, не съм ги чувал да се оплакват от езика.

Цитат
Третият подход е радикално различен - там нямаме отделни worker процеси и нишки за всяка заявка, вместо това всички използвани сокети се вкарват в един fd set и се ползва select()/poll()/epoll()/etc за да се poll-ва set-а за събития

Не бях чувал за това :) Можеш ли да пратиш линк към някое гитхъбско репо писано така да разгледам, че ми стана интересно?

Цитат
И най-накрая, тези неща като цяло в последно време не са толкова важни, откакто се появиха облаците и стана лесно да си вдигнеш като ти кефне нова инстанция. Като цяло това кара хората да се замислят повече за лесното скалиране на приложението, отколкото за оптималното изтискване на ресурсите. Като това не винаги е прост проблем, лесен за решаване.

Е това е нормално, никой няма да си играе да пише оптимизации при положение че може просто да налее още малко долари на месец и да си вдигне параметрите на чарколяка който наема. Стига да не стигнеш момента когато тези пари ще станат неприятно големи, и тогава щеш не щеш ще ти се наложи да правиш магии  ;D
Активен

I did a 'zcat vmlinuz > /dev/audio' and I think I heard God...

gat3way

  • Напреднали
  • *****
  • Публикации: 6050
  • Relentless troll
    • Профил
    • WWW
Re: Конфигурация за уеб сървър
« Отговор #10 -: Aug 23, 2015, 15:02 »
Цитат
Не бях чувал за това :) Можеш ли да пратиш линк към някое гитхъбско репо писано така да разгледам, че ми стана интересно?

Мммм произволно node.js приложение предполагам. Макар че аз поне node.js никога не съм пипал, javascript нещо не ми е от любимите неща, такива неща съм правил на питон с tornado фреймуърка. Та предполагам из github ще има доста tornado неща също, за тях бих могъл да коментирам повече какво и как го правят :)

P.S всъщност торнадо-то си идва с доста демо примери, може да хвърлиш едно око:

https://github.com/tornadoweb/tornado/tree/master/demos
« Последна редакция: Aug 23, 2015, 15:05 от gat3way »
Активен

"Knowledge is power" - France is Bacon

Naka

  • Напреднали
  • *****
  • Публикации: 3400
    • Профил
Re: Конфигурация за уеб сървър
« Отговор #11 -: Aug 23, 2015, 16:13 »
Добре де аз кой подход съм правил ??? ??? Преди се опитвах да правя на PHP сървер... и го направих и ми върши работа.

Общо взето в тази последователност:
socket_create()
socket_bind()
socket_listen()

след това с socket_select() се определят сокетите на които има движение, а чрез socket_accept() се приема нова клиентска конекция ако има такава и се добавят в $client_socks[].
правят се два масива:
$client_socks[] с всички активни клиентски сокети и масива
$read[], които са тези сокети сред активните на които е детекнато движение.
След това по този списък се облужват(четат) един по-един тези на които преди това е детекното движението.
е това е кода дето успях да скалъпя...Орязъл съм го за пригледност така че може да има и несъответсвия.

Код
GeSHi (PHP):
  1. #!/usr/bin/php -Cq
  2. <?php
  3.  
  4. // test
  5. // nc localhost 8181
  6. // ncat localhost 8181
  7. //
  8. // monitor
  9. // netstat -ntc
  10.  
  11. $address = '127.0.0.1';
  12. // '0.0.0.0' слуша на всички интерфейси
  13. $address = '0.0.0.0';
  14. $port = 8181;
  15.  
  16. $max_clients = 3;
  17.  
  18.  
  19.  
  20. function socket_init($address, $port)
  21. {
  22. // създава TCP мастер сокет който да слуша на  $address:$port и връща този сокет
  23. // при грешка се връща false
  24.  
  25. // Create a TCP Stream socket
  26. if (false === ($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)))
  27. {
  28. fwrite(STDERR, "socket_create() failed: reason: ".socket_strerror(socket_last_error())."\n");
  29. return false;
  30. }
  31.  
  32. // Bind the socket to an address/port
  33. if (false === @socket_bind($sock, $address, $port))
  34. {
  35. fwrite(STDERR, "socket_bind() failed: reason: ".socket_strerror(socket_last_error($sock))."\n");
  36. return false;
  37. }
  38.  
  39. // Start listening for connections
  40. // man 2 listen
  41. // http://fixunix.com/unix/379049-server-socket-how-limit-number-connections.html
  42. // http://stackoverflow.com/questions/5111040/listen-ignores-the-backlog-argument
  43. //
  44. // вторият параметър на socket_listen() се нарича 'backlog' и няма никакъв ефект за ограничаването
  45. // на броя конекции. Той е само консултативен и посочва по някакъв вътрешен алгоритъм на OS-а
  46. // колко ще бъде голяма опашката на чакащите конекции.
  47. //
  48. // The backlog argument to listen() is only advisory.
  49. //
  50. // POSIX says:
  51. // The backlog argument provides a hint to the implementation which the implementation shall use
  52. // to limit the number of outstanding connections in the socket's listen queue.
  53. // Current versions of the Linux kernel round it up to the next highest power of two,
  54. // with a minimum of 16. The revelant code is in reqsk_queue_alloc().
  55. //
  56. if (false === socket_listen($sock, 0))
  57. {
  58. fwrite(STDERR, "socket_listen() failed: reason: ".socket_strerror(socket_last_error($sock))."\n");
  59. return false;
  60. }
  61.  
  62. return $sock;
  63. }
  64.  
  65.  
  66. //////////////////////////////////////////////////////////////////////////////////////////////
  67. ////////////////////////////////////////// Начало инициализация ////////////////////////////////////////////
  68.  
  69. /////////// Инициализация Сокети //////////////
  70. // http://php.net/manual/en/sockets.examples.php
  71.  
  72. // http://www.binarytides.com/php-socket-programming-tutorial/
  73. // http://bg2.php.net/manual/en/function.socket-select.php
  74.  
  75. if (false === ($master_sock = socket_init($address, $port))) die;
  76.  
  77. fwrite(STDERR, "Listen on port $port.\n");
  78.  
  79.  
  80. //////////////////////////////////////////////////////////////////////////////////////////////
  81. ////////////////////////////////////////// Главна програма ////////////////////////////////////////////
  82.  
  83.  
  84. // масив с клиенските сокети, който реално ще се обслужват -- резултатите от $msg_sock = socket_accept($master_sock)
  85. $client_socks = array();
  86.  
  87. // масив от сокети, които ще се проверяват за нови конекции от socket_select()
  88. // и това ще са върнатите сокети от  socket_select(), които са кандидатите за обработка защото в тях вече има постъпили данни
  89. // ако се приеме конекцията за обработка от read[] масива то тя ще се добави в $client_socks[]
  90. $read = array();
  91.  
  92.  
  93. // main loop
  94. while (true)
  95. {
  96. // main loop подготовка на клиенските сокети за обработка - приемане отказване
  97. //////////////////////////////////////////////////////////////////////////////
  98.  
  99.  
  100.      // prepare array of readable client sockets
  101.      $read = array();
  102.      // за да работи правилно socket_select() трябва първият в списъка който ще се подаде де е master сокета
  103.      $read[0] = $master_sock;
  104.  
  105.      // прехвъляне на списъка с активните сокети $client_socks[] в $read[] масива за проверка
  106.      // т.е. правим копие на $client_socks[] в $read[] защото след socket_select() §$read[] масива ще е променен
  107.      for ($i = 0, $size=count($client_socks); $i < $max_clients and $i < $size; $i++)
  108.      {
  109.    if($client_socks[$i] !== null)
  110. $read[$i+1] = $client_socks[$i];
  111.      }
  112.  
  113.    // чака блокиращо докато се появи някъде, че има постъпили данни на някой сокет.
  114.    // последният параметър NULL показва блокиращо чакане.
  115.    // А другите два параметъра за следене по запис и  exceptions $w= NULL, $e= NULL са забраннени да не се ползват.
  116.    //
  117.    // при изход socket_select() връща броя сокети в които има постъпили данни. и масива $read (по адрес), който
  118.    // е списък на сокетите в които има постъпили данни.
  119.    //
  120.    // когато във върнатият масив се съдържа и $master_sock това означава и че има и новопостъпила конекция.
  121.    // ??? една нова конекция или няколко. всички примери обслужват само една - може би точно така действа socket_select()
  122.    if(socket_select($read, $w= NULL, $e= NULL, NULL) === false)
  123.    {
  124. fwrite(STDERR, "socket_select() failed: reason: "
  125.       . socket_strerror(socket_last_error())."\n");
  126. fwrite(STDERR, "The Server can NOT service the incommning connection.\n");
  127. break;
  128.    }
  129.  
  130.  
  131.  
  132.    // if $read contains the master socket, then a new connection has come in
  133.    // намираме първият свободен слот в $client_socks[] и там записваме конекцията
  134.    // първият свободен слот може да е както в средата на масива така и накрая, след запълнените елементи
  135.    if (in_array($master_sock, $read, true))
  136.    {
  137. $accepted=false;
  138.        for ($i = 0, $size=count($client_socks); $i < $max_clients; $i++)
  139.        {
  140.    // може и само if ($client_socks[$i] === null)
  141.    // тази допълнителна проверка $i>=$size се прави само да няма Notice:  Undefined variable за  $client_socks[$i]
  142.    // когато се отработва ситуацията когато се добава сокет в края на масива
  143.    // (т.е $client_socks все още е по-малък от максималният си размер - $max_clients и $i излиза отвън)
  144.            if ($i>=$size OR $client_socks[$i] === null)
  145.            {
  146.    // Тази функция чака (блокиращо) за осъществяване на връзката от отдалеченият клиент.
  147.    // (В случая не чака а връща веднага защото конекцията е приготвена от преди от socket_select())
  148.    // Когато клиента осъществи връзка socket_accept() връща нов 'клиентски' сокет за комунукация за точно
  149.    // тази конекция.
  150.    //
  151.    // If there are no pending connections, socket_accept() will block until a connection becomes present.
  152.    // this function will accept incoming connections on that socket. Once a successful connection is made,
  153.    // a new socket resource is returned, which may be used for communication.
  154.    // If there are multiple connections queued on the socket, the first will be used.
  155.    // винаги да се ползва socket_clear_error() защото socket_last_error() не чисти грешката.
  156.    if (( $client_socks[$i] = $msg_sock = socket_accept($master_sock)) === false)
  157.  {
  158. fwrite(STDERR, "socket_accept() failed: reason: ".
  159. socket_strerror(socket_last_error($master_sock))."\n");
  160. fwrite(STDERR, "The Server can NOT service the incommning connection.\n");
  161. socket_clear_error($master_sock);
  162.  break 2;
  163.  }
  164.  
  165.    socket_getpeername($msg_sock, $client_ip, $client_port);
  166.    fwrite(STDERR, "($i) Connection established. $client_ip:$client_port\n");
  167.  
  168.    // Винаги точно 3 реда съобщение - това ще позволи на автомата който се вързва към сървера
  169.    // лесно да отдели тези 3 реда.
  170.    socket_write($msg_sock, "Добре дошли в сървера.\n");
  171.    socket_write($msg_sock, "\n");
  172.    // край на цикъла, защото е вече намерен слота и е осъществена връзката
  173.  
  174.  
  175.    $accepted=true;
  176.            break;
  177.            } //if
  178.        } // for ($i = 0; $i < $max_clients; $i++)
  179.  
  180. if (!$accepted)
  181.  {
  182.  // имало е индикация за нова конекция защото сме вътре в проверката if (in_array($master_sock, $read))
  183.  // но е нямало свободен слот. Затваря се конкцията към клиента
  184.  // единственият начин за затваряне на (пендиг) конекцията е тя да се приеме да се изпише кратко съобщение на клиента
  185.  // и да се затвори. Така няма да може да се предаде по нататък на тежката обработка.
  186.  if (( $msg_sock_denited = socket_accept($master_sock)) === false)
  187.  {
  188. fwrite(STDERR, "socket_accept() failed: reason: ".
  189. socket_strerror(socket_last_error($master_sock))."\n");
  190. fwrite(STDERR, "The Server can NOT service the incommning connection.\n");
  191. socket_clear_error($master_sock);
  192.  break 1;
  193.  }
  194.  socket_getpeername($msg_sock_denited, $client_ip, $client_port);
  195.  
  196.  fwrite(STDERR, "Connection denied. $client_ip:$client_port\n");
  197.  
  198.  socket_write($msg_sock_denited, "Welcome to the Server.\n");
  199.  socket_write($msg_sock_denited, "Server busy. Too many connections. Try again later.\n");
  200.  socket_write($msg_sock_denited, "\n");
  201.  socket_close($msg_sock_denited);
  202.  } // if (!$accepted)
  203.  
  204.    } //if (in_array($master_sock, $read))
  205.  
  206. // main loop край на подготовката на клиенските сокети за обработка - приемане отказване
  207. ////////////////////////////////////////////////////////////////////////////////////////
  208.  
  209.  
  210. //fwrite(STDERR, "Loop start.\n");
  211. // loop - обслужване на клиентски сокети
  212. ////////////////////////////////////////
  213. for ($i = 0, $size=count($client_socks); $i < $max_clients and $i < $size; $i++)
  214. {
  215. if (in_array($client_socks[$i] , $read, true))
  216.        {
  217.  
  218. $msg_sock=$client_socks[$i];
  219. // fwrite(STDERR, "\n\n(start)\n");
  220.  
  221. // socket_read() чака
  222. // и връща false при следните ситуации:
  223. // 1. error
  224. // 2. connection closed
  225. if ( false === ($input_line = socket_get_data($msg_sock,$error,$error_str)) )
  226. {
  227. if(104 == $error) { fwrite(STDERR, "($i) Connection closed.\n");
  228.    socket_close($msg_sock);
  229.    $client_socks[$i]=NULL;
  230.    continue; }
  231. else { fwrite(STDERR,  "socket_read() failed: reason: $error_str\n");  break 2; }
  232. }
  233.  
  234.  
  235. /////////////////////////////////////////////////////////////////////////////////////////////////////
  236. /////// оснавната част на скрипта ////////////////////////////////////////////////
  237. /////////////////////////////////////////////////////////////////////////////////////////////////////
  238. // !!! към това което се пише обратно ($input_line), не трябва да се добавя \n накрая защото и си има
  239.  
  240.  
  241. $translated_line = $input_line;
  242. // връща го обратно по нета
  243. socket_write($msg_sock, $translated_line);
  244.  
  245.  
  246. ////////////////////////////////////////////////////////////////////////////////////////////////////
  247. /////// основната част на скрипта ////////////////////////////////////////////////
  248. ////////////////////////////////////////////////////////////////////////////////////////////////////
  249.  
  250. }
  251. }
  252. // fwrite(STDERR, "Loop end.\n");
  253. // loop - край на обслужване на клиентски сокети
  254. ////////////////////////////////////////////////
  255.  
  256. } // end of main loop
  257. socket_close($master_sock);
  258.  
  259. ?>
  260.  


Обаче въпроса който ме мъчи е как може да се ограничи броя на приеманите конекции? например разрешени са три едновременни конекции и искам на четвъртият клиент да му се откаже конекциятя? да му се върне нещо то рода на Server busy, access denied..... Това не можах да разбера как се прави и дали изобщо е възможно с tcp?


в socket_listen() има параметър дето се нарича 'backlog' той е някакъв кърнелси стек? за броя конекции но изобщо не оказва влияние на броя конекции.

Едиственото което успях да измисля е като дойде 4-та конекция да я приема да изпиша нещо към клиента от рода на Server busy и веднага да затворя съответният клиентски сокет?
« Последна редакция: Aug 24, 2015, 10:01 от Naka »
Активен

Perl - the only language that looks the same before and after encryption.

gat3way

  • Напреднали
  • *****
  • Публикации: 6050
  • Relentless troll
    • Профил
    • WWW
Re: Конфигурация за уеб сървър
« Отговор #12 -: Aug 23, 2015, 16:28 »
Не точно, backlog-а е по-скоро максималния брой на клиентските връзки които чакат да ги accept-неш, а като удариш тази бройка на клиентите им се връща обикновено грешка при connect() и вече си е тяхна работа дали да върнат грешка или да пробват отново.

Няма нещо наготово, което да те лимитира колко клиентски връзки да приемеш - това си зависи от теб. Може примерно да пазиш броя на клиентските връзки и като стигнеш до максимума отворени, да не accept-ваш нови.


Цитат
Добре де аз кой подход съм правил ??? ??? Преди се опитвах да правя на PHP сървер... и го направих и ми върши работа.

Ами третия, само че не оптимално.

Апропо, нещата са описани доста по-детайлно тук: http://www.kegel.com/c10k.html
« Последна редакция: Aug 23, 2015, 16:32 от gat3way »
Активен

"Knowledge is power" - France is Bacon

Naka

  • Напреднали
  • *****
  • Публикации: 3400
    • Профил
Re: Конфигурация за уеб сървър
« Отговор #13 -: Aug 23, 2015, 16:50 »
Ами третия, само че не оптимално.

В смисъл? че третият подход не е оптимален или че греша някъде в постановката. Скорост и ниска латенция изобщо не ми е нужна, защото процеса който обслужва е хиляди пъти по бавен. Единствено ме интересува постановката да е правилна, защото все имам неприятно усещане че нещо греша със сокетите.

Цитат
Може примерно да пазиш броя на клиентските връзки и като стигнеш до максимума отворени, да не accept-ваш нови.

Да но те се трупат в опашката точно заради backlog-а. например клиентите 4,5,6,7,..... седят и чакат и по никакъв начин не могът да разберат че немогат да се вържат. Едва когато се затвори някоя от активните конекции от 1,2,3 тогава на някой от чакащите му идва реда. А аз това не искам да се случва.
« Последна редакция: Aug 23, 2015, 17:28 от Naka »
Активен

Perl - the only language that looks the same before and after encryption.

gat3way

  • Напреднали
  • *****
  • Публикации: 6050
  • Relentless troll
    • Профил
    • WWW
Re: Конфигурация за уеб сървър
« Отговор #14 -: Aug 23, 2015, 17:23 »
В смисъл че не ползваш неблокиращо IO и че select е бавно и лимитирано откъм максимален брой дескриптори в сета. Но ако производителността не е критична, значи няма значение.

А иначе, backlog-а няма отношение към това дали затваряш активни конекции. Можеш да затвориш всички, но да не викаш accept и тогава ще продължат да се трупат там, просто ако искаш да сложиш твърд лимит на активните клиенти го прави преди accept и да не ти пука толкова за опашката чакащи - това така или иначе е работа на операционната система, ти единствено можеш да кажеш колко да се трупат там преди да почне да им се връща грешка.
Активен

"Knowledge is power" - France is Bacon