Комментарии 24
Стоит упомянуть, что onLoad() и onUnload() компонента вызываются в контексте основного потока, а handleRequest() — в контексте потока из тред-пула. Это означает, что подключение к базе, например, выполняется один раз, и надо обязательно помнить про многопоточность доступа и контексты. Например, в случае с MySQL, придётся делать пул коннектов.
Не надеюсь на ответ, спустя больше года, но все же попытаюсь. А зачем вызывать подключение к базе в onLoad() компонента? Можно ведь коннектиться в handleRequest() каждый раз. В случае PostgreSQL через какой-нибудь пуллер-коннектов, тот же PgBouncer, например. Тогда не будет накладных расходов на дорогостоящее подключение к самой базе, а будут «легкие» коннекты к PgBouncer. Пытаюсь разобраться с этим фреймворком, потому интересуюсь. Заранее спасибо за ответ, если он последует 8)
Много подключений делать плохо как минимум по причине того, что при использовании TCP сокеты (не fd, а именно структуры под сокеты в ядре) могут тупо кончиться. Ещё вариант: при подключении делаются некие настройки соединения. Если подключаться в handleRequest(), то их каждый раз нужно будет делать.
А так, конечно, прям требованием подключение к базе в onLoad() не является. Делайте так, как лучше/быстрее в вашем случае. Своим комментарием я хотел подчеркнуть то, что onLoad() выполняется не в контексте тредпула, а из главного потока FastcgiDaemon при его инициализации.
А так, конечно, прям требованием подключение к базе в onLoad() не является. Делайте так, как лучше/быстрее в вашем случае. Своим комментарием я хотел подчеркнуть то, что onLoad() выполняется не в контексте тредпула, а из главного потока FastcgiDaemon при его инициализации.
Странно почему так медленно, у меня C (scgi) + nginx выдают 20 тыс в секунду при 1 тыс конкурентных. При том что там есть еще логика.
В подобном тесте fastcgi дает большие накладные расходы. Ведь NodeJS не был спрятан за http сервером? Если сравнивать C++ приложение, работающее в качестве http сервера, результаты будут значительно лучше. Сравнил с моей поделкой.
NodeJS:
C++ приложение:
Хотя мой код далеко не оптимальный, если сравнивать с nginx.
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)
Но как правильно указал автор, не совсем корректно сравнивать ничего не делающее приложение.
а что у Вас в качестве веб-сервера используется?
Я тоже ожидал больших результатов от fastcgi. Но скорее всего медлительность связана с моим конкретным окружением: VirtualBox, одно ядро, дефолтные настройки как nginx, так и Fastcgi Daemon.
Тоже используем FastCGI при построении C++ бэкендов. За основу взяли стандартную libfcgi-dev и написали вокруг неё небольшую обвязку на С++. По дизайну библиотека получилась очень похожей на описываемую в статье. Померил предлагаемый в статье пример — получается 2-5 мс. Измерения проводил на рабочей машине (i7, 8GB). Бэкенд работал так же в связке с Nginx, для тестирования использовался тот же ab. Однако, тестирование проводилось через loopback. Считаю такой метод измерений более показательным, т.к. все накладные расходы на tcp-handshake и прочее сводятся к минимуму, измеряется именно эффективность связки Nginx + FastCGI бэкенд. Предлагаю автору попробовать измерить без виртуализации и через loopback:)
У меня вначале получилось по производительности хуже, чем на php, но по совету одного местного хаброжителя — уменьшил уровень логгирования — количество обрабатываемых запросов в секунду выросло в разы по сравнению с конфигурацией по умолчанию.
Спасибо за статью. Буду ждать продолжения.
А кто-нибудь уже пробовал CppCMS — Web фреймворк от создателя Boost.Locale? Было бы интересно сравнить его с FastCGI-Deamon.
А кто-нибудь уже пробовал CppCMS — Web фреймворк от создателя Boost.Locale? Было бы интересно сравнить его с FastCGI-Deamon.
Для тех, кто пытается повторить :
в XML конфиге указан путь "hellofascgi" вместо "hellofasTsgi". Поэтому по указанному автором адресу в браузере будет 404 вместо hello stranger
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Веб-приложение на C++, или укрощение демона FastCGI