Нужно слушать порт, залогировать HTTP-запрос и отдать статический HTTP-ответ не зависимо от параметров запроса. Тащить nginx как бы оверхед.
Вопрос такой: как сделать настолько быстрое и незатратное (по ресурсам) решение, насколько это возможно?
Пока оставим вопрос логирования (там имеет смысл накапливать данные в памяти, а не сразу писать на диск). Вопрос по прослушке порта, а именно как лучше это делать?
Тот же nginx для Windows использует WSASocketW вроде.
Для Unix вроде netinet/tcp.h — какой-то не блокирующий или вроде того. Кто может подробнее об этом рассказать? Так же не плохо бы увидеть пример простого прослушивания при минимально возможных затратах ресурсов.
Здравствуйте, Shmj, Вы писали:
S>Нужно слушать порт, залогировать HTTP-запрос и отдать статический HTTP-ответ не зависимо от параметров запроса. Тащить nginx как бы оверхед.
Здравствуйте, Слава, Вы писали:
S>>Нужно слушать порт, залогировать HTTP-запрос и отдать статический HTTP-ответ не зависимо от параметров запроса. Тащить nginx как бы оверхед. С>Возьмите tinyhttpd
Все равно оверхед. И не ясно действительно ли он выжимает все.
Здравствуйте, Shmj, Вы писали:
S> Все равно оверхед. И не ясно действительно ли он выжимает все.
Не очень понятно — нужно "выжать все" или сделать минимальное решение? Для второго можно посмотреть на libmicrohttpd. Для первого ставить nginx (или любой другой веб-сервер из понравившегося бенчмарка) и не тратить свое время.
Здравствуйте, Shmj, Вы писали:
S>Нужно слушать порт, залогировать HTTP-запрос и отдать статический HTTP-ответ не зависимо от параметров запроса. Тащить nginx как бы оверхед.
S>Вопрос такой: как сделать настолько быстрое и незатратное (по ресурсам) решение, насколько это возможно?
Тащить nginx.
И для Windows, и для Unix (Linux & etc) — на самом деле есть очень много нюансов в решении такой простой задачи.
S>Пока оставим вопрос логирования (там имеет смысл накапливать данные в памяти, а не сразу писать на диск). Вопрос по прослушке порта, а именно как лучше это делать?
Если задаешь такой вопрос, то через какое-либо готовое решение.
Если ну очень сильно хочется самому, то посмотри в сторону libuv/libev/libevent — в них большая часть граблей будет решена за тебя.
S>Тот же nginx для Windows использует WSASocketW вроде.
nginx для Windows не слишком эффективен, почти хрестоматийный пример, что авторы не стали связывается с полноценной кроссплатформенной реализацией, а сделали упор на Unix-ах.
А WSA — "windows socket api", всё имеющее этот префикс в Unix отсутствует. Хотя сами функции во делались на основе сокетов Unix-а, и во многих местах схожи.
S>Для Unix вроде netinet/tcp.h — какой-то не блокирующий или вроде того. Кто может подробнее об этом рассказать? Так же не плохо бы увидеть пример простого прослушивания при минимально возможных затратах ресурсов.
tcp.h — это, что называется, "другое".
Рассказано почти в любой книжке по программированию в Linux/Unix в разделе сетевое программирование/работа с сетью/сокеты — ну не пересказывать же?
Простые примеры имеют ограниченную работоспособность. Где-то не используется REUSEADDR, где-то проблемы с блокировками. Я бы всё-же не советовал лезть в этот API, тем более по примерам кода с форумов.
Здравствуйте, m2l, Вы писали:
m2l>А WSA — "windows socket api", всё имеющее этот префикс в Unix отсутствует. Хотя сами функции во делались на основе сокетов Unix-а, и во многих местах схожи.
В винде вполне себе совместимое бсд сокет апи. А WSA* — это уже про асинхронщину, и про то, чтобы кинуть окошку сообщение, если что-то на сокет пришло, и тд, и тп. На голых сокетах асинхронщина делается также, как и в *никсах. Хотя poll/epoll нет, но оно и в *никсах не всегда бывает. Аналога WSA* в голых *никсах нету никакого.
Здравствуйте, Marty, Вы писали:
m2l>>А WSA — "windows socket api", всё имеющее этот префикс в Unix отсутствует. Хотя сами функции во делались на основе сокетов Unix-а, и во многих местах схожи.
M>В винде вполне себе совместимое бсд сокет апи. А WSA* — это уже про асинхронщину, и про то, чтобы кинуть окошку сообщение, если что-то на сокет пришло, и тд, и тп. На голых сокетах асинхронщина делается также, как и в *никсах. Хотя poll/epoll нет, но оно и в *никсах не всегда бывает. Аналога WSA* в голых *никсах нету никакого.
А с чём ты не согласен в моём утверждении?
BSD-совместимое? Да, но это socket/recv/send, а не WSASocket/WSASend/WSARecv что хорошо видно по их сигнатурам. При этом, при передаче 0/NULL в доп-параметры WSA* они ведут себя почти так-же, как socket/recv и т.д — поэтому утверждение, что WSA* про асинхронщину — ложное. Что аналога нет я написал в первом предложении. И, если уж на то пошло, то там есть мелкие различия поведения вроде shutdown/close и close или с работой того же select, к которому ты апеллируешь. Насчет poll — мягко скажем, лучше обходить стороной, а epoll есть только в Linux, но зато во всех мейнстримных дистрибутивах последних 10+ лет.
Здравствуйте, Shmj, Вы писали:
S>Нужно слушать порт, залогировать HTTP-запрос и отдать статический HTTP-ответ не зависимо от параметров запроса. Тащить nginx как бы оверхед.
S>Вопрос такой: как сделать настолько быстрое и незатратное (по ресурсам) решение, насколько это возможно? S>Пока оставим вопрос логирования (там имеет смысл накапливать данные в памяти, а не сразу писать на диск). Вопрос по прослушке порта, а именно как лучше это делать? S>Тот же nginx для Windows использует WSASocketW вроде.
Так в чём вопрос в итоге? Sockets API?
S>Для Unix вроде netinet/tcp.h — какой-то не блокирующий или вроде того. Кто может подробнее об этом рассказать? Так же не плохо бы увидеть пример простого прослушивания при минимально возможных затратах ресурсов.
netinet/tcp.h это о внутренних структурах TCP, а не о пользовательском интерфейсе.
Пользовательский всё равно будет socket(), bind(), listen(), accept(), recv(), send(), и так далее.
Примеры — на каждом углу.
А вообще в качестве ответа за 5 минут на вопрос в таком виде — ответ — inetd! Ну или xinetd под некоторым линуксом.
И в качестве хэндлера шелл-скрипт типа
#!/bin/sh
while :; do
read LINE
echo $LINE >>$LOGFILE
if [ -z "$LINE" ]; then break; fi
done
echo HTTP/1.0 200 OK
echo
echo Денег нет, вы держитесь здесь, всего доброго, хорошего настроения, здоровья!
Здравствуйте, Shmj, Вы писали:
S>Нужно слушать порт, залогировать HTTP-запрос и отдать статический HTTP-ответ не зависимо от параметров запроса. Тащить nginx как бы оверхед. S>Вопрос такой: как сделать настолько быстрое и незатратное (по ресурсам) решение, насколько это возможно?
cpp-httplib — я использовал эту очень простую либу для одного своего хобби проекта.
Здравствуйте, m2l, Вы писали:
S>>Тот же nginx для Windows использует WSASocketW вроде. m2l>nginx для Windows не слишком эффективен, почти хрестоматийный пример, что авторы не стали связывается с полноценной кроссплатформенной реализацией, а сделали упор на Unix-ах. m2l>А WSA — "windows socket api", всё имеющее этот префикс в Unix отсутствует.
Ибо это гуано нафиг не нужно.
Современный веб-сервер для Линукса — это io_uring, и zero-copy сокеты, с ядерной поддержкой TLS (а на продвинутых картах — вообще аппаратной).
Здравствуйте, Shmj, Вы писали:
S>Нужно слушать порт, залогировать HTTP-запрос и отдать статический HTTP-ответ не зависимо от параметров запроса. Тащить nginx как бы оверхед.
S>Вопрос такой: как сделать настолько быстрое и незатратное (по ресурсам) решение, насколько это возможно?
Здравствуйте, Cyberax, Вы писали:
m2l>>А WSA — "windows socket api", всё имеющее этот префикс в Unix отсутствует. C>Ибо это гуано нафиг не нужно.
Аргументов не будет?
C>Современный веб-сервер для Линукса — это io_uring, и zero-copy сокеты, с ядерной поддержкой TLS (а на продвинутых картах — вообще аппаратной).
WSASend/WSARecv на выровненных данных для асинхронного ввода-вывода, при соответствующем драйвере сетевой карты поддерживает zero-copy..... Это, к слову, насчёт твоей оценки WSASend.
C>Samba как пример: ...
Currently this implements SMB_VFS_{PREAD,PWRITE,FSYNC}_SEND/RECV and avoids the overhead of the userspace threadpool in the default vfs backend. See also vfs_io_uring(8).
Они пока ещё не до конца уверенны в себе и по дефолту не используют его, только если сам добавишь в конфиг, на свой страх и риск (не малый риск, если почитать release changes насчёт bugfix).
C>В Windows 11 добавили практически аналогичный API: https://windows-internals.com/ioring-vs-io_uring-a-comparison-of-windows-and-linux-implementations/
Справедливости ради, io_uring привнёс наконец то асинхронную работу через один интерфейс и с файлами и с сетью, чего раньше в linux не было. Но было в Windows как часть IOCP с Windows NT 3.5 ещё ~25 лет назад. Добавим возможность zero-copy буферов за счет усложнённой сигнатуры WSASend/WSARecv (хотя этим объективно практически никто не пользовался). Ещё можно вспомнить ядерную реализацию HTTPS в Windows — TLS в ядре не ново, и много споров вызывает. То по итогу ключевое нововведение io_uring — общая область памяти между сетевой картой, ядром и прикладным приложением. И такой подход при всех своих огромных плюсах на нагрузках вроде Netflix или Youtube имеют большой минус связанный с тем как всё это будет работать в моменты, когда эта общая область памяти фиксированного размера будут заканчивается (прикладной уровень, например не будет успевать обработать всё что к нему прилетело). Ядру и сетевой карте нужно будет гонять данные между временными буферами и т.д. — в граничных условиях этот интерфейс ещё несколько лет лучше не эксплуатировать.
PS. io_uring с ядерной поддержкой TLS ярко контрастирует с тем же QUIC, где всё пытаются наоборот засунуть всё в user-mode. Прямо такие противоположности и отличная тема для священных войн.
Здравствуйте, ononim, Вы писали:
C>>В Windows 11 добавили практически аналогичный API: https://windows-internals.com/ioring-vs-io_uring-a-comparison-of-windows-and-linux-implementations/ O>И оно прям сильно лучше чем RIO sockets, которые тоже все такие из себя zero-copy/no-syscall?
Утверждают, что да. RIO позволяет просто обойти всю машинерию с созданием IRP, которая в Винде очень дорогая. Но больше он ничего особо не даёт. Аналог io_uring ещё позволяет посылать асинхронно наборы команд.
Кроме того, текущая инфраструктура "TCP Chimney Offload" — тормозистор зачастую больший, чем просто обычное использование.
Здравствуйте, reversecode, Вы писали:
R>wsa работает на всех версиях винды R>а не ка ioring только на 11 R>народ начал мерить производительность io_ring/epoll и разницы особо не заметил
io_uring — это пока новое API, так что не все используют его правильно. В некоторых применениях (SMB, например) разница в разы.
Новые версии ядра добавляют ещё плюшек. Например, не нужно больше создавать новые файловые дескрипторы для простых операций (можно заранее создать пул и переиспользовать их). Это позволяет местами существенно увеличить производительность для серверов, обслуживающих тонны короткоживущих соединений.
нет сложности в использовании io_uring
а перформенс самбы очевиден, из за отсутствия асинхронного sendfile в линуксе
io_uring это как бы заменяет
а поскольку самба у нас file<->network сервер, вот поэтому и возросло
там же где нет файловых операций а только network-network там оно особо не дает выиграша
я было и сам думал что вот уменьшив количество сисколов и копирования данных юзер кернель юзер
даст прирост, но он ой какой маленький
может быть в каких то клаудах где терабитные трафики оно и сильно заметно
но на обычном хайлоаде, разницы особой нет
я бы даже сказал что выигрывают приложение где более оптимальные алгоритмы типа work stealing