Comments 82
Есть ли готовое демо чтобы «пощупать живьем»?
+3
Почему вы не использовали fastcgi++? Можно было не писать свой вебсервер, а просто использовать nginx, например.
+27
FastCGI, насколько я понял, даёт приложению взаимодействовать с веб-сервером через сокет. В моём случае, веб-приложение и веб-сервер становятся едины, и приложение запускается просто вызовом функции.
-1
Зачем вам единство с вебсервером? В этом больше минусов, чем плюсов.
Nginx можно настроить так, чтобы он кроме ваших приложений, обрабатывал и другие запросы. Кроме того, в случае с fastcgi при внесении изменений в приложение, достаточно пересобрать и перезапустить только приложение, а в вашем случае необходимо перезапускать весь вебсервер.
К тому же nginx намного больше протестирован, чем ваш сервер (к вопросу о безопасности).
Чем вам не нравится взаимодействие через unix сокет?
Nginx можно настроить так, чтобы он кроме ваших приложений, обрабатывал и другие запросы. Кроме того, в случае с fastcgi при внесении изменений в приложение, достаточно пересобрать и перезапустить только приложение, а в вашем случае необходимо перезапускать весь вебсервер.
К тому же nginx намного больше протестирован, чем ваш сервер (к вопросу о безопасности).
Чем вам не нравится взаимодействие через unix сокет?
+19
В моём веб-сервере тоже предусмотрена перезагрузка приложения (обновление и переподключение библиотеки одной командой).
Сам же веб-сервер я делал с учётом того, что возможно буду использовать его для работы с WebSocket (для создания браузерной сетевой игры), где количество человек может быть очень большим, поэтому был смысл экономить.
Сам же веб-сервер я делал с учётом того, что возможно буду использовать его для работы с WebSocket (для создания браузерной сетевой игры), где количество человек может быть очень большим, поэтому был смысл экономить.
0
PS: у unix сокета нет очередей, и если сокет «захлебнется» запросы уйдут в ошибку конекта.
Имхо, лучше по старому доброму tcp, даже на localhost.
Имхо, лучше по старому доброму tcp, даже на localhost.
0
Как же без очереди соединения с одного сокета разбирать? Очередь там есть и её размер регулируется
net.core.somaxconn
.Имхо, лучше по старому доброму tcp, даже на localhost.ИМХО очень вредный совет. Да, tcp легче переживает переполнение очередей, которых к тому же несколько, но это просто способ скрыть наличие проблемы, а не её решение. Если бэкенд захлебнулся, то фронтэнд должен сразу об этом узнать.
+2
Разница в быстродействии в коде, «вкомпиленом» в nginx и через FastCGI (например, fastcgipp) — раз в пять в пользу первого.
0
Разница в быстродействии отсутствует. От того, что код скомпилировать вместе с nginx, он не становится магическим образом быстрее. FastCGI позволяет изолировать код приложения от кода веб-сервера ценой небольших накладных расходов. Но конечно, если ваш код ничего не делает, кроме отдачи «hello world», то эти накладные расходы могут в 5 и более раз превысить расходы на выполнение приложения.
Возникает вопрос, нужно ли экономить на спичках? Чаще всего не нужно, а пытаясь этим заниматься, вы обретаете множество других проблем, гораздо серьезней, чем производительность, не говоря уж о в разы больших трудозатратах на написание и поддержку кода внутри nginx.
Возникает вопрос, нужно ли экономить на спичках? Чаще всего не нужно, а пытаясь этим заниматься, вы обретаете множество других проблем, гораздо серьезней, чем производительность, не говоря уж о в разы больших трудозатратах на написание и поддержку кода внутри nginx.
0
Я думаю, потому что на самом деле свой вебсервер писать не нужно, а нужно использовать в качестве базы готовые библиотеки (LibEvent, boost::asio, etc). А сервер в любом случае будет работать быстрее т.к. не тратится время на инициализацию. Nginx'у без разницы на что проксировать cgi или другой сервер.
Кроме того сервер даёт много дополнительных плюшек в виде понятного интерфейса, маршрутизации и т.п.
Кроме того сервер даёт много дополнительных плюшек в виде понятного интерфейса, маршрутизации и т.п.
+3
UFO just landed and posted this here
Ну конкретно в данном случае речь о создании чего то вроде фреймворка для написания сайтов на C++. Тот же
Статику отдавать такой сервер вообще не должен, по-моему. Для этого есть специально разработанные для этого решения вроде Nginx'а.
libevent.a
имеет размер 2.5Мб — даже на микроконтроллер засунуть можно, при определенных обстоятельствах.Статику отдавать такой сервер вообще не должен, по-моему. Для этого есть специально разработанные для этого решения вроде Nginx'а.
+1
Почему я не могу создавать высокопроизводительные веб-приложения на таком языке, как C++ (не CGI)? Ведь этот язык мне нравится больше всех других. Никогда не слышал о том, что бывают сайты, написанные на C++. Почему?есть и достаточно, очевидно плохо искал, сам тоже страдал велосипедостроением, но делал не через dll загрузку, а через компиляцию.
Почему веб-разработку захватили скриптовые (интерпретируемые) языки программирования?в разы проще разработка, большинству проектов вполне достаточно скорости скриптового языка.
возможно твой велосипед кому-то понадобиться, но принципиально есть nginx, который уже проверн сотнями проектов и позволяет проксировать fcgi/scgi/wcgi, есть достаточно библиотек, которые поддерживают эти протоколы.
+5
У меня эта функция не используется нигде, а используется такой вот «костыль». Суть которого делать select сразу нескольких сокетов, а не одного, как вы указали.
P.S. ссылки не печатаются мои в этом сообщении :(
P.S. ссылки не печатаются мои в этом сообщении :(
-2
После
#elif POSIX
логичнее было бы увидеть epool
-4
Суть в том, что использование select — очень плохая практика. На Windows следует использовать I/O completion ports, на Linux — epoll, на MacOS/FreeBSD — kqueue. В противном случае ваш сервер сможет нормально обслуживать только 3.5 соединения.
+4
Для любителя асемблера и нижнего уровня можно рекомендовать повеситься на сигналы/прерывания(юзерспейса).
А для винды есть «ламповы» WaitForMultipleObjectsEx (ну это лучше чем select)
А для винды есть «ламповы» WaitForMultipleObjectsEx (ну это лучше чем select)
0
Проблема не в уровне. Хоть в микрокомандах процессора в режиме ядра программируйте, это ничем не поможет Проблема в сложности алгоритма опроса. select работает за O(самый большой номер опрашиваемого файла), poll за O(число соединений), epoll, kqueue работают за O(1). I/O completion устроено принципиально иначе, но сложность от числа коннектов там тоже O(1). WaitForMultipleObjectsEx — аналог poll и тоже работает за O(n).
+1
Видимо, мне придётся переписывать алгоритм опроса сокетов на входящие соединения.
Событийно-ориентированная модель, значит.
Для Windows тогда придётся использовать WSAAsyncSelect. Для Linux — epoll. Ветвление алгоритмов для разных систем произойдёт обязательно, в этом случае, как бы я этого не избегал раньше.
Событийно-ориентированная модель, значит.
Для Windows тогда придётся использовать WSAAsyncSelect. Для Linux — epoll. Ветвление алгоритмов для разных систем произойдёт обязательно, в этом случае, как бы я этого не избегал раньше.
-1
select работает за O(самый большой номер опрашиваемого файла)
Насколько велик overhead при большом количестве соединений по сравнению со временем обработки самого запроса?
Что имеется в виду под «самый большой номер опрашиваемого файла»?
Где можно почитать подробнее про внутренности select? Обычно использовал select на поток для каждого порта, или thread pool. Ваше утверждение о select заинтересовало.
0
www.webcitation.org/6ICibHuyd
и больше в гугле по «c10k problem».
и больше в гугле по «c10k problem».
0
Саму статью проглядел (в части 1 поток 1 соединение) до вашего ответа, но так и не понял, чем плох select. В данной статье, например, говорится о многопоточности в Apache и стратегии 1 поток — 1 соединение. Приводятся аргументы за и против (аргументы «против» вида «некоторые ОС не позволяют создать много потоков» не рассматриваем, т.к. 10к потоков создать можно в той же windows несмотря на кучу ограничений в этой области). В статье есть список Interesting select()-based servers.
Меня больше заинтересовали ваши слова о «сложности алгоритма опроса», этот момент остался непонятым, как и что есть «самый большой номер опрашиваемого файла».
Я могу, конечно, посмотреть на внутренности select в исходниках Linux или ReactOS, но, как я понял, вы уже разобрались в этом и можете что-то пояснить. Или я не понял вашу аргументацию против select'а.
Или вы имеете в виду ситуацию, когда 1м селектом опрашиваются 10к сокетов и на все один поток? Я-то о стратегии 1 соединение=1 thread = 1 socket = 1 select per socket.
Меня больше заинтересовали ваши слова о «сложности алгоритма опроса», этот момент остался непонятым, как и что есть «самый большой номер опрашиваемого файла».
Я могу, конечно, посмотреть на внутренности select в исходниках Linux или ReactOS, но, как я понял, вы уже разобрались в этом и можете что-то пояснить. Или я не понял вашу аргументацию против select'а.
Или вы имеете в виду ситуацию, когда 1м селектом опрашиваются 10к сокетов и на все один поток? Я-то о стратегии 1 соединение=1 thread = 1 socket = 1 select per socket.
+1
У select() неудобный интерфейс — приходится обходить почти весь список дескрипторов (точнее, вплоть до изменившегося дескриптора с максимальным номером), чтобы узнать, какие готовы. И так после каждого вызова.
epoll_wait() пишет события последовательно, поэтому после возврата epoll_wait() можно обойти только те дескрипторы, которые изменились.
Есть также разница во внутренней реализации — select() добавляет процесс в N списков ожидания на каждом вызове. И после завершения select() процесс нужно отписать от N списков ожидания.
epoll имеет собственный список ожидания. Конечно, сокету epoll нужно подписаться на N сокетов, но это нужно сделать один раз. Вход и выход из epoll() требуют исключения процесса лишь из одного списка ожидания.
Итого, пусть мы имеем N дескрипторов, с M из них что-то случилось:
select() — O(N) на инициализации, О(N) на старте, O(N) на выходе, O(maxno(M)) на проверке десткипторов, уничтожения не нужно.
epoll_wait() — O(N) на инициализации, O(1) на старте, О(1) на выходе, O(M) на проверке дескрипторов, O(N) на уничтожении.
А ещё epoll сокеты можно вкладывать друг в друга.
Источник: stackoverflow.com/questions/17355593/why-is-epoll-faster-than-select
epoll_wait() пишет события последовательно, поэтому после возврата epoll_wait() можно обойти только те дескрипторы, которые изменились.
Есть также разница во внутренней реализации — select() добавляет процесс в N списков ожидания на каждом вызове. И после завершения select() процесс нужно отписать от N списков ожидания.
epoll имеет собственный список ожидания. Конечно, сокету epoll нужно подписаться на N сокетов, но это нужно сделать один раз. Вход и выход из epoll() требуют исключения процесса лишь из одного списка ожидания.
Итого, пусть мы имеем N дескрипторов, с M из них что-то случилось:
select() — O(N) на инициализации, О(N) на старте, O(N) на выходе, O(maxno(M)) на проверке десткипторов, уничтожения не нужно.
epoll_wait() — O(N) на инициализации, O(1) на старте, О(1) на выходе, O(M) на проверке дескрипторов, O(N) на уничтожении.
А ещё epoll сокеты можно вкладывать друг в друга.
Источник: stackoverflow.com/questions/17355593/why-is-epoll-faster-than-select
+1
приходится обходить почти весь список дескрипторов (точнее, вплоть до изменившегося дескриптора с максимальным номером)
То-есть, как я и предполагал, речь идет о ситуации, когда в один select загоняется массив со всеми (или просто большой частью) сокетов? В случае, если у нас каждое соединение обслуживается отдельным потоком, такой проблемы нет.
Есть также разница во внутренней реализации — select() добавляет процесс в N списков ожидания на каждом вызове. И после завершения select() процесс нужно отписать от N списков ожидания.
Процесс или поток? В какой ОС?
Сдается мне, здесь солидная разница в реализации между nix и Win.
0
В случае, если у нас каждое соединение обслуживается отдельным потоком
А зачем вообще связываться с select(), если у нас по потоку на коннект? Получили сокет из accept(), отдали его треду, пусть тред использует блокирующие вызовы. Разве что ограничить время блокирующей операции, т.к. стандартный read/write этого не позволяет. В таком случае, я думаю, epoll() вообще не нужен.
10к потоков создать можно в той же windows
Можно, только памяти на это потребуется немало, например, в linux по умолчанию под стек каждого pthread выделяется 2mb. Для создания 10.000 одновременных соединений протребуется 20GB памяти только под стек. Разумеется, минимальный размер стека регулируется, и оверхед можно существенно уменьшить, указав более подходящие значения.
Тем не менее, неблокирующим серверам обычно требуется существенно меньше памяти. Также уменьшаются (немаленькие) накладные расходы на переключения контекста между задачами.
Процесс или поток? В какой ОС?
В Linux, раз уж речь идёт о epoll. В Linux процесс и поток — вещи по сути одинаковые.
0
А зачем вообще связываться с select(), если у нас по потоку на коннект? Получили сокет из accept(), отдали его треду, пусть тред использует блокирующие вызовы
select позволяет отделить таймаут. Единственный оверхед, который я вижу это вызов WaitForMultipleObjects каждый раз, который наверняка делается внутри. Но это мизер по сравнению с самим вводом-выводом.
Также уменьшаются (немаленькие) накладные расходы на переключения контекста между задачами.
Думаю, в случае, если поток спит (win), то эти расходы малы. Поток проснется, когда будет, что делать. А в этом случае сам ввод-вывод, его обработка займут времени поболее переключения контекста, кмк.
Плюс в некоторых случаях, например, когда сервер является промежуточным звеном (нередкий сценарий), то обработка запроса потоком просто удобнее, в случае кругового опроса все равно придется создавать свой «контекст» в виде описания задачи и пр. И если потребуется ожидание ввода-вывода из другого источника, сохранение такого контекста много труднее, чем контекста потока.
Разумеется, минимальный размер стека регулируется, и оверхед можно существенно уменьшить, указав более подходящие значения.
Уже сталкивался с этим в Win32, там проблемы начинаются уже при меньшем количестве потоков (1000+-), но стек в 64к решает вопрос.
Если кому-то интересно, здесь есть хорошее описание ограничений Windows Mark Russinovich'ем, втч по кол-ву потоков в W32 и W64:
В Linux, раз уж речь идёт о epoll. В Linux процесс и поток — вещи по сути одинаковые.
Ясно; у меня основной опыт с Win32.
0
UFO just landed and posted this here
Каждый вызов функции из библиотеки оборачивается в try {} catch (), если приложение падает с исключением, то оно ловится и игнорируется, а если что-то критическое произойдёт, то веб-сервер конечно ляжет.
-3
Если честно, то мультиплексирование на select меня убило, в современном мире это издевательство, возьмите что-нить готовое libevent хотя бы что ли. А лучше boost::asio.
+8
А через что там (libevent, boost::asio) работает мультиплексирование?
Серьёзно, я искал что-нибудь получше, но не нашёл ничего.
(Ссылки на описание других методов и их преимуществ приветствуются)
Серьёзно, я искал что-нибудь получше, но не нашёл ничего.
(Ссылки на описание других методов и их преимуществ приветствуются)
0
Как минимум без libevent и boost::asio в POSIX'е есть poll(). Правда не во всех системах есть нативная его реализация (иногда это просто проксирование того же select'а)
+1
То-то и оно. Читал о том, что poll в некоторых системах просто использование нескольких select, это меня и отпугнуло.
А что используют те же библиотеки libevent или boost::asio? Они же должны базироваться на каких-то функциях, реализованных в операционной системе.
А что используют те же библиотеки libevent или boost::asio? Они же должны базироваться на каких-то функциях, реализованных в операционной системе.
0
nginx.org/ru/docs/events.html
linux — epoll
freebsd — kqueue
windows — хз
Не забывайте, что сами веб серверы написаны на C/C++.
И многие языки программирования все ещё написаны на C/C++.
И <? echo «hello world!» ?>: все равно парсится чем-то, написанном на C/C++.
linux — epoll
freebsd — kqueue
windows — хз
Не забывайте, что сами веб серверы написаны на C/C++.
И многие языки программирования все ещё написаны на C/C++.
И <? echo «hello world!» ?>: все равно парсится чем-то, написанном на C/C++.
+4
Советую почитать про «c10k problem», ну и по сути искать именно по этой строке, найдется много информации. В различных системах используются разные механизмы мультиплексирования poll (posix), epoll (linux), kqueue (freebsd), IOCP (windows). poll на деле не далеко ушел от select по качеству своей работы. Данные механизмы (за windows не говорю, не изучал IOCP) в своей основе являются событийными и позволяют снизить нагрузку на систему за счет того, что нет лишних ожиданий. Библиотеки libevent, libev, libuv, boost::asio реализуют данные механизмы, IOCP правда редкий гость в них, но в boost::asio реализована и его поддержка. Если подробнее, то есть очередь событий, куда валятся все события, программист сам выгребает из очереди все пришедшие события и обрабатывает их. На деле библиотеки большую часть рутины берут на себя. Осваивать с boost::asio тяжко, но библиотека очень мощная, при этом нормально работает в многопоточном режиме, тогда как у других перечисленных большая проблема с этим.
+4
>>«как писать сайты на C++. В интернете ничего толкового по этой теме не нашёл (только через CGI)»
Возможно Вас заинетерсуют два популярных web frameworks Iron(http://ironframework.io/) и Nickel(http://nickel.rs/) для Rust.
Возможно Вас заинетерсуют два популярных web frameworks Iron(http://ironframework.io/) и Nickel(http://nickel.rs/) для Rust.
0
Не очень понятно, как быть с безопасностью такого решения. Один вэб сервер может обслуживать множество сайтов, например на PHP, и каждый из них ничего не сможет узнать о «соседях». В то время как сайты в виде подключаемых библиотек исполняются в одном и том же адресном пространстве и все ресурсы одного сайта доступны всем остальным. Получается, что надо либо держать на сервере по одному сайту, либо вешать какой-нибудь frontend на порту, чтобы раскидывать подключения по разным копиям сервера под разными пользователями. То есть то, чем занимается nginx. И тогда непонятно почему не делать просто вэб приложения через fast-cgi. А уж на чем они будут реализованы, на сях, на ассемблере или еще на чем-нибудь экзотическом — это уже определяется требованиями задачи и фантазией разработчика…
+3
Не используйте глобальные переменные и не будет у вас таких проблем.
-2
Глобальные переменные — это не единственное зло при таком подходе. Я изначально написал про ресурсы — вся директория пользователя или ресурсы соседних длл-ок доступны. А там могут например лежать конфиденциальные документы, доступ к которым должен быть ограничен для неавторизованных посетителей. Платный контент для закачки и так далее. То есть достаточно либо установить сайт с вредоносной закладкой, либо воспользоваться какой-нибудь уязвимостью существующего сайта, чтобы получить доступ ко всему контенту всех сайтов данного сервера.
0
Да, я знаю об этом проблеме. У меня она не решена, как вы верно заметили.
Но ведь не всё сразу делается.
Но ведь не всё сразу делается.
0
А я считаю, что это как раз не проблема и вам ее не нужно решать. Ваше приложение запускается по той же модели, что и приложения, написанные на Go. Т.е. у каждого приложения свой веб-сервер со всеми вытекающими. Подобная идеология в корне отличается от стандартного подхода (один веб-сервер и много сайтов), поэтому эти подходы даже сравнивать не стоит.
Каждое ваше приложение в идеале должно запускаться от имени отдельного пользователя. В этом случае никаких утечек конфиденциальных данных не будет.
Мне ваш проект очень понравился. Надеюсь, что вы его не забросите.
Каждое ваше приложение в идеале должно запускаться от имени отдельного пользователя. В этом случае никаких утечек конфиденциальных данных не будет.
Мне ваш проект очень понравился. Надеюсь, что вы его не забросите.
0
Хм. В этом есть смысл.
Изначально, при задумке (а потом и при разработке), я ориентировался на модель работы обычных (распространённых) веб-серверов (apache, nginx).
Если я пойду дальше этим путём, то мне придётся повторно изобрести fastcgi. А то что уже существует, конечно, незачем изобретать.
Спасибо за мысль.
Изначально, при задумке (а потом и при разработке), я ориентировался на модель работы обычных (распространённых) веб-серверов (apache, nginx).
Если я пойду дальше этим путём, то мне придётся повторно изобрести fastcgi. А то что уже существует, конечно, незачем изобретать.
Спасибо за мысль.
0
Эхх, тоже сделал сайт на С++. Приложение-генератор статических HTML-страничек, которые потом веб-сервер и отдаёт. Выполняется как CGI, так и в консоли на пользовательской машине (тогда файлы на сервер надо залить). Пользователю наружу для комментариев доступен только один РНР-скрипт, который пишет сами комменты в БД MySQL. После просмотра модератором опять запускается генерация статических страниц.
Но для внесения изменений очень уж не удобно каждый раз перекомпилировать, да и перегенерация полуторы тысячи страниц занимает продолжительное время.
Но для внесения изменений очень уж не удобно каждый раз перекомпилировать, да и перегенерация полуторы тысячи страниц занимает продолжительное время.
0
Для «языка Ада» тоже существует такой проект, называется AWS (Ada Web Server и когда-то давно именно Ada Web Server выдавался, а не Amazon Web Services по запросу «AWS» в поисковиках...). Основная идея — вебсервер в приложении, а не приложение в веб-сервере.
Вполне себе используется в системе обработки полетных планов (Flight plan processing).
Вполне себе используется в системе обработки полетных планов (Flight plan processing).
0
>>Удивился, какое множество сайтов не соответствуют требованиям RESTful, то есть, фактически, — работают неправильно).
Какое-то очень-очень громкое категорическое заявление «фактически, — работают неправильно», а если RESTful не нужен?
А вообще хотелось бы побольше подробностей, почему вы решили использовать для сайтов С++
Это просто эксперимент? Если вы писали так нечто реальное, интересно было бы увидеть работающий проект.
Также интересны сравнения тестов по производительности на реальных нагрузках, сравнения по скорости разработки с более распространенными для этих целей языками.
Какое-то очень-очень громкое категорическое заявление «фактически, — работают неправильно», а если RESTful не нужен?
А вообще хотелось бы побольше подробностей, почему вы решили использовать для сайтов С++
Это просто эксперимент? Если вы писали так нечто реальное, интересно было бы увидеть работающий проект.
Также интересны сравнения тестов по производительности на реальных нагрузках, сравнения по скорости разработки с более распространенными для этих целей языками.
+4
Мне нравится больше RESTful архитектура. Она лучше всего подходит для понимания работы HTTP протокола. Чего не скажешь о таких средствах как PHP, где заранее определены массивы $_GET (параметры ресурса) и $_POST (данные). Что сильно меня запутало при разработке сервера (сам много c PHP работал).
Почему C++? Да, это начиналось как эксперимент. В конце своей статьи написал, что делаю сайт, который уже работает, но пока не вышел в свет.
Тестировал нагрузку, конечно же. Сайт, который делаю, работает под Windows и даёт результат чуть больше 900 запросов в секунду (не Keep-Alive) с одной выборкой из БД. Учитывая что там процессор — Intel Atom 1037U.
Почему C++? Да, это начиналось как эксперимент. В конце своей статьи написал, что делаю сайт, который уже работает, но пока не вышел в свет.
Тестировал нагрузку, конечно же. Сайт, который делаю, работает под Windows и даёт результат чуть больше 900 запросов в секунду (не Keep-Alive) с одной выборкой из БД. Учитывая что там процессор — Intel Atom 1037U.
-7
>>Мне нравится больше RESTful архитектура.
Мне оно тоже нравится, там где оно к месту, но называть там где этого нет неправильным — правильным не считаю :)
>>Чего не скажешь о таких средствах как PHP, где заранее определены массивы $_GET (параметры ресурса) и $_POST (данные).
А параметры ресурса это разве не данные? И я не совсем понял, чем этим массивы мешают архитектуре RESTful.
>>Сайт, который делаю, работает под Windows и даёт результат чуть больше 900 запросов в секунду
Просто в подобных статьях вроде вашей, лично мне, больше всего хотелось бы видеть реальные практические сравнения.
Т.е. что-то из серии «вот нечто написанное на PHP/Python/Ruby — а вот тоже написанное на С++, отдает в NN раз больше ответов в секунду, но код писался в N раз дольше, зато серверов теперь не 50, а 5». По-моему это было бы очень полезно, а то иногда задумываешь что-то переписать на С++, а останавливает мысль что толку будет немного.
Мне оно тоже нравится, там где оно к месту, но называть там где этого нет неправильным — правильным не считаю :)
>>Чего не скажешь о таких средствах как PHP, где заранее определены массивы $_GET (параметры ресурса) и $_POST (данные).
А параметры ресурса это разве не данные? И я не совсем понял, чем этим массивы мешают архитектуре RESTful.
>>Сайт, который делаю, работает под Windows и даёт результат чуть больше 900 запросов в секунду
Просто в подобных статьях вроде вашей, лично мне, больше всего хотелось бы видеть реальные практические сравнения.
Т.е. что-то из серии «вот нечто написанное на PHP/Python/Ruby — а вот тоже написанное на С++, отдает в NN раз больше ответов в секунду, но код писался в N раз дольше, зато серверов теперь не 50, а 5». По-моему это было бы очень полезно, а то иногда задумываешь что-то переписать на С++, а останавливает мысль что толку будет немного.
+4
Меня с самого знакомства с веб-программированием удивляли ограничения в инструментах. Сперва везде было только PHP+MySQL, потом появились всяческие Ruby on Rails и тому подобные вещи. По неясной для меня причине в веб-разработке очень многие забывают, что не всегда стоит открывать банки, забивать гвозди и рыть траншеи одним и тем же отбойным молотком. Бывает, когда реляционная база даёт свои преимущества, а бывает, что создаёт настолько узкое место, что и вода не течёт. Есть места, где стоит смотреть на документоориентированые NoSQL, а где-то лучше Key-Value. Так же, есть место и компилируемым языкам в веб-разработке.
Для своих целей мы используем небольшой фреймворк на C++, который компилируется в модуль для Apache 2.4. Его функции:
— Объектная модель данных. Идея взята из cocos2d-x 2.0, а там из Obj-C, потому выглядит жутковато.
— Хранение данных. Используется CouchBase.
— Кодирование/декодирование JSON
— Автопостроение REST API по модели данных. Самая важная фича здесь.
— Возможность встраивания контроля доступа прямо в модель. Поскольку в 99% случаев никто не пишет ничего в обход автоматического API.
— Поддержка сессий. Аналогично PHP с криптографией и логикой посильнее.
Нет и никогда не планировалось:
— Генерации страниц в любом виде. Только JSON.
— Поддержки других источников данных кроме CouchBase (хотя самые-самые первые версии использовали PostgreSQL, но делали это так, словно это было Key-Value Storage)
Хотели вскрыть исходники этого всего, но времени патологически мало. Не дошло дело даже до нормального документирования и названия. Если кого-то заинтересовало, у меня гитхаб есть в аккаунте. Код дарю под указанной лицензией. Он ужасен, хреново портабелен, но мало ли…
Для своих целей мы используем небольшой фреймворк на C++, который компилируется в модуль для Apache 2.4. Его функции:
— Объектная модель данных. Идея взята из cocos2d-x 2.0, а там из Obj-C, потому выглядит жутковато.
— Хранение данных. Используется CouchBase.
— Кодирование/декодирование JSON
— Автопостроение REST API по модели данных. Самая важная фича здесь.
— Возможность встраивания контроля доступа прямо в модель. Поскольку в 99% случаев никто не пишет ничего в обход автоматического API.
— Поддержка сессий. Аналогично PHP с криптографией и логикой посильнее.
Нет и никогда не планировалось:
— Генерации страниц в любом виде. Только JSON.
— Поддержки других источников данных кроме CouchBase (хотя самые-самые первые версии использовали PostgreSQL, но делали это так, словно это было Key-Value Storage)
Хотели вскрыть исходники этого всего, но времени патологически мало. Не дошло дело даже до нормального документирования и названия. Если кого-то заинтересовало, у меня гитхаб есть в аккаунте. Код дарю под указанной лицензией. Он ужасен, хреново портабелен, но мало ли…
+3
[мимо]
0
Тоже давно смотрю в сторону ухода написания сайтов целиком на C++. Сейчас использую гибридный вариант c PHP-CPP.
В качестве плюсов использования C++ в веб разработке (в качестве дополнения к посту) я бы назвал:
1) Итоговое приложение работает молниеносно.
2) Никаких архитектурных компромиссов. В том же PHP всегда стоит выбор либо быстро работает, либо красивая архитектура.
3) На самом деле, если разработчик уже знает C++, то разработка на C++ не занимает больше времени чем на динамических языках. Особенно в двух последних стандартах.
4) Статическая типизация, статический анализ кода из коробки.
5) Огромное количество готовых библиотек на все случаи жизни.
и т.д.
Из минусов, на мой взгляд, только отладка.
Если говорить о реализации веб фреймворка на С++. То что хотелось бы видеть в первую очередь:
1) Разбор заголовков (работа с данными POST, GET, Cookies) (можно взять http-parser).
2) Шаблонизатор (можно взять SMART-TPL)
В качестве плюсов использования C++ в веб разработке (в качестве дополнения к посту) я бы назвал:
1) Итоговое приложение работает молниеносно.
2) Никаких архитектурных компромиссов. В том же PHP всегда стоит выбор либо быстро работает, либо красивая архитектура.
3) На самом деле, если разработчик уже знает C++, то разработка на C++ не занимает больше времени чем на динамических языках. Особенно в двух последних стандартах.
4) Статическая типизация, статический анализ кода из коробки.
5) Огромное количество готовых библиотек на все случаи жизни.
и т.д.
Из минусов, на мой взгляд, только отладка.
Если говорить о реализации веб фреймворка на С++. То что хотелось бы видеть в первую очередь:
1) Разбор заголовков (работа с данными POST, GET, Cookies) (можно взять http-parser).
2) Шаблонизатор (можно взять SMART-TPL)
+3
UFO just landed and posted this here
Как некий академический опыт, этот проект вполне годен. Но на практике, разумеется, так никто не делает и делать не будет. Дело в том, что современные средства низкоуровневой работы с HTTP-протоколом прошли многие годы оптимизации и борьбы за безопасность. Вашему инструменту придется пройти весь этот путь тоже.
В реальности высоконагруженные проекты используют C/C++, но делают это немного иначе. Классический подход состоит в определении узкого места в приложении (bottleneck) и реализации его в виде расширения к текущему языку программирования. Например тот же PHP поддерживает подгрузку внешних модулей, чем многие и пользуются.
В реальности высоконагруженные проекты используют C/C++, но делают это немного иначе. Классический подход состоит в определении узкого места в приложении (bottleneck) и реализации его в виде расширения к текущему языку программирования. Например тот же PHP поддерживает подгрузку внешних модулей, чем многие и пользуются.
+7
Какой-то у вас не к селу не к городу сервер получился.
Конкурировать с «большими» серверами у вас вряд ли получится. Уже есть быстрый минималистичный сервер Ngix и богатый возможностями Apache. Тем более с такой моделью безопасности больше одного приложения на вашем сервере все равно загружать нельзя.
Зато у вас мог бы получится встраиваемый сервер. Но что хотят пользователи встраиваемого сервера:
* Чтоб он статически линковался, и можно было таскать с собой один файл
* Чтоб каждый раз при подключении нового клиента создавался указанный объект обработчик, и для каждого из указанных url вызывалась указанная функция, в которую передались бы расшифрованные параметры
* Чтоб при повторном запросе того же клиента вызывался тот же обработчик (с сохранением контекста)
* Чтоб сервер автомагически отдавал статику из файлов, сериализовал в json и обратно, поддерживал ssl и выполнял авторизацию:)
Чего не хотят пользователи встраиваемого web-server-a:
* Думать о заголовках, печеньках и прочем HTTP
Конкурировать с «большими» серверами у вас вряд ли получится. Уже есть быстрый минималистичный сервер Ngix и богатый возможностями Apache. Тем более с такой моделью безопасности больше одного приложения на вашем сервере все равно загружать нельзя.
Зато у вас мог бы получится встраиваемый сервер. Но что хотят пользователи встраиваемого сервера:
* Чтоб он статически линковался, и можно было таскать с собой один файл
* Чтоб каждый раз при подключении нового клиента создавался указанный объект обработчик, и для каждого из указанных url вызывалась указанная функция, в которую передались бы расшифрованные параметры
* Чтоб при повторном запросе того же клиента вызывался тот же обработчик (с сохранением контекста)
* Чтоб сервер автомагически отдавал статику из файлов, сериализовал в json и обратно, поддерживал ssl и выполнял авторизацию:)
Чего не хотят пользователи встраиваемого web-server-a:
* Думать о заголовках, печеньках и прочем HTTP
+1
Заинтересовался последними изменениями стандарта с++, эти исходники просто подарок
0
А не пробовали Go там сервер из коробки и после C/C++ перебраться не проблема?
0
Искал ответ на первый вопрос — как писать сайты на C++. В интернете ничего толкового по этой теме не нашёл (только через CGI). И ужаснулся: как же так? Я хочу быть свободен в выборе инструмента разработки, хочу использовать тот язык, который мне нравится. И до сих пор никто ничего не сделал? Или сделал, но использует только у себя?
Есть на Хабре посты о разработке сайтов на C++, например, вот этот пост.
Как-то постил топик на тему создания своего веб-сервера на основе libevent менее, чем в 40 строк. На основе этого решения (допиленный конечно же) работает мой небольшой информационный ресурс моей «поделки» (в профиле). Погоняв немного через утилиту ab, меня решение устроило, хабраэффекта не наблюдалось :)
Так что есть и посты на эту тему, и работающие сайты. Так же немало бэкенд-демонов со встроенным веб-сервером на основе libevent, microhttpd и тд пишется на С++ и не только для небольших частных поделок.
Посмотрите немного шире, решений найдете достаточно.
P.S. А на Wt смотрели? Там так же есть встроенный сервер.
+2
Сам страдал таким. Глупо. Лучше силы вкладывать в приложение
0
pocoproject.org/index.html — очень хороший готовый веб сервер для c++
а еще как писали выше, единство веб-сервера с приложением это не всегда хорошо, взаимодействие через сокет (в случае fastcgi) практически никаких задержек не создает.
мы в своих веб-приложениях используем исключительно c++, веб-сервер написан на основе библиотеки microhttpd, взаимодействует с основным приложением через сокет, примерно по тому же принципу что и fastcgi
а еще как писали выше, единство веб-сервера с приложением это не всегда хорошо, взаимодействие через сокет (в случае fastcgi) практически никаких задержек не создает.
мы в своих веб-приложениях используем исключительно c++, веб-сервер написан на основе библиотеки microhttpd, взаимодействует с основным приложением через сокет, примерно по тому же принципу что и fastcgi
0
Не удивлюсь, если текущий вариант через select окажется медленнее, чем nginx+ЯП с JIT.
0
А есть сравнения этого сервера с nginx / apache, запущенными на той же машине, хотя бы в ab?
0
поддержка «сайта на с++» то еще «удовольствие». опыт имеется ;(.
И в 99% процентах случаях беcсмысленно, т.к. узкое место — база данных.
Хотя существует ниша для Wt.
И в 99% процентах случаях беcсмысленно, т.к. узкое место — база данных.
Хотя существует ниша для Wt.
0
Сайт на C++ != веб сервер на C++.
Для веб серверов (http, https and etc) есть тот же nginx и не надо тут изобретать велосипед. А вот сайты которые пишутся на интерпретированных ЯП в основе своей деятельности занимаются конкатинацией строк. Обрабатывают аргументы, тягают данные из БД и шаблонизируют всё это (даже если отдаётся JSON по сути).
Так что если вы хотите писать сайты то берите CppCMS или Wt и в бой, там всё вполне удобное и рабочее. Вот только особой прибавки к производительности нету, а сложностей явно больше (и шансов отстрелить себе ногу).
Для веб серверов (http, https and etc) есть тот же nginx и не надо тут изобретать велосипед. А вот сайты которые пишутся на интерпретированных ЯП в основе своей деятельности занимаются конкатинацией строк. Обрабатывают аргументы, тягают данные из БД и шаблонизируют всё это (даже если отдаётся JSON по сути).
Так что если вы хотите писать сайты то берите CppCMS или Wt и в бой, там всё вполне удобное и рабочее. Вот только особой прибавки к производительности нету, а сложностей явно больше (и шансов отстрелить себе ногу).
0
Sign up to leave a comment.
Разработка сайтов (веб-приложений) на C++ (и не только) в виде подключаемых библиотек (*.so, *.dll)