<html><body><div style="font-family: arial, helvetica, sans-serif; font-size: 10pt; color: #000000"><div data-marker="__QUOTED_TEXT__"><div style="font-family: arial, helvetica, sans-serif; font-size: 10pt; color: #000000"><div></div></div>Gena Makhomed Wrote:<br>-------------------------------------------------------<br>> On 19.02.2024 16:01, Anatoliy Melnik via nginx-ru wrote:<br>> <br>> >>>> Если вы предлагаете писать напрямую с nginx-а в файл --<br>> >>>> сделайте у себя ротацию файлов с интервалом 30 сек<br>> >>>> при 200-250 тыс подключений/сек...<br>> >>>><br>> >>>> Если у вас уже есть такое рабочее решение -<br>> >>>> поделитесь опытом, буду рад вас выслушать.<br>> >>><br>> >>> Я намеренно ввел вас в заблуждение путем публикации сообщения,<br>> >>> допускающее двойное толкование в ту или иную сторону по желанию<br>> >>> сторон.<br>> >><br>> >> Почему / зачем?<br>> > <br>> > Был шанс увидеть в ответ нестандартное решение.<br>> <br>(мантры про логи...)<br>> <br>> Какое именно "нестандартное решение" для вышеобозначенной проблемы<br></div><div data-marker="__QUOTED_TEXT__">(мантры....)</div><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">Если вам его не видно -- это не значит, что его нет.<br>Тот же костыль из юникс-сокета у меня в "альфа" версии на этапе проверки возможностей <br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">показал результат в 400тыс/сек с запасом.<br>Кстати от вас я так и не увидел ни одной ссылки на конкретные значения из вашего личного опыта.<br>Лично мой опыт показывает, что при значениях более 500тыс/сек  и примерно 1млн "живых" tcp сессий "падает" уже сама ось.<br>Если у вас есть конкретный пример, что на таком-то железе, такой-то оси вы "перевариваете" 1млн/сек -- отлично.<br>Если нет... Ну на нет и суда нет.<br><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__"><br>> <br>> >> С моей точки зрения более важным является обеспечение более<br>> высокой<br>> >> надежности работы системы, чтобы логи не терялись в процессе<br>> записи,<br>> >> чем экономия свободного места на диске и экономия ресурсов NVMe<br>> SSD.<br>> >><br>> >> Поэтому с моей точки зрения - я не могу признать решение<br>> >> через syslog и unix socket более оптимальным, чем вариант<br>> >> записи логов напрямую в файлы и ротации логов через SIGUSR1.<br>> >><br>> >> а ротацию логов можно делать и чаще, чем раз в 30 секунд,<br>> >> например, раз 15, или раз в 10 или даже раз в 5 секунд,<br>> >> если хочется уменьшить отставание статистики по времени.<br>> >><br>> >> По сути - лог-файл на диске - это можете воспринимать примерно,<br>> >> как то же самое, что и unix socket, только с буфером не в памяти,<br>> >> а в виде файла на диске и без существенных ограничений по размеру<br>> >> такого буфера, что будет лучше сглаживать всплески нагрузки<br>> >> и может позволить большую асинхронность между процессом<br>> >> записи информации в лог и процессом чтения информации<br>> >> из лога. А во всем остальном - никакой существенной<br>> >> разницы нет, учитывая только что запись логов в файлы<br>> >> меньше грузит процесор и использует немного больше<br>> >> свободного места на диске.<br>> >><br>> >> Но мне например, лучше чтобы процессор был немного свободнее,<br>> >> чем проистаивающее и никак не используемое место на диске.<br>> >><br>> >> Но самое главное - что запись логов в файлы не приводит к потере<br>> >> данных, а запись логов в unix socket может приводить к потерям<br>> >> даных, если читатель будет не успевать забирать данные из unix<br>> >> socket.<br>> >><br>> >> Более надежное и более простое решение, и более экономно<br>> >> расходующее процесор сервера - и будет более оптимальным.<br>> <br>> > пока я наблюдал скорее проблему "писатель не успевает записывать",<br>> > а не "читатель не успевает забирать".<br>> <br>> видимая Вами проблема "писатель не успевает записывать"<br>> вызвана именно тем, что "читатель не успевает забирать".<br></div><div data-marker="__QUOTED_TEXT__">> </div><div data-marker="__QUOTED_TEXT__">> Потому что когда у Вас был всего один читатель - он не успевал<br>> читать данные из syslog и поэтому у nginx не было никаких других<br>> вариантов, кроме как дропать часть сообщений. После того как вместо<br>> одного читателя Вы сделали 10 читателей - они начали успевать читать<br>> данные из syslog и проблема с потерей сообщений стала быть Вам не<br>> видна.<br>> </div><div data-marker="__QUOTED_TEXT__">Вы, как и всегда, имеете полное право на свое мнение.<br> <br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__"><br>> > Эта же проблема и при файлах присутствует -- NVME не у всех всегда<br>> везде.<br>> > Система дисковая как ни крути - общий ресурс, и если ее интенсивно<br>> нагрузить<br>> > чем-то еще логи тоже могут получить проблему читатель-писатель.<br>> <br>> На frontend-сервере, сеть может быть загружена на 100% передачей<br>> данных,<br>> и процессор может быть загружен на 100% шифрованием/расшифровской<br>> TLS.<br>> Дисковая подсистема может использоваться только для записи логов.<br>> <br>> нагружать дисковую подсистему чем-либо еще, крмое записи логов<br>> - нерационально, имеет смысл даже полностью выключить использование<br>> диска при проксировании, чтобы не было блокирования nginx на<br>> операциях<br>> дискового ввода-вывода и чтобы не было увеличения latency, когда<br>> этого<br>> можно очень просто ибежать:<br></div><div data-marker="__QUOTED_TEXT__">> <br>> proxy_http_version 1.1;<br>> proxy_request_buffering off;<br>> proxy_max_temp_file_size 0;<br>> <br></div><div data-marker="__QUOTED_TEXT__">> По поводу того, что сейчас NVMe есть не у всех и не всегда<br>> - это Вы мне сейчас из какого года свое сообщение пишете ?<br></div><div data-marker="__QUOTED_TEXT__"><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">Вы, как и всегда, имеете полное право на свое мнение.<br>Свой набор критериев оптимальности и эффективности. <br></div><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div></div><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">> <br>> > Единственный плюс прямой записи в файл -- это длительное хранение<br>> данных, чего лично мне вот вообще не требуется.<br>> <br>> У Вас очень специфически задачи. Потому что как правило логи нужны.<br><br></div><div data-marker="__QUOTED_TEXT__">Что и было описано еще в самом начале.<br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__"><br>> Потому что если логи не нужны - их просто выключают для 1хх, 2хх<br>> и 3хх статусов и логгируют только 4хх и 5хх ошибки, так что размер<br>> лог-файлов получается очень небольшим и никаких проблем создать не<br>> может.<br>> <br>> map $status $loggable {<br>>      ~^[45]  1;<br>>      default 0;<br>> }<br>> access_log /path/to/access.log combined if=$loggable;<br>> <br>> >> Вот как я уже говорил, задача построения VPN - если взять все<br>> множество<br>> >> таких задач, то в части случаев для построения VPN более<br>> оптимальным<br>> >> вариантом будет использование WireGuard, а в части случаев -<br>> OpenVPN.<br>> >> Именно потому, что WireGuard обладает некоторыми свойствами<br>> >> и качествами, которые отсутствуют в OpenVPN, и наоборот,<br>> >> потому что OpenVPN обладает некоторыми свойствами и качествами,<br>> >> которые отсутствуют в WireGuard. И поэтому в части случаев<br>> >> оказывается более оптимальным и целесообразным построение<br>> >> VPN с использованием WireGuard, а в некоторых случаях<br>> >> - более оптимальнныи и целесообразным оказывается<br>> >> построение VPN с использованием OpenVPN.<br>> >><br>> > И в части случаев оба они окажутся в равной степени не пригодны...<br>> > Да и там, где пригодны, далеко не всегда оптимальны по каким-то<br>> критериям.<br>> > VPN технологий существуют десятки. Но вы почему-то в этом посте<br>> ограничились 2-мя.<br>> > А как же "все множество путей" ?<br>> > Эти 2 достаточно удобны для решения большого круга задач -- это да,<br>> но это не отменяет достоинств других VPN-ов.<br>> <br>> Я рассматриваю только те реализации VPN, которые доступны<br>> в виде open source, и которые доступны для использования,<br>> без необходимости покупать лицензию на право использования<br>> программы.<br>> <br>> Все другие варианты Open Source VPN имеет смысл рассматривать<br>> только в том случае, если они имеют какие-то преимущества,<br>> по сравнению с WireGuard и OpenVPN. Если у них никаких<br>> преимуществ нет - тогда их можно и не рассматривать.</div><div data-marker="__QUOTED_TEXT__">> <br>> Еще есть Shadowsocks, если необходимо обходить<br>> блокировки WireGuard и OpenVPN через DPI,<br>> но это очень специфическая задача.</div><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">В openssh-е есть "встроенный" socks5. Можно вообще без дополнительного ПО обойтись.<br>Довольно долгое время вообще ppp over ssh пользовался и более чем устраивало.<br>Но опять же.<br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">Вы, как и всегда, имеете полное право на свое мнение.<br>Свой набор критериев оптимальности и эффективности. </div><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">> <br>> WireGuard и OpenVPN - это две наиболее надежные<br>> по качеству кода и наиболее проверенные аудитами<br>> реализации VPN. По этому парметру - все остальные<br>> реализации и варианты VPN - значительно хуже.<br>> <br>> Например, в самом протоколе IPsec или в его популярных реализациях<br>> могут быть закладки от NSA, поэтому IPsec лучше не использовать.<br>> https://en.wikipedia.org/wiki/IPsec#Alleged_NSA_interference<br>> </div><div data-marker="__QUOTED_TEXT__">> >> Так ведь свободное место на разделе есть, с этим же нет проблем.<br>> <br>> > Есть проблема.<br>> > В исходной постановке (когда сия задача встала передо мной) задачи<br>> было пожелание обойтись имеющимся ресурсом.<br>> > Я задачу решил именно в этих начальных условиях.<br>> <br>> Как правило, свободное место на диске - это самый дешевый ресурс.<br>> И экономить место на диске, увеличивая нагрузку на процессор,<br>> или теряя часть сообщений - это не самое лучшее решение.</div><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">Вы, как и всегда, имеете полное право на свое мнение.<br>Свой набор критериев оптимальности и эффективности. </div><div data-marker="__QUOTED_TEXT__"><br>> <br>> >>> с моей точки зрения менять одну проблему на другую смысла нет<br>> >><br>> >> использование места на диске - это не проблема, это необходимая<br>> плата<br>> >> за то, что запись в логи будет происходить без потерь информации,<br>> >> и что чтения и обработка информации из логов не обязаны быть<br>> >> такими синхронными и производительными, как в случае с unix<br>> >> socket`ами.<br>> >><br>> > Обязаны! и синхронными и производительными.<br>> > Если статистика будет накапливаться быстрее, чем обрабатываться, то<br>> данные никогда не будут актуальны.<br>> > Т.е. я сегодня увижу статистику за вчера, а за сегодня-- только<br>> через 2 дня, а к концу года буду видеть уже с отставанием в месяц??<br>> > И кому это будет интересно??<br>> <br>> Вы меня не поняли.<br>> <br>> Если использовать unix socket - при переполнении буфера<br>> в памяти происходит потеря части сообщений. Если в условиях<br>> постановки задачи важно не терять сообщения - тогда читатель<br>> сообщений должен быть таким же производительным и как писатель.<br>> <br>> Иногда, во время DDoS-атак приходит огромное количество запросов,<br>> так что процессор может быть занят на 100% и просто не остается<br>> на сервере процессорных мощностей для того, чтобы читатель<br>> с другой стороны unix socket`а успевал бы считывать данные<br>> с такой же скоростью, с какой их будет писать туда nginx.<br>> А это означает, что такая ситуация неизбежно приведет<br>> к потере части сообщений, которые nginx будет вынужден<br>> дропать потому что читатель не успевает их читать<br>> с другой стороны unix socket`а.<br>> <br>> Мне такое нестабильно работающее и ненадежное решение не нужно,<br>> которое вроде бы нормально работает под небольшой нагрузкой,<br>> но начинает глючить и терять сообщения, когда нагрузка возрастает.<br>> <br>> Если же nginx пишет логи в файл - тогда такой высокой степени<br>> синхронности читателя и писателя логов не нужно, пототому что<br>> нет буфера в памяти, который очень быстро может переполниться,<br>> а есть просто файлы на диске, и читатель логов может читать их<br>> с постоянной скоростью, например, 1 мегабайт в секунду, и даже<br>> если будут всплески нагрузки на сервер и в какие-то моменты<br>> nginx будет писать логи со скоростью 10 или 100 мегабайт в секунду<br>> - это все равно не будет приводить к потере сообщений, потому что<br>> в этом случае нет небольшого буфера в оперативной памяти, а роль<br>> буфера выполняет фактически все свободное место на диске сервера.> <br>> И пиковые всплески нагрузки на сервер будут сглаживаться с помощью<br>> очень большого "буфера" на диске, и потери сообщений тогда не будет.<br>> <br>> То есть, при всех прочих условиях, более надежная и более устойчивая<br>> к всплескам нагрузки система обработки логов nginx которая не теряет<br>> сообщения является более предпочтительной, чем та система, которая<br>> теряет часть сообщений в процессе работы при всплесках нагрузки.<br></div><div data-marker="__QUOTED_TEXT__">> <br>> В большинстве случаев потери сообщений недопустимы<br>> или крайне нежелательны, поэтому запись сообщений<br>> напрямую в лог-файлы, без дополнительных костылей<br>> через syslog и unix socket`ы практически всегда<br>> будет более предпочительным вариантом.<br>> <br>> Тем более, что работающее решение для ротации логов nginx<br>> при 200-250 тысячах подключений в секунду и интервале ротации<br>> раз в 30 секунд можно очень легко получить, заменив SIGHUP на<br>> SIGUSR1.<br>> Это есть ответ на тот Ваш вопрос о решении Вашей настоящей проблемы<br>> X,<br>> который приведен в самом начале этого сообщения.<br>> <br></div><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__"><div data-marker="__QUOTED_TEXT__"><div data-marker="__QUOTED_TEXT__">Вы, как и всегда, имеете полное право на свое мнение.<br>Свой набор критериев оптимальности и эффективности. <br></div><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div></div></div><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">> > Итоги разных экспериментов:<br>> > Исходные данные - CPU Xeon E5-26xx v4 CPU 2.2GHz<br>> > Для наглядности привожу данные по 1 вычислительному ядру.<br>> > Итак, на 1 вычислительное ядро<br>> > --- Существующий на данный момент бекэнд, куда nginx у меня<br>> проксирует запросы -- максимум около 2000 в секунду на одно ядро<br>> (вообще не моя епархия, но там точно НЕ php).<br>> > --- NGINX для теста, на который отзеркалированы запросы, вся его<br>> функция -- выдать ответ "200" и сообщение в лог записать, все,<br>> никакого проксирования или отдачи контента,<br>> > никаких вычислений и т.д. Голый "200" + строка в лог-файле<br>> средствами nginx-а, ротация 10 секунд с удалением результата. ---<br>> максимум примерно 10 000 в секунду на 1 ядро<br>> > --- парсинг данных из лога, накопленного за 60 секунд из расчета<br>> нагрузки 400тыс/сек, т.е. 24млн строк. -- на одном ядре от 8 минут. в<br>> зависимости от нагрузки на дисковую подсистему 8-9 минут. т.е. при<br>> среднем 500секунд 48 000 в секунду на одно ядро.<br>> > --- Обработка через юникс-сокет "на лету" python3.9 скриптом -- 43<br>> 000 в секунду на одно ядро 100% соответствие результатов, около 89-92%<br>> занятость ядра CPU.<br>> > <br>> > Итого технически "самый быстрый" -- парсинг лога, но тянет за собой<br>> запись-чтение-удаление при относительном преимуществе 9-12% и<br>> > зависимости результата от файлового ввода-вывода.<br>> <br>> парсинг лога не только самый быстрый, он еще и самый надежный,<br>> потому что в этом варианте нет потери сообщений. - Собственно,<br>> о чем я Вам и говорил, что это есть самый оптимальный вариант.<br>> <br>> нагрузку на сеть можно уменьшить, включив HTTP/1.1 и keepalive<br>> при подключении к backend`у - это если делать обработку логов<br>> именно через mirror на специально выделенный для этой задачи сервер.<br>> <br>> Вы же не рассмотрели вариант, когда nginx сам пишет логи напрямую<br>> в файл, например, блоками по 1 мегабайту, делая всего один системный<br>> вызов для записи одного такого блока информации. Насколько<br>> я понимаю, при N рабочих процессах nginx для этого потребуется<br>> дополнительно всего лишь только N мегабайт оперативной памяти.<br>> Но в результате - получим значительное уменьшение расходования<br>> процессора на запись логов и значительно меньшее количество<br>> операций переключения контекста, ведь по умолчанию вызывается<br>> операция записи для каждой строчки лога.<br></div><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">Вы, как и ранее, совершенно спокойно решаете за меня что я делал, а чего не делал.<br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">Еще на старте я указал, что<br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">"долго, кучно, с кучей подробностей.... и абсолютно бесполезно."<br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">Вы с блеском подтвердили этот тезис.<br>Дальнейшее обсуждение не имеет смысла.<br></div><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">> <br>> > Таким образом единственный сколь-нибудь существенный бонус -<br>> потенциальная полнота данных для обработки перестает быть<br>> существенным, когда считаем<br>> > усредненные данные на миллионных выборках.<br>> <br>> полнота даных для обработки - как правило это важно.<br>> <br>> если Вам нужны усредненные данные на милионных выборках -<br>> тогда с технической точки зрения, самым оптимальным вариантом<br>> будет написать модуль для nginx, который будет делать эту работу<br>> на лету и практически мгновенно и практически с 0 затратами ресурсов.<br></div><div data-marker="__QUOTED_TEXT__"><br></div><div data-marker="__QUOTED_TEXT__">Ок. Встанет перед вами такая задача -- вы выберете соответствующий путь ее решения.<br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">> <br>> > Не знаю насколько эффективен будет Go.<br>> <br>> Go создан достаточно умными людьми,<br>> такими как Роб Пайк, один из создателей кодировки UTF-8.<br>> <br>> Go позволяет сделать concurrency используя goroutines и channels,<br>> и этот язык программирования, созданный в Google практически<br>> идеально подходит для работы в состоянии высоких нагрузок,<br>> позволяя быстро писать быстрый, качественный и надежный код,<br>> который легко справляться даже с очень высокими нагрузками.</div><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">Без проблем -- пишете, тестируете, выкладываете сюда сравнительные результаты.</div><div data-marker="__QUOTED_TEXT__">С числами, процентами, погрешностями и т.д. в конкретной задаче.<br><br></div><div data-marker="__QUOTED_TEXT__">> <br>> Если производиельности которую дает Go будет не хватать,<br>> тогда остается только Rust, C++ и C, но обычно - дешевле<br>> и проще будет просто горизонтальное масштабирование,<br>> путем увеличения количества серверов для вебсайта.<br>> <br>> Если нет highload, тогда удобнее и приятнее Python,<br>> и скорость написания кода будет выше, но скорость<br>> работы кода будет ниже - вот такой тут trade-off.<br>> </div><div data-marker="__QUOTED_TEXT__">> > Он должен на порядок превосходить какой-нибудь php<br>> <br>> Он превосходит. Поэтому практически весь highload делают<br>> сейчас именно на Go а не на PHP, если есть возможность выбора<br>> и нет необходимости работать с большим количеством legacy кода.<br></div><div data-marker="__QUOTED_TEXT__">"Он превосходит" и "он превосходит на порядок" -- несколько разные формулировки.<br>Но у вас есть возможность показать это практически -- пишете 2 реализации одного и тогоже функционала на Go и НЕ_Go,<br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">сравниваете, затем сравниваете с "тупо 200 всем прям с nginx-а" и обнародуете результат.<br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__"><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">На даном этапе лично я свой "костыль" довел до альфа-версии инвалидского кресла с моторчиком :)<br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">Проверяю возможность автоматического противодействия ДДоС-у почти в реальном времени.<br>Но это уже совсем другая история.<br><br data-mce-bogus="1"></div><div data-marker="__QUOTED_TEXT__">> <br>> -- <br>> Best regards,<br>>   Gena<br>> <br>> _______________________________________________<br>> nginx-ru mailing list<br>> nginx-ru@nginx.org<br>> https://mailman.nginx.org/mailman/listinfo/nginx-ru<br><br><br><br></div></div></body></html>