Комментарии 160
..Java к вебу очень косвенно относится
Тут вы ошибаетесь
Посмотрите хотя бы:
https://en.wikipedia.org/wiki/Programming_languages_used_in_most_popular_websites
Да разнообразие и популярность фрейморков для веба в Java говорит об обратном:
Spring, Dropwizard, Spark, Vert.x и т.д.
Вы на Java и не пишите похоже
То, что фпм работает в целом быстре, чем пхп как модуль апача — это общеизвестный факт. Но на принцип работы (который автор указал в результирующей таблице) это никак не влияет.
Каждый запрос так или иначе будет выполняться в своем процессе. Неблокирующего i/o нет.
Я php ни в чем не обвиняю, если что. Просто применительно к этому тесту принципиальной разницы между fcgi vs mod_php не будет.
Правильнее указать, что связка nginx + php-fpm работает быстрее (не намного и не всегда) и меньше памяти потребляет, но это не заслуга php-fpm, а nginx. Применительно к этому тесту грамотно настроенный nginx + php-fpm на третьем графике позволит получить лучший результат.
А вы знаете, что обозначает FPM? Помнится делал бенчмарки и apache+php-fpm показывал лучшие результаты чем apache+mod_php
Fastcgi process manager. Слово "Fast" здесь — часть названия протокола взаимодействия с веб-сервером, и оно само по себе не означает более быструю работу, если вы намекали на это.
В принципе как раз может: ОС не нужно форкать apache+mod_php, а только apache.
Результаты в другой стране и не актуальны — php5.2 емнип там был
в связке PHP + Apache при большом количестве подключений доминирующим фактором становятся удельные накладные расходы, связанные с созданием новых процессов и выделением им памяти, что негативно влияет на производительность PHP
Это серьёзное обвинение и, как говорится, needs to be backed with hard numbers.
А дефолтная конфигурация sudo apt-get install lamp-server^ никак не тянет на hard numbers…
UPD: А! Он ещё ПХП 5.4 использовал! 2017 год на дворе, блжад!
Наверно потому же, почему и Java тестировали на сервлетах, хотя есть Grizzly/Netty. Типа это более популярно. Хотя если кто-то только смотрит на финальные каритинки, не читая текст, в надежде выбрать более "крутую" технологию для нового проекта, то может сложиться немного неадекватное предстваление. Ведь и на PHP, и на Java можно сделать оптимальнее. Даже касательно Node.js, если задача напряжная для CPU (как здесь — подсчёт контрольных сумм), то можно запустить несколько процессов и баллансировать между ними nginx-ом/haproxy/etc. Это позволит загрузить все ядра процессора. Так сравнивать некорректно. Но Go всё же рулит.
Образец для тестов PHP был без использования reactphp, насколько я понял?
И без HHVM. ReactPHP под HHVM показывает совсем другие цифры:)
Ну HHVM это всё же допиленный PHP, а react — просто php-библиотека.
Между 7 и hhvm на базе 5.6 критической разницы не заметил, кстати.
Я говорил о ReactPHP. После прогрева его JIT компилятор показывает очень интересные результаты, которых может не быть при использовании в более традиционном сценарии использования.
Какой ещё JIT-компилятор у reactphp, это просто набор PHP-классов?
hhvm с ядром 5.6 от php 7.0.x отличается на пару процентов даже с прогревом.
JIT компилятор в HHVM, он хорошо проявляет себя когда функции вызываются без перезапуска много раз, что и происходит при запуске HTTP сервера с ReactPHP поверх HHVM.
Не знаю о каком ядре 5.6 идет речь, HHVM поддерживает обе версии одновременно с некоторыми нюансами.
Коротко о HHVM: Symfony 4: End of HHVM support.
Пруф: http://symfony.com/blog/symfony-4-end-of-hhvm-support
Сравнение производительности на Apache2? Почему не Nginx?
А модуль-то вам зачем О_о? Есть же php-fpm.
Сравнение производительности на Apache2? Почему не php-fpm?, то и я, наверное, не полез бы со своим сарказмом…
php-fpm или apache — это выбор между тем, кто будет запускать php. А nginx может стоять перед любым из них.
Apache вполне поддерживает php-fpm.
Да, я тоже некорректно выразился — под «apache» я подразумевал «apache+php_module». И да, согласен, можно перед php-fpm поставить и apache (с fast_cgi модулем) вместо nginx, только лучше выбрать mpm event или worker. Правда, я большой разницы в производительности на своих неправильных тестах не увидел, единственное — apache больше оперативки съел.
… и Java есть реализации неблокирующих вводов/выводов, доступных для использования в веб-приложениях. Но они не так распространены, как вышеописанные подходы..
Это спорное утверждение. И, как мне кажется, если привести статистику с неблокирующими вызовами на Java то она будет уж точно не хуже Go (а может даже лучше).
нативный код может быть в 2 случаях:
1) если вам не нравится стандартный java nio вы можете попросить epoll из линукса
2) если не устраивает скорость ssl в java и вы используете обертку поверх openssl
во всех остальных случаях чистая java которую хоть на android запускай.
в 99% использований нетти всегда укладываются в стандартную java.
https://github.com/netty/netty/tree/4.1/transport-native-epoll
https://github.com/netty/netty/tree/4.1/transport-native-kqueue
https://github.com/netty/netty/tree/4.1/transport-native-unix-common
xhumanoid сверху уже ответил, что в проекте действительно по сути одна только Java. Но все же в репозитории полно нативного кода.
Просто поражает, откуда такая пустословная уверенность в быстроте go…
Если говорить именно о том, что с fasthttp будет сильно круче, то не уверен, несколько быстрее будет. Fasthttp выделяет намного меньше памяти и соответственно GC меньше съест. Правда код на нем, по личному опыту, трудно поддерживать: неинформативные ошибки, попытка почитать код приводит к чтению функций по 200-400 строк…
Бенчмарки можно посмотреть тут
Просто поражает, откуда такая пустословная уверенность в быстроте go…
Скорее всего, потому что из коробки go и правда быстрее. Как минимум потому, что впитал новые идеи, в то время как старые языки базируются на старых. Просто проблема в том, что люди, которые работают с языком (например, Java) знают, что решения, которые из коробки предлагает Java в основном не используются, если вам нужна скорость, но зато используются во всех туториалах и там, где не особо важна скорость чтения (например, десктопное приложение).
А когда кто-то пилит такой бенчмарк, то ищет мануалы и находит решения из коробки.
Вы немного меня не поняли. Я говорю, что базовые решения для Java не используются, если вам нужна скорость, а например, используются netty.
А в случае с go, используется стандартный функционал go, который написан с учетом идей, которые использовали те же библиотеки на java, например.
Скажем, если сравнивать работу с потоками с Java c Go из коробки быстрее на Go, потому что на Java нет легких потоков. Я не прав?
- Сравнивая разные модели вычислений, вывод почему-то перенесся целиком на рантаймы.
- Почти всегда в вопросах производительности заложен как минимум один трейдофф. Этим всегда пользуются маркетологи, рисуя один кейс и игнорируя другие. «Уверовавшие»потом ходят и продолжают их дело, рассказывают про эдем, эликсир вечного перформансного счастья и т.д. (чем ниже порог входа тем проще и больше можно привлекать людей, «жизнь коротка, ты и так уже потратил 15 минут на обучение, ты теперь можешь всё!»)
Или использовать netty/akka-http/undertow/mina или более высокоуровневый vert.x, например. И в процессе шедулить задачи как принято в конкретной библиотеки на FJP или обыкновенный ThreadPool.
У Go обычно фиксированное число потоков, так что если загрузить их достаточным количеством cpu-bounded работы он будет не сильно отличаться от nodejs или java в аналогичных условиях.
https://github.com/valyala/fasthttp/tree/master/examples/fileserver
fasthttp, например, в полтора раза быстрее nginx при раздаче файлов :)
https://github.com/valyala/fasthttp/tree/master/examples/fileserver
Ну себя они в плохом свете точно выставлять не будут…
Я не против этого сервера, как и не против Go. Просто с трудом верится в такой разрыв, по сравнению с nginx, и других бенчмарков быстро не удалось найти…
Там очень много разделов и частей, и во многих случаях fasthttp выигрывает, ну или по крайней мере занимает топовые места.
Но все же хотелось бы видеть чистое сравнение на разных нагрузках, разных количествах одновременных подключений и т.д.
Я многого не понимаю в веб приложениях, но зачем нам там много операций чтения в них?
… ведь он специально разработан для решения таких задач
Не аргумент.
В этой статье весьма спорное решение использовалось для других языков, в частности для Java. Либо приведите конкретные пруфы, либо не бросайтесь словами.
и где я бросаюсь словами?
ежу понятно что GO будет быстрее
Чем можете подтвердить это утверждение?
https://golang.org/doc/faq#What_is_the_purpose_of_the_project
Go is fully garbage-collected and provides fundamental support for concurrent execution and communication.
By its design, Go proposes an approach for the construction of system software on multicore machines.
«ежу понятно что GO будет быстрее» следует из логики, инструмент заточенный под конкретные условия будет быстрее, банально потому что оверхеда меньше, то что другие инструменты создавались под другие условия общеизвестно, наследственность давлеет над ними несмотря на многолетнее развитие.
Пруфы на условия
PHP — https://en.wikipedia.org/wiki/PHP
Java — https://en.wikipedia.org/wiki/Java_(programming_language)
Node.js — https://en.wikipedia.org/wiki/Node.js
На всякий случай даю пруф на логику — https://en.wikipedia.org/wiki/Logic
инструмент заточенный под конкретные условия будет быстрее, банально потому что оверхеда меньше
Из того что инструмент заточен под конкретные условия еще ничего не следует. Это лишь говорит о том на что будут направлены усилия разработчиков, но никак не о том что получится в итоге.
наследственность давлеет над ними несмотря на многолетнее развитие
Она же еще и позволяет убрать кучу детских болячек и вылизать все технические решения
А последнюю ссылку вам бы не мешало проштудировать самому, а может даже и сделать конспект
Из того что инструмент заточен под конкретные условия еще ничего не следует. Это лишь говорит о том на что будут направлены усилия разработчиков, но никак не о том что получится в итоге.
выражение — инструмент заточен — означает что он уже соответствует заданным условиям а не когдато будет.
наследственность давлеет над ними несмотря на многолетнее развитие
Она же еще и позволяет убрать кучу детских болячек и вылизать все технические решения
выражение — наследственность давлеет — означает что есть что-то с чем приходится мирится а не исправлять. исправление возможно если выкинуть существующее и написать заново но это уже не наследственность.
так что логику надо еще подкачать.
Почему для Node.js не был задействован модуль cluster? Это как бы изкоробочная функциональность.
Про ReactPHP уже говорили (кстати, без кластера он должен был показать во втором тесте столь же плохой результат что и нода).
Получается что графики иллюстрируют сравнение 1-го ядра для node.js против 4-х для всех остальных языков :(
(посмотрел исходники по ссылке из статьи )
У вас какие то устаревшие сведенья, уже давно (вроде с 1.5) по умолчанию GOMAXPROCS равно кол-во CPUs.
Я буду обновлять комментарии перед отправкой. Я буду обновлять комментарии перед отправкой. Я буду обновлять комментарии перед отправкой.
Это я пропустил, или автор в самом деле сравнивает перфоманс:
- многопоточной непрогретой JVM, с JSP в Томкате
- PHP, который сидит за непонятным дефолтным конфигом Apache (в целом тоже многопоточном)
- и однопоточную node.js
Ничего из перечисленного вами (кроме кластера) не поможет в CPU-bound задаче (тест 2), скорее даже помешает.
Зато я писал про конкретный тест.
Сильнее всего нода просела именно во втором. И именно там ваши предложения лишь замедлят работу.
Когда нас интересует лишь средняя производительность, а не время отклика, или же когда все задачи одинаковые — то как раз перебор массива for-ом оказывается наилучшим способом даже на одном потоке.
Да какая разница сколько подключений блокировано, если задача — cpu-bound? Ее физически невозможно выполнить быстрее чем она уже выполняется!
Как можно отвечать "медленно, но всем", когда ответ — это 64 байта плюс заголовки?
А как мы ответим "медленно, но всем"? Допустим у нас такие условия: у нас есть 10 входящих реквестов, каждый реквест выполняет цикл длительностью 1 сек, таймаут на ответ = 9 сек. При таких условиях 1й клиент получит ответ через 1 сек, 2й — через 2 сек… 10й клиент получит таймаут. Если мы делаем одновременное выполнение всех запросов, то исполниться они должны примерно одновременно, т.е. все через 10 сек, т.е. все клиенты получат таймаут. Или разве не так?
Сейчас это выглядит так:
//fnc.js
function fileSystemOperation() {
//...
}
const proc = cp.fork("./fnc.js", [args], {
execArgv: []
});
и дальше через process.send комуникация. Не подскажите более просто решение?
Не очень понятно, что такое синхронные операции с fs, их почти все можно делать асинхронно, оперируя стримами. Но уж если там абстрактная число-молотилка, то кроме форка и ipc ничего не придумаешь, можно только взять какую-нибудь библиотечку по удобнее чем cp.fork
А операции совсем дорогие, можно подумать про какую-нибудь очередь, живущую вообще отдельно от сервера.
Существует ряд вариаций, но среднестатистический PHP-сервер выглядит так.
От пользовательского браузера поступает HTTP-запрос на ваш веб-сервер Apache.
Я знаю, что такой комментарий уже был выше. Но повторюсь: дальше нет смысла читать. Никакого. Автор весьма далек от современной разработки на PHP.
Плюс еще автор умудрился взять самую, пожалуй, старую доступную ему конфигурацию тестового стенда: «PHP v5.4.16; Apache v2.4.6» А что не PHP 4 сразу?
Берем Форд модель Т и Volvo XC90. Устраиваем гонки. Вольво выигрывает. Форд — дрянь? ))
хотябы php7.x + php-fpm + nginx.
не говоря уже про react/php-pm/swoole
Уверен, что там еще и префорк на нуле специально был, иначе сложно объяснить смысл последнего графика.
Если верить другому бенчмарку (http://marcjschmidt.de/images/reactphp-benchmark-requests.png), то react может работать наравне обычного hhvm или phpfpm+nginx.
Если верить третьему бенчмарку (http://hostingadvice.digitalbrandsinc.netdna-cdn.com/wp-content/uploads/2015/03/nodejs-vs-php-performance-requests-per-second.png), то php 5.5 + opcache сильно медленнее ноды, а hhvm — наравне.
По большому счёту, быстрый гуглинг говорит о том, что кардинально картина не меняется от манипуляций с reactphp, поднимая результаты максимум в два раза (неважно, используется react, hhvm или php7+opcache+php-fpm).
Но тогда и для Golang вместо net/http делать fasthttp (что на порядок быстрее может быть, чем обычный net/http).
кстати, я как раз редко встречаю такую практику, даже в яндексе на ноде пишут простенькие http-рендеры, тяжелые операции выполняются на java
Навреное потому, что обычно на ноде пишут сервисы, суть в которых минимальная обработка данных(циклами, хэши считать), и по максимуму работа с I/O.
но в некоторых npm библиотеках встречал node-gyp зависимости, и однажды проект не установился, когда gcc был версии меньше 4.4, требовал 4.8. Видимо, в узких местах пишут на Си.
С таким же успехом к ноде можно прикрутить серверную часть от nginx(это будет просто — у обоих асинхронщина в крови, оба на этом взлетели), ой, тогда получится lua script для nginx). Но и этим никто не заморачивается в ноде, она и так прекрасна — сетевой стек весь на js, полный контроль над соединением начиная с tcp.
Ой. Что я вижу. И эти люди мне рассказывали про каллбэк-хэлл:) Ну и эвент-дравен во всей красе. Только в ноде это родное все, а в пхп — попытка прикрутить асинхронщину.
$client = new swoole_redis;
$client->connect('127.0.0.1', 6379, function (swoole_redis $client, $result) {
echo "connect\n";
var_dump($result);
$client->set('key', 'swoole', function (swoole_redis $client, $result) {
var_dump($result);
$client->get('key', function (swoole_redis $client, $result) {
var_dump($result);
$client->close();
});
});
});
Есть еще ayres, kraken, php-pm, php fastcgi daemon и тд.
Хотя бы apache+php-fpm, поскольку остальные тоже работают из-под апача.
"Остальные" — это кто?
В этой статье мы сравним Node, Java, Go и PHP из-под Apache
Разве это не означает, что Apache стоит перед всеми?
Правильно читать вот так:
В этой статье мы сравним (Node), (Java), (Go) и (PHP из-под Apache)
Как минимум нода в отдельном веб-сервере точно никогда не нуждалась. Для Java существует AJP, но это дополнительная возможность, а не основная. Про Go не скажу.
$file_data = file_get_contents(‘/path/to/file.dat’);
InputStream fileIs = new FileInputStream("/path/to/file");
я даже заглянул в код. Думаю очевидно что чтение файла и открытие дескриптора на него — это две совершенно разные вещи.
AloneCoder зачем вы это вообще переводили?
А переводил затем, что любая статья про бенчмарки всегда неоднозначна и порождает дискуссию, обмен мнениями и реальным опытом, что прекрасно и ценно
Тесты в итоге выгдядят так: берём собаку, медведя, слона и кита. Смотрите — кит передвигается хуже всех. Еле по земле ползает.
И вредность данной статьи в том, что потом ходят толпами люди глубоко не разбирающиеся в условиях применения особенностей языков и тычут пальчиком вот в такие «статьи» — node дескать отстой. Mail.ru на Хабре доказало!
Добавлю к некорректному сравнению php и node.js ещё то, что в ноде никто уже несколько лет не пишет на коллбэках. Ну и отдельное удивление вызывает, что в статье не указаны версии движков. Как бы php5 очень сильно отличается по скорости от php7, то же самое с нодой.
Переводчик написал, что это некое мнение для порождения дискуссии, но статья представляет собой ровно то, что является одним из заголовков — "ложь, наглая ложь и бенчмарки". К тому же невооружённым взглядом заметно, что автор тащиться от Go, и видимо поэтому был готов натянуть козу на слона, чтобы показать, как хорош его любимый язык. Стыдно должно быть за такие статьи.
Что касается PHP:
1) php nts (fpm) — работает в многопроцессовом режиме, php ts (mod apache) работает в многопоточном режиме, так что нельзя утверждать, что пых клонит процессы. Т.к. использовался апач — скорее всего использовался, mod + ts, т.е. многопоточный режим.
2) В пыхе есть неболкирующее I/O, в том числе и встроено в сам язык, к пример асинхронные запросы к mysqli, про react + event loop на основе какого-нибудь ev я уже не говорю, т.к. выборка будет не репрезентативна, т.е. это библиотеки, а не stdlib.
3) Не показаны версия и настройки опкеша. По-умолчанию конфиг содержит отключённый опкеш, но стоит его включить и отключить ревалидацию (т.е. избавиться от лишних запросов на жёсткий диск) — можно крайне сильно удивиться (я уж не говорю про jit-сборки, т.к. опять же, выборка не репрезнативна будет).
Большинство Java веб-серверов создают новый поток выполнения для каждого поступающего запроса, и уже в этом потоке в конце концов вызывают функцию, которую написали вы, разработчик приложения.
Потоки объединяются (pooled), чтобы минимизировать стоимость их создания и уничтожения, но в любом случае если у нас тысячи подключений, то создаются тысячи потоков, что плохо сказывается на работе диспетчера.
Это неправда, никто не создает новый поток для каждого выполнения. Потоки всегда в пуле, как это дальше написано и именно по-этому их не создается тысячи, потому что везде уже давно используется ивент-луп для обработки соединений и io-операций и на каждое соединение новые потоки тоже не создаются.
Большинство приложений, веб- и прочих, их не используют, но они хотя бы есть. Некоторые Java веб-серверы пытаются как-то применять преимущества неблокирующих вызовов, однако подавляющее большинство развёрнутых Java-приложений всё ещё работает так, как описано выше.
Не знаю ни одного современного веб-сервера на джаве, который бы не использовал неблокирующее io и ивент-луп так или иначе. И да, как описано выше соответственно сейчас никто не работает, кроме может быть каких-то самопальных поделок сделанных людьми, которые прочли статьи вроде этой.
Прежде чем перейти к обсуждению Go, должен сообщить, что я его поклонник.
Почему-то когда я прочел эти откровенные домыслы, мне подумалось, что дальше будет что-то вроде, «а вот го-то, он совсем другой..» — и точно. Наверное потому, что именно об этом языке появляется много таких совершенно профанских статей, которые кроме фейспалма ничего не вызывают.
Нужны колбэки
Нет, у джавы для неблокирющего io есть каналы из nio, которые прекрасно работают без колбэков и позволяют эффективно реализовать ивентлуп.
Бенчмарки вообще уморили: какие-то дефолтные конфиги и jsp для обработки запроса. Выбраны почему-то именно сервлеты, запускаются «бэнчмарки» без прогрева; когда один раз запускалось, томкат за указанное время еще и жсп поди успел скомпилировать. От реализации рассчета хеша вообще слезы на глаза наворачиваются. Не буду ничего говорить про другие языки, уверен, что там так же ляп на ляпе. А ведь кто-то возможно посмотрит и сделает какой-то вывод далекий от реальности.
1) Начиная с версии 1.5 GOMAXPROCS = количество CPU, по-моему равные условия можно создать если в тестовом приложении Node.js использовать cluster https://nodejs.org/api/cluster.html
2) В Node.js как fs так и crypto (в частности crypto.randomBytes и crypto.pbkdf2) выходят в libuv thread pool http://docs.libuv.org/en/v1.x/threadpool.html, на мой взгляд результат мог бы быть иным если установить UV_THREADPOOL_SIZE=128 (максимум)

Показатель = sort.(v3/(v1*v2))
Чем больше, тем лучше
Хотел бы увидеть более полную версию статьи, основанную на дополнительных данных, ввиде:
1. Дополнить данные схемы языками Ruby и Python, хотя бы потому-то что они тоже довольно популярны в виде бэкенда
2. И добавить еще одну ветку сравнений, в виде использования фреймворков. Т.е. как бы было на нативе и на ФВ. Не знаю как вы, но я ооочень редко встречал поддерживаемые велосипедные проекты)) Обычно(самые распрастранненые варианты)
when(lang) {
Java -> Spring
PHP -> Laravel
Python -> Django
Ruby -> Ruby on Rails
NodeJs -> Express.js
}
Было бы любопытно посмотреть на цифры и объективное исследование)
Ради интереса сделал тесты:
go 1.8.3 на виртуальном стенде в 4 ядра и 1 ГБ памяти лучший результат:
Server Software:
Server Hostname: 127.0.0.1
Server Port: 4000
Document Path: /test?n=1
Document Length: 64 bytes
Concurrency Level: 5000
Time taken for tests: 2.776 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Total transferred: 1810000 bytes
HTML transferred: 640000 bytes
Requests per second: 3602.04 [#/sec] (mean)
Time per request: 1388.102 [ms] (mean)
Time per request: 0.278 [ms] (mean, across all concurrent requests)
Transfer rate: 636.69 [Kbytes/sec] received
Connection Times (ms)
min mean[±sd] median max
Connect: 0 300 390.9 132 1012
Processing: 1 365 352.5 195 1623
Waiting: 1 360 347.8 192 1622
Total: 1 664 436.5 700 1927
Percentage of the requests served within a certain time (ms)
50% 700
66% 1024
75% 1074
80% 1095
90% 1192
95% 1273
98% 1354
99% 1437
100% 1927 (longest request)
php 7.1.5 nginx + php-fpm (pm.max_children = 200, opcache.enable=1) лучший результат:
Server Software: nginx/1.13.0
Server Hostname: 127.0.0.1
Server Port: 80
Document Path: /test.php?n=1
Document Length: 64 bytes
Concurrency Level: 5000
Time taken for tests: 4.448 seconds
Complete requests: 10000
Failed requests: 1893
(Connect: 0, Receive: 0, Length: 1893, Exceptions: 0)
Write errors: 0
Non-2xx responses: 1893
Total transferred: 2504197 bytes
HTML transferred: 884197 bytes
Requests per second: 2248.37 [#/sec] (mean)
Time per request: 2223.832 [ms] (mean)
Time per request: 0.445 [ms] (mean, across all concurrent requests)
Transfer rate: 549.84 [Kbytes/sec] received
Connection Times (ms)
min mean[±sd] median max
Connect: 0 199 309.1 137 1069
Processing: 4 459 667.1 122 3127
Waiting: 1 447 669.9 103 3125
Total: 5 658 767.5 327 4093
Percentage of the requests served within a certain time (ms)
50% 327
66% 1024
75% 1138
80% 1313
90% 1527
95% 2125
98% 3236
99% 3251
100% 4093 (longest request)
Итог 3602.04 #/sec (go) против 2248.37 #/sec (php). Да, php проигрывает, но не так тотально как описывает автор.
Были ошибки запросов:
2017/05/28 23:42:10 [alert] 24969#24969: *758703 socket() failed (24: Too many open files) while connecting to upstream, client: 127.0.0.1, server: localhost, request: "GET /test.php?n=1 HTTP/1.0", upstream: "fastcgi://127.0.0.1:9000", host: "127.0.0.1"
2017/05/28 23:42:10 [crit] 24968#24968: accept4() failed (24: Too many open files)
Ставил ulimt -n 200000
, в конфиге php-fpm rlimit_files = 65535
, в nginx.conf worker_connections 10000
и worker_rlimit_nofile 200000
— не помогло
С сокетами получилось больше, но и ошибок больше:
Server Software: nginx/1.13.0
Server Hostname: 127.0.0.1
Server Port: 80
Document Path: /test.php?n=1
Document Length: 64 bytes
Concurrency Level: 5000
Time taken for tests: 2.471 seconds
Complete requests: 10000
Failed requests: 2797
(Connect: 0, Receive: 0, Length: 2797, Exceptions: 0)
Write errors: 0
Non-2xx responses: 2797
Total transferred: 2620813 bytes
HTML transferred: 1000813 bytes
Requests per second: 4046.81 [#/sec] (mean)
Time per request: 1235.542 [ms] (mean)
Time per request: 0.247 [ms] (mean, across all concurrent requests)
Transfer rate: 1035.73 [Kbytes/sec] received
Connection Times (ms)
min mean[±sd] median max
Connect: 0 439 445.8 226 1306
Processing: 81 394 212.7 389 990
Waiting: 1 349 202.5 365 969
Total: 110 833 491.5 626 1975
Percentage of the requests served within a certain time (ms)
50% 626
66% 865
75% 1323
80% 1356
90% 1759
95% 1862
98% 1872
99% 1875
100% 1975 (longest request)
2017/05/29 08:53:25 [alert] 10283#10283: *107893 socket() failed (24: Too many open files) while connecting to upstream, client: 127.0.0.1, server: localhost, request: "GET /test.php?n=1 HTTP/1.0", upstream: "fastcgi://unix:/var/run/php-fcgi.sock:", host: "127.0.0.1"
В php-fpm выставил listen.backlog = 10000
Это из-за ошибок. Когда происходит ошибка, то выдаётся всё очень быстро и тоже идёт в зачёт. Вообще ab не самая классная тулза. Вечером попробую siege'ом.
Самый адекватный без ошибок получилось с конкурентностью 1000:
Server Software:
Server Hostname: 127.0.0.1
Server Port: 4000
Document Path: /test?n=1
Document Length: 64 bytes
Concurrency Level: 1000
Time taken for tests: 2.641 seconds
Complete requests: 10000
Failed requests: 0
Write errors: 0
Total transferred: 1810000 bytes
HTML transferred: 640000 bytes
Requests per second: 3786.41 [#/sec] (mean)
Time per request: 264.102 [ms] (mean)
Time per request: 0.264 [ms] (mean, across all concurrent requests)
Transfer rate: 669.28 [Kbytes/sec] received
Connection Times (ms)
min mean[±sd] median max
Connect: 0 5 10.7 1 53
Processing: 1 247 133.2 230 868
Waiting: 1 243 132.0 226 856
Total: 1 252 131.5 233 869
Percentage of the requests served within a certain time (ms)
50% 233
66% 289
75% 328
80% 353
90% 422
95% 504
98% 590
99% 644
100% 869 (longest request)
Server Software: nginx/1.13.0
Server Hostname: 127.0.0.1
Server Port: 80
Document Path: /test.php?n=1
Document Length: 64 bytes
Concurrency Level: 1000
Time taken for tests: 2.925 seconds
Complete requests: 10000
Failed requests: 14
(Connect: 0, Receive: 0, Length: 14, Exceptions: 0)
Write errors: 0
Non-2xx responses: 14
Total transferred: 2261806 bytes
HTML transferred: 641806 bytes
Requests per second: 3418.30 [#/sec] (mean)
Time per request: 292.543 [ms] (mean)
Time per request: 0.293 [ms] (mean, across all concurrent requests)
Transfer rate: 755.03 [Kbytes/sec] received
Connection Times (ms)
min mean[±sd] median max
Connect: 0 44 35.5 36 147
Processing: 38 238 89.1 236 577
Waiting: 1 210 84.6 207 526
Total: 43 282 84.4 276 583
Percentage of the requests served within a certain time (ms)
50% 276
66% 315
75% 336
80% 347
90% 380
95% 420
98% 456
99% 574
100% 583 (longest request)
После 1000 у php начинаются проблемы с потерей.
А если через wrk?
Что такое wrk?
Ничего особо не изменилось
Running 30s test @ http://127.0.0.1/test.php?n=1
12 threads and 400 connections
Thread Stats Avg Stdev Max ± Stdev
Latency 100.20ms 63.06ms 542.07ms 76.27%
Req/Sec 348.20 110.88 0.85k 72.45%
124513 requests in 30.07s, 32.06MB read
Requests/sec: 4140.13
Transfer/sec: 1.07MB
Running 30s test @ http://127.0.0.1:4000/test?n=1
12 threads and 400 connections
Thread Stats Avg Stdev Max ± Stdev
Latency 89.85ms 65.55ms 669.74ms 77.39%
Req/Sec 399.38 81.51 800.00 69.61%
143512 requests in 30.11s, 24.77MB read
Requests/sec: 4765.73
Transfer/sec: 842.38KB
С 4000 коннектов ошибки у php
Running 30s test @ http://127.0.0.1/test.php?n=1
12 threads and 4000 connections
Thread Stats Avg Stdev Max ± Stdev
Latency 489.23ms 137.15ms 2.00s 94.40%
Req/Sec 362.90 249.27 3.52k 69.79%
128605 requests in 30.09s, 33.59MB read
Socket errors: connect 0, read 404, write 0, timeout 4065
Non-2xx or 3xx responses: 5850
Requests/sec: 4274.27
Transfer/sec: 1.12MB
Running 30s test @ http://127.0.0.1:4000/test?n=1
12 threads and 4000 connections
Thread Stats Avg Stdev Max ± Stdev
Latency 677.23ms 567.81ms 2.00s 60.05%
Req/Sec 418.88 183.85 2.30k 75.17%
146148 requests in 30.13s, 25.23MB read
Socket errors: connect 0, read 0, write 0, timeout 11398
Requests/sec: 4850.27
Transfer/sec: 857.32KB
Невероятно непрофессиональный подход и просто типичнейший фанбой-булшит. Ничего толком о тестовой конфигурации, ни о железе, ни о софте, ни о версиях. Прогретая джава, не прогретая? Абстрактный аппач с пхп — как минимум странно. Тестирование на разном железе с разным объемом оперативки и количеством ядер? Где?
Мейлру студенческие работы стало переводить?
(Без иронии.)
Производительность I/O бэкэнда: Node vs. PHP vs. Java vs. Go