Pull to refresh

Comments 24

Стоит упомянуть, что onLoad() и onUnload() компонента вызываются в контексте основного потока, а handleRequest() — в контексте потока из тред-пула. Это означает, что подключение к базе, например, выполняется один раз, и надо обязательно помнить про многопоточность доступа и контексты. Например, в случае с MySQL, придётся делать пул коннектов.
Не надеюсь на ответ, спустя больше года, но все же попытаюсь. А зачем вызывать подключение к базе в onLoad() компонента? Можно ведь коннектиться в handleRequest() каждый раз. В случае PostgreSQL через какой-нибудь пуллер-коннектов, тот же PgBouncer, например. Тогда не будет накладных расходов на дорогостоящее подключение к самой базе, а будут «легкие» коннекты к PgBouncer. Пытаюсь разобраться с этим фреймворком, потому интересуюсь. Заранее спасибо за ответ, если он последует 8)
Много подключений делать плохо как минимум по причине того, что при использовании TCP сокеты (не fd, а именно структуры под сокеты в ядре) могут тупо кончиться. Ещё вариант: при подключении делаются некие настройки соединения. Если подключаться в handleRequest(), то их каждый раз нужно будет делать.

А так, конечно, прям требованием подключение к базе в onLoad() не является. Делайте так, как лучше/быстрее в вашем случае. Своим комментарием я хотел подчеркнуть то, что onLoad() выполняется не в контексте тредпула, а из главного потока FastcgiDaemon при его инициализации.
Странно почему так медленно, у меня C (scgi) + nginx выдают 20 тыс в секунду при 1 тыс конкурентных. При том что там есть еще логика.
В подобном тесте fastcgi дает большие накладные расходы. Ведь NodeJS не был спрятан за http сервером? Если сравнивать C++ приложение, работающее в качестве http сервера, результаты будут значительно лучше. Сравнил с моей поделкой.

NodeJS:

Concurrency Level:      100
Time taken for tests:   1.877 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      1150000 bytes
HTML transferred:       140000 bytes
Requests per second:    5328.73 [#/sec] (mean)
Time per request:       18.766 [ms] (mean)
Time per request:       0.188 [ms] (mean, across all concurrent requests)
Transfer rate:          598.44 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.2      0       6
Processing:     1   19   3.4     17      33
Waiting:        1   19   3.4     17      32
Total:          4   19   3.4     17      33

Percentage of the requests served within a certain time (ms)
  50%     17
  66%     18
  75%     18
  80%     19
  90%     25
  95%     26
  98%     30
  99%     31
 100%     33 (longest request)


C++ приложение:

Concurrency Level:      100
Time taken for tests:   0.493 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      1370000 bytes
HTML transferred:       210000 bytes
Requests per second:    20287.80 [#/sec] (mean)
Time per request:       4.929 [ms] (mean)
Time per request:       0.049 [ms] (mean, across all concurrent requests)
Transfer rate:          2714.29 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    2   0.6      2       7
Processing:     1    3   0.8      3       8
Waiting:        1    2   0.7      2       7
Total:          3    5   0.8      5      11

Percentage of the requests served within a certain time (ms)
  50%      5
  66%      5
  75%      5
  80%      5
  90%      6
  95%      6
  98%      9
  99%      9
 100%     11 (longest request)


Хотя мой код далеко не оптимальный, если сравнивать с nginx.
И добавлю то же C++ приложение, но в режиме fastcgi через nginx:

Concurrency Level:      100
Time taken for tests:   1.208 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      1560000 bytes
HTML transferred:       210000 bytes
Requests per second:    8275.49 [#/sec] (mean)
Time per request:       12.084 [ms] (mean)
Time per request:       0.121 [ms] (mean, across all concurrent requests)
Transfer rate:          1260.72 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.9      0       7
Processing:     3   12   2.5     12      32
Waiting:        2   12   2.7     12      32
Total:          3   12   2.2     12      32

Percentage of the requests served within a certain time (ms)
  50%     12
  66%     12
  75%     12
  80%     13
  90%     13
  95%     16
  98%     19
  99%     21
 100%     32 (longest request)


Но как правильно указал автор, не совсем корректно сравнивать ничего не делающее приложение.
а что у Вас в качестве веб-сервера используется?
Своя библиотечка, также сделанная для разработки web приложений на C++.
Чистые сокеты и собственный парсинг HTTP?
Почему не используете Mongoose, Boost или POCO?
Кто сказал, что там чистые сокеты? Где в boost реализация HTTP и FastCGI? Где в POCO и Mongoose поддержка FastCGI?
Я имел в виду часть веб-сервера:
C++ приложение, работающее в качестве http сервера
Потому, что так сложилось. Давайте мы не будем обсуждать мою бибилотеку, она не имеет к статье никакого отношения. Вот когда я напишу статью о ней, к этому вопросу можно будет вернутся :-)
Я тоже ожидал больших результатов от fastcgi. Но скорее всего медлительность связана с моим конкретным окружением: VirtualBox, одно ядро, дефолтные настройки как nginx, так и Fastcgi Daemon.
Тоже используем FastCGI при построении C++ бэкендов. За основу взяли стандартную libfcgi-dev и написали вокруг неё небольшую обвязку на С++. По дизайну библиотека получилась очень похожей на описываемую в статье. Померил предлагаемый в статье пример — получается 2-5 мс. Измерения проводил на рабочей машине (i7, 8GB). Бэкенд работал так же в связке с Nginx, для тестирования использовался тот же ab. Однако, тестирование проводилось через loopback. Считаю такой метод измерений более показательным, т.к. все накладные расходы на tcp-handshake и прочее сводятся к минимуму, измеряется именно эффективность связки Nginx + FastCGI бэкенд. Предлагаю автору попробовать измерить без виртуализации и через loopback:)
Попробуйте лучше через unix socket тогда, а не просто tcp через loopback.
loopback имелся ввиду в связке ab — Ngnix. Для взаимодействия Nginx — FastCGI используем как раз unix socket.
пять лет назад я делал что-то похожее libscgi
пока заказчики не жаловались…
У меня вначале получилось по производительности хуже, чем на php, но по совету одного местного хаброжителя — уменьшил уровень логгирования — количество обрабатываемых запросов в секунду выросло в разы по сравнению с конфигурацией по умолчанию.
Спасибо за статью. Буду ждать продолжения.
А кто-нибудь уже пробовал CppCMS — Web фреймворк от создателя Boost.Locale? Было бы интересно сравнить его с FastCGI-Deamon.

Для тех, кто пытается повторить :

в XML конфиге указан путь "hellofascgi" вместо "hellofasTsgi". Поэтому по указанному автором адресу в браузере будет 404 вместо hello stranger

Эта штука умерла 6 лет назад, лучше не надо повторять)

Может не умерла, а достигла совершенства, поэтому и менять там нечего) Я собрал, все работает. А какая есть альтернатива? Чтобы так же, на плюсах в три строчки простенький сервер?

Для простенького сервиса, наверное, пойдёт, но для production, скорее, не стоит, это же никто не поддерживает, в том числе в плане совместимости с новыми стандартами и библиотеками

Для IO нагрузки подойдёт userver, для числодробилки не могу дать совета, но и вряд ли fastcgi-daemon2 на C++03

Sign up to leave a comment.

Articles