В этой статье я рассмотрю опыт практического выбора и тестирования услуг виртуального хостинга. Предпосылкой к этому стал тот факт, что текущей хостер перестал удовлетворять моим требованиям, а именно цена, стабильность и скорость при должном качестве техподдержки. Рынок услуг хостинга развивается достаточно динамично, снижаются цены при повышении качества и разнообразия услуг.
Исходные данные для тестирования
Сравним два относительно недорогих виртуальных хостинга со схожими тарифами.
Текущий провайдер — M-hoster, тариф Standard (5$ в мес.) со следующими ограничениями: RAM 2 GB, 1768 IOPS, число процессов — 100, скорость доступа к диску — 100 Мбайт/с, лимит IO — 10 МБ/с. Диск SSD в массиве RAID-10, процессор 2x Intel Xeon E5-2697 v2 @ 2.70GHz с 12 двухпоточными ядрами каждый, что обеспечивает в сумме 2 x (24×2) = 48 потоков. Лимит времени процессора — 1000%. Защита от DDoS отключена.
Тестируемый хостер — Hostiman. Самый дешёвый тариф — RuGold (199 руб/мес.) со следующими характеристиками: 30 % ядра CPU, 1 GB DDR4 RAM, NVMe SSD, Entry Process (EP) соединения — 20, процессов — 35, скорость IO — 10 МБ/с. На сервере используется процессор Intel(R) Xeon(R) CPU E3-1270 v6 @ 3.80GHz с 4 ядрами и 8 потоками.
Hostiman был выбран среди аналогичных претендентов по причине низкой цены, вполне комфортных тарифных охранениях и быстрых ответов техподдержки. В нашем тестировании оба претендента используют панель ISPmanager и операционную систему CloudLinux для управления пользователями и лимитами. Кроме того, важно отметить, что для тестирования была выбрана одинаковая версия PHP — 7.3.26 и движок, обрабатывающий PHP запросы также одинаковый — это LSAPI. Многие не знают, что это такое, поэтому сделаем небольшое отступление.
Протокол LSAPI (LiteSpeed Server Application Programming Interface) был разработан специально для бесшовной, оптимизированной связи между веб-сервером LiteSpeed и сервером Apache для ускорения обработки динамических запросов. LSAPI имеет высокую скорость обработки PHP, сопоставимую со скоростью Nginx + FPM, а также поддерживает .htaccess как и Apache + mod_php. Вот его другие достоинства:
- поддержка .htaccess (Nginx его не поддерживает);
- альтернативные версии PHP для разных доменов;
- поддержка всех возможностей mod_php;
- Усиление безопасности. LSAPI поддерживает модуль безопасной работы с приложениями suEXEC. Кроме того, здесь реализована возможность изолированного запуска процессов в chroot окружении.
- Ускорение работы с opcode-кэшированием. Технология LSAPI поддерживает кэширование промежуточного кода (opcode caching) — быструю загрузку PHP-процессов из общей памяти. Эта функция реализована с помощью подключаемых расширений (например, XCache, Zend Opcache), которые могут меняться в зависимости от версии PHP.
- Уменьшение потребления ресурсов. Процессам lsphp требуется гораздо меньше памяти. Это уменьшает общую нагрузку на систему и снижает вероятность превысить ресурсные лимиты, выделенные пользователю.
- Увеличение производительности. Благодаря высокой скорости обработки PHP, сайты начинают загружаться и работать быстрее. Производительность LSAPI на 50% выше, чем у Apache (mod_PHP) и на 20% превосходит FastCGI.
Справедливости ради, сразу отмечу, что по моим тестам LSAPI не превосходит по производительности комбинацию Nginx+PHP-FPM, а комбинации Nginx+Apache+PHP-FPM уступает, но не значительно. Обработчик LSAPI входит в модуль интеграции CloudLinux, который доступен в ISPmanager Business.
Комплексное тестирование
Для комплексной оценки хостера требуется оценить стабильность (uptime сервера), скорость отклика сайтов и работу техподдержки.
Для тестирования я установил CMS WordPress 5.7 на оба хостинга, причем на Hostiman я сделал сразу 2 сайта с разными плагинами кэширования, чтобы посмотреть разницу. Эта CMS была выбрана как наиболее популярная и в то же время достаточно требовательная с точки зрения ресурсов.
Тестирование стабильности
Тестирование длилось месяц. Доступность сайтов мониторилась с помощью бесплатного сервиса UptimeRobot, который раз в 5 мин делает запрос по выбранному протоколу к сайту и проверяет ответ. Результаты аптайма следующие:
- M-hoster — 99,97-99.98% (для разных сайтов). Используется «Медная фольга» (Москва).
- Hostiman — 100%. Используется ДЦ Selectel (Москва).
На мой взгляд Selectel выглядит более привлекательным.
Тестирование производительности
В этом тесте я оценил скорость отклика сервера в милисекундах, а также производительность PHP в эталонных тестах.
Время отклика оценивалось также через сервис UptimeRobot и через аналитический сайт WebPageTest.
Время отклика через UptimeRobot:
- M-hoster — среднее 1475 мс, типовое 1305 мс (плагин W3 Total cache)
- Hostiman — среднее 815 мс, типовое 740 мс (сайт с плагином W3 Total cache); среднее — 1134 мс, типовое — 820 мс (плагин WP Super Cache). Плагин WP Fastest cache показал еще более плохие результаты.
Затем я протестировал первичный отклик и выдачу контента одинаковых сайтов с двух серверов.
- M-hoster: первый байт — 0,381 мс, загрузка основного контента — 1,040 мс, полная загрузка страницы — 3.029 мс
- Hostiman: первый байт — 0,193 мс, загрузка основного контента — 0,718 мс, полная загрузка — 2,592 мс.
По результатам видно, что во всех тестах Hostiman имеет превосходство на 30-50%.
Для оценки производительности PHP использовались свободно распространяемые нагрузочные вычислительные тесты:
Для интереса я также запускал один и тот же скрипт с разными версиями PHP в LSAPI. Результаты следующие:
M-hoster:
-------------------------------------- | PHP BENCHMARK SCRIPT | -------------------------------------- Start : 2021-03-22 13:28:35 Server : hosting.hww.ru@127.0.0.1 PHP version : 5.5.38 Platform : Linux -------------------------------------- test_math : 1.057 sec. test_stringmanipulation : 1.124 sec. test_loops : 0.843 sec. test_ifelse : 0.630 sec. -------------------------------------- Total time: : 3.654 sec. -------------------------------------- | PHP BENCHMARK SCRIPT | -------------------------------------- Start : 2021-03-22 13:30:36 Server : hosting.hww.ru@127.0.0.1 PHP version : 7.3.26 Platform : Linux -------------------------------------- test_math : 0.245 sec. test_stringmanipulation : 0.346 sec. test_loops : 0.242 sec. test_ifelse : 0.178 sec. -------------------------------------- Total time: : 1.011 sec. -------------------------------------- | PHP BENCHMARK SCRIPT | -------------------------------------- Start : 2021-03-22 13:41:35 Server : hosting.hww.ru@127.0.0.1 PHP version : 7.4.14 Platform : Linux -------------------------------------- test_math : 1.155 sec. test_stringmanipulation : 0.345 sec. test_loops : 0.152 sec. test_ifelse : 0.307 sec. -------------------------------------- Total time: : 1.959 sec.
Мы видим, что самая быстрая версия PHP 7.3.26, результат — 1.011 секунды. В ней же протестируем с сервер Hostiman:
-------------------------------------- | PHP BENCHMARK SCRIPT | -------------------------------------- Start : 2021-03-22 13:51:44 Server : h2.ipnets.ru@127.0.0.1 PHP version : 7.3.26 Platform : Linux -------------------------------------- test_ifelse : 0.122 sec. test_loops : 0.138 sec. test_stringmanipulation : 0.199 sec. test_math : 0.162 sec. -------------------------------------- Total time: : 0.621 sec.
Время — 0,621 секунда, что на 40% быстрее.
Далее для подтверждения результатов выполним более тяжелый нагрузочный тест. Ограничим его 256 МБ памяти и временем исполнения 60 секунд.
M-hoster:
------------------------------------------------------------------------------------------- | PHP BENCHMARK SCRIPT | ------------------------------------------------------------------------------------------- Start : 2021-03-22 13:56:00 Server : Linux/3.10.0-962.3.2.lve1.5.42.el7.x86_64 x86_64 Platform : Linux System : Linux CPU : model : Intel(R) Xeon(R) CPU E5-2697 v2 @ 2.70GHz cores : 12 available : 48 MHz : 3203.613MHz Memory : 256 Mb available Benchmark version : 1.0.37 PHP version : 7.3.26 available modules : mbstring : yes json : yes pcre : yes Max execution time : 60 sec Crypt hash algo : MD5 ------------------------------------------------------------------------------------------- TEST NAME : SECONDS | OP/SEC | OP/SEC/MHz | MEMORY ------------------------------------------------------------------------------------------- 01_math : 1.763 sec | 366.42 kOp/s | 114.38 Ops/MHz | 2 Mb 02_string_concat : 0.408 sec | 12.18 MOp/s | 3.80 kOps/MHz | 84.64 Mb 03_1_string_number_concat : 1.408 sec | 2.29 MOp/s | 715.99 Ops/MHz | 4 Mb 03_2_string_number_format : 1.434 sec | 2.25 MOp/s | 703.03 Ops/MHz | 4 Mb 04_string_simple_functions : 1.453 sec | 577.79 kOp/s | 180.36 Ops/MHz | 4 Mb 05_string_multibyte : 1.103 sec | 76.10 kOp/s | 23.75 Ops/MHz | 4 Mb 06_string_manipulation : 3.258 sec | 257.70 kOp/s | 80.44 Ops/MHz | 4 Mb 07_regex : 2.126 sec | 395.04 kOp/s | 123.31 Ops/MHz | 4 Mb 08_1_hashing : 2.537 sec | 330.98 kOp/s | 103.31 Ops/MHz | 4 Mb 08_2_crypt : 7.090 sec | 910.95 Op/s | 0.28 Ops/MHz | 4 Mb 09_json_encode : 2.665 sec | 315.05 kOp/s | 98.34 Ops/MHz | 4 Mb 10_json_decode : 3.987 sec | 210.62 kOp/s | 65.74 Ops/MHz | 4 Mb 11_serialize : 1.708 sec | 491.50 kOp/s | 153.42 Ops/MHz | 4 Mb 12_unserialize : 2.184 sec | 384.48 kOp/s | 120.02 Ops/MHz | 4 Mb 13_array_fill : 2.207 sec | 14.61 MOp/s | 4.56 kOps/MHz | 12 Mb 14_array_range : 0.714 sec | 90.34 kOp/s | 28.20 Ops/MHz | 12 Mb 14_array_unset : 1.820 sec | 17.72 MOp/s | 5.53 kOps/MHz | 12 Mb 15_loops : 0.926 sec | 139.57 MOp/s | 43.57 kOps/MHz | 4 Mb 16_loop_ifelse : 0.607 sec | 53.21 MOp/s | 16.61 kOps/MHz | 4 Mb 17_loop_ternary : 1.627 sec | 19.85 MOp/s | 6.20 kOps/MHz | 4 Mb 18_1_loop_defined_access : 0.446 sec | 28.96 MOp/s | 9.04 kOps/MHz | 4 Mb 18_2_loop_undefined_access : 3.532 sec | 3.66 MOp/s | 1.14 kOps/MHz | 4 Mb 19_type_functions : 0.807 sec | 2.40 MOp/s | 749.28 Ops/MHz | 4 Mb 20_type_conversion : 0.801 sec | 2.42 MOp/s | 755.32 Ops/MHz | 4 Mb 21_0_loop_exception_none : 0.035 sec | 73.88 MOp/s | 23.06 kOps/MHz | 4 Mb 21_1_loop_exception_try : 0.037 sec | 70.73 MOp/s | 22.08 kOps/MHz | 4 Mb 21_2_loop_exception_catch : 1.241 sec | 2.08 MOp/s | 649.79 Ops/MHz | 4 Mb 22_loop_null_op : 1.218 sec | 26.52 MOp/s | 8.28 kOps/MHz | 4 Mb 23_loop_spaceship_op : 1.122 sec | 28.79 MOp/s | 8.99 kOps/MHz | 4 Mb 26_1_class_public_properties : 0.084 sec | 38.24 MOp/s | 11.94 kOps/MHz | 4 Mb 26_2_class_getter_setter : 0.395 sec | 8.17 MOp/s | 2.55 kOps/MHz | 4 Mb 26_3_class_magic_methods : 0.785 sec | 4.12 MOp/s | 1.28 kOps/MHz | 4 Mb ------------------------------------------------------------------------------------------- Total time: : 51.530 sec | 7.55 MOp/s | 2.36 kOps/MHz | Current PHP memory usage: : 4 Mb Peak PHP memory usage: : 81.29 Mb
Выполнение теста заняло 51,5 секунды с скоростью 7,55 миллионов операций в секунду.
Hostiman:
------------------------------------------------------------------------------------------- | PHP BENCHMARK SCRIPT | ------------------------------------------------------------------------------------------- Start : 2021-03-22 13:54:24 Server : Linux/3.10.0-962.3.2.lve1.5.28.el7.x86_64 x86_64 Platform : Linux System : Linux CPU : model : Intel(R) Xeon(R) CPU E3-1270 v6 @ 3.80GHz cores : 4 available : 8 MHz : 3999.926MHz Memory : 256 Mb available Benchmark version : 1.0.37 PHP version : 7.3.26 available modules : mbstring : yes json : yes pcre : yes Max execution time : 60 sec Crypt hash algo : MD5 ------------------------------------------------------------------------------------------- TEST NAME : SECONDS | OP/SEC | OP/SEC/MHz | MEMORY ------------------------------------------------------------------------------------------- 01_math : 1.290 sec | 522.50 kOp/s | 130.63 Ops/MHz | 2 Mb 02_string_concat : 0.018 sec | 287.66 MOp/s | 71.92 kOps/MHz | 2 Mb 03_1_string_number_concat : 0.012 sec | 286.60 MOp/s | 71.65 kOps/MHz | 2 Mb 03_2_string_number_format : 1.018 sec | 3.31 MOp/s | 827.84 Ops/MHz | 2 Mb 04_string_simple_functions : 1.218 sec | 719.08 kOp/s | 179.77 Ops/MHz | 2 Mb 05_string_multibyte : 1.432 sec | 61.19 kOp/s | 15.30 Ops/MHz | 2 Mb 06_string_manipulation : 1.985 sec | 441.40 kOp/s | 110.35 Ops/MHz | 2 Mb 07_regex : 1.648 sec | 531.45 kOp/s | 132.86 Ops/MHz | 2 Mb 08_1_hashing : 1.835 sec | 477.54 kOp/s | 119.39 Ops/MHz | 2 Mb 08_2_crypt : 5.498 sec | 1.23 kOp/s | 0.31 Ops/MHz | 2 Mb 09_json_encode : 4.067 sec | 215.40 kOp/s | 53.85 Ops/MHz | 2 Mb 10_json_decode : 3.041 sec | 288.07 kOp/s | 72.02 Ops/MHz | 2 Mb 11_serialize : 2.968 sec | 295.19 kOp/s | 73.80 Ops/MHz | 2 Mb 12_unserialize : 2.574 sec | 340.32 kOp/s | 85.08 Ops/MHz | 2 Mb 13_array_fill : 1.667 sec | 20.09 MOp/s | 5.02 kOps/MHz | 12 Mb 14_array_range : 0.415 sec | 161.48 kOp/s | 40.37 Ops/MHz | 12 Mb 14_array_unset : 1.614 sec | 20.76 MOp/s | 5.19 kOps/MHz | 12 Mb 15_loops : 0.749 sec | 179.92 MOp/s | 44.98 kOps/MHz | 6 Mb 16_loop_ifelse : 0.619 sec | 54.48 MOp/s | 13.62 kOps/MHz | 6 Mb 17_loop_ternary : 0.837 sec | 40.25 MOp/s | 10.06 kOps/MHz | 6 Mb 18_1_loop_defined_access : 0.373 sec | 36.16 MOp/s | 9.04 kOps/MHz | 6 Mb 18_2_loop_undefined_access : 4.931 sec | 2.73 MOp/s | 683.35 Ops/MHz | 6 Mb 19_type_functions : 1.115 sec | 1.81 MOp/s | 453.16 Ops/MHz | 6 Mb 20_type_conversion : 1.052 sec | 1.92 MOp/s | 480.39 Ops/MHz | 6 Mb 21_0_loop_exception_none : 0.018 sec | 153.39 MOp/s | 38.35 kOps/MHz | 6 Mb 21_1_loop_exception_try : 0.029 sec | 91.54 MOp/s | 22.89 kOps/MHz | 6 Mb 21_2_loop_exception_catch : 1.576 sec | 1.71 MOp/s | 427.64 Ops/MHz | 6 Mb 22_loop_null_op : 1.056 sec | 31.92 MOp/s | 7.98 kOps/MHz | 6 Mb 23_loop_spaceship_op : 1.111 sec | 30.32 MOp/s | 7.58 kOps/MHz | 6 Mb 26_1_class_public_properties : 0.068 sec | 49.20 MOp/s | 12.30 kOps/MHz | 6 Mb 26_2_class_getter_setter : 0.214 sec | 15.73 MOp/s | 3.93 kOps/MHz | 6 Mb 26_3_class_magic_methods : 0.462 sec | 7.30 MOp/s | 1.82 kOps/MHz | 6 Mb ------------------------------------------------------------------------------------------- Total time: : 46.510 sec | 8.72 MOp/s | 2.18 kOps/MHz | Current PHP memory usage: : 6 Mb Peak PHP memory usage: : 10.32 Mb
Тест выполнен за 46,5 секунд со скоростью 8,72 MOps, что на 10% быстрее.
Кроме того, обратите внимание на одну любопытную особенность — пиковое потребление памяти у M-hoster 81 Мбайт, а у Hostiman всего 10. Это говорит о том, что в первом случае процессор не успевает работать с памятью и данные кэшируются.
Работа техподдержки
Оценивалось время ответа на тикет, как новый, так и обновление старого.
- M-hoster: от 4 часов до 2 суток.
- Hostiman: 8-20 минут.
Итоги
По всем статьям нашего тестирования Hostiman выигрывает, причем местами вдвое. Мы видим, что как производительность, так и стабильность выше. Намного лучше работают и сотрудники техподдержки. Я однозначно выбираю его для своих будущих проектов.
Кроме того, обобщая итоги тестирования, хочу сделать один немаловажный вывод: для производительности современных сайтов наиболее критичная производительность процессора. M-hoster значительно проиграл потому, что использует старый процессор Intel Xeon E5-2697 v2 2013 года выпуска, который неоптимально работает с потоками и набором команд, не поддерживается SSE последних версий. Также видно, что столько много ядер требуется хостеру потому, что он всех клиентов повесил на один сервер. Важно и с каким типом памяти работает процессор. Эта модель поддерживает только DDR3.
У Hostiman процессор младшей серии, но последних поколений, 2017 года выпуска. Xeon E3-1270 v6 имеет как большую номинальную частоту, так и поддерживает набор команд SSE 4.2, что значительно ускоряет некоторые математические операции, в частности, сортировку.
Следующим выводом отмечу, что теперь стоит обращать внимание только на те хостинги, которые используют диcки NVMe. А вот как раз объем оперативной памяти не важен, важно то, сколько памяти выделено на процесс в конфигурации.