Разработка web-приложений на C++


    Прочитав недавний топик про использование C++ и fastcgi, я наконец-то решился опубликовать свои наработки на тему Web и C++.

    Существующие решения, с моей точки зрения, реализуют простые вещи сложным образом. Моей целью было устранить это досадное недоразумение, написав библиотеку, которая позволит писать эффективные кросс-платформенные веб-приложения на С++ так же легко и быстро, как и на PHP, Python, Java, и т.д.

    Чтобы не мучать читателя ожиданием, перейдём сразу к коду простейшего приложения, написанного с помощью этой библиотеки (страница проекта на Google Code, лицензия MIT).

    Исходный код Main.h
    1. #ifndef _MAIN_H
    2. #define _MAIN_H
    3.  
    4. #include <WebToolkit.h>
    5.  
    6. class HelloWorld:public IHttpRequestHandler
    7. {
    8. private:
    9.         Server server;
    10. public:
    11.         HelloWorld();
    12.         void Run();
    13.         void Handle(HttpRequest* request,HttpResponse* response);
    14. };
    15.  
    16. #endif

    Исходный код Main.cpp
    1. #include "Main.h"
    2.  
    3. HelloWorld::HelloWorld():server(8080,"0.0.0.0")
    4. {
    5.         server.RegisterHandler(this);
    6. }
    7.  
    8. void HelloWorld::Run()
    9. {
    10.         server.Run();
    11. }
    12.  
    13. void HelloWorld::Handle(HttpRequest* request,HttpResponse* response)
    14. {
    15.         response->Write("<html><body><h1>Hello, world!</h1></body></html>");
    16. }
    17.  
    18. int main()
    19. {
    20.         try
    21.         {
    22.                 HelloWorld app;
    23.                 app.Run();
    24.         }
    25.         catch(exception& e)
    26.         {
    27.                 cout<<e.what()<<endl;
    28.         }
    29. }

    Этому приложению вообще не нужен сторонний веб-сервер. Получается обычный исполняемый файл (размер в Windows — 29 Кб), который можно просто взять и запустить. Результат его выполнения Вы можете увидеть в самом начале статьи.

    Библиотека кроссплатформенна, её можно использовать и в Windows, и в Linux (кстати, есть желающие портировать под FreeBSD или MacOS?). Её малый размер позволяет веб-приложениям выполняться в embedded-системах. Например, на роутере (я проверил на своём домашнем, ASUS WL-500gP V1, с установленной прошивкой OpenWRT).

    А если использовать какую-нибудь встраиваемую БД, например, sqlite, то можно создать приложение, которое полностью выполняется в одном процессе. А это значит, что не будет тратиться лишнее время на межпроцессное взаимодействие. Выгода очевидна — скорость. А учитывая, что сама программа написана на С++, то, возможно, это ключ к написанию самых быстрых веб-приложений. :)

    И, в качестве бонуса — готовое к применению приложение — файловый сервер (скачать можно там же):

    Вкусности:
    • Легковесный
    • Кросс-платформенный
    • Очень простая настройка
    • Поддерживает пользовательские стили
    • Поддерживает докачку файлов
    • Поддерживает юникод в именах файлов

    Понравилось? Присоединяйтесь! :)
    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 174

      0
      > Её малый размер позволяет веб-приложениям выполняться в embedded-системах.

      А окружение тоже туда запихнёте? :)
        0
        Что вы имеете в виду под окружением? Если ОС — то да, запихну. Ядро линукса+busybox=несколько Мб. Посмотрите на OpenWRT.
        –39
        позволит писать эффективные кросс-платформенные веб-приложения на С++ так же легко и быстро, как и на PHP, Pyhton, Java, и т.д.


        Процесс компиляции, это уже не быстро.
        Хватит унижать Python!
          +17
          А я и не унижал :) У питона свои плюсы, и свои минусы.
          Программа на Python не требует компиляции, зато на C++ она будет быстрее.
          И, время на компиляцию — не такое уж оно и большое, если подумать.

          P.S. Вы мне напомнили этот комикс:

            –10
            под унижением понималось неправильно написанное название.
            не думаю, что будет велика разность в скоростях, ведь тут используется fastcgi.
            p.s. ничего против не имею, просто люблю python :)
              0
              Название я исправил.

              И, вообще-то, здесь не используется FastCGI. :)
                +1
                я мыслями в предыдущем топике :)
            • UFO just landed and posted this here
                +1
                А Вы сами-то писали это самое «тяжеловесное что-то да ещё и с интерфейсом» или Вам «Рабинович напел»? ;)
                Это «тяжеловесное» обычно разбивается на модули, а модули — на отдельные классы, которые живут в отдельных файлах и перекомпилируются по отдельности, по мере необходимости. Сделал изменения в классе — перекомпилил класс — слинковал — готово. Будь там хоть 100 файлов в проекте, хоть 1000, хоть 10000.

                P.S.: говорю как человек, который за это самое «тяжеловесное да ещё и с интерфейсом» получает баппке вот уже много лет ;)
              +1
              сколько по-вашему выполняется компиляция?)
                –2
                относительно долго ;)
                  +7
                  Относительно полного отсутствия компиляции — действительно долго :)
                  Относительно времени на написание кода — можно пренебречь.
                    +1
                    вы когда нибудь компилировали что-нибудь?)
                      0
                      Вопрос даже не в том, сколько компилируется, а сколько перекомпилируется.
                      Сдаётся мне, товарищи свято верят в то, что при внесении каких-либо изменений проект каждый раз пересобирается полностью %)
                  +1
                  Компилируйте распределенно.
                    +1
                    Компиляция вообще-то происходит один раз, а потом выполняется уже бинарный файл. В отличие от пайтона, который КАЖДЫЙ РАЗ разбирает исходник и интерпретирует его.
                      +2
                      а тогда чем есть *.pyc-файлы?
                        0
                        Просто слабо разбираюсь конкретно в питоне, получается, что мне нужно держать весь DocumentRoot открытым на запись для всех?
                          0
                          Там по другому делается. .py-файлы не лежат в DocumentRoot. Лежат обычно в /home какого-нибудь пользователя.

                          И url не связан с названием файла (похожего для php можно добиться при помощи mod_rewrite), именно поэтому файлы могут лежать где угодно.
                            –1
                            Ну, а под каким юзером запускается пайтон, под пользователем (?!), или как nobody (т.е. как сервер)? Если второе, то это еще забавнее, /home давать права на запись для everybody.
                              0
                              Я в первом сообщении не написал, но .pyc-файлы не обязательно создавать, и без них все прекрасно работает, т.е. права на запись серверу не нужны.
                                +4
                                Я тащусь от манеры хабаровчан с первого же комментария погрузиться в дискуссию так, что забыть, о чем идет речь изначально.
                                  0
                                  Ну я увидел в комментарии 'DocumentRoot' и на него, собственно, отвечал :-)

                                  Вообще почитайте, как python на веб запускается, для общего развития, будет интересно.
                                  Там штук 10 примерно одинаково распространенных способов.
                                  • UFO just landed and posted this here
                              0
                              собрать .pyc, .pyo можно один раз хоть от рута, в дальнейшем python не будет читать .py, а только .pyo/.pyc
                                –1
                                А можно просто не генерировать .pyc (вряд ли кто-то станет специально это делать)
                                Тем более при изменении .py все равно он будет использоваться.
                              +1
                              Это не совсем компиляция в классическом понимании.
                              A program doesn't run any faster when it is read from a ‘.pyc’ or ‘.pyo’ file than when it is read from a ‘.py’ file; the only thing that's faster about ‘.pyc’ or ‘.pyo’ files is the speed with which they are loaded.

                              www.network-theory.co.uk/docs/pytut/CompiledPythonfiles.html
                                +2
                                да нет, это компилляция. Вот только компилляция в байткод вм (cpython) и компилляция в машинный код — ну совсем разные вещи.

                                btw, boo — питоноподобный язык под Mono/.Net. В некотрых задачах результат БЫСТРЕЕ чем «тупой» код на Си. Например, рекурсивный способ опредения последовательности фибоначчи. Изза хитрожопой tail-оптимизации в самом Mono — результат получается быстрее чем C. При том что исходник 1-в-1 как питон.
                          +1
                          Все гениальное, действительно просто. Я даже не ожидал такого минимализма кода при объектно-ориентированности и уж конечно не ожидал такого маленького размера исполняемого кода.

                          спасибо за ссылку на великолепный проект.
                            +1
                            исполняемого файла.
                              +1
                              Ну только, судя по коду, он не совсем соответствует RFC :-)
                              Правда, речь о пограничных случаях.
                              –6
                              сколько строчек, чтобы вывести «Hello world».
                                +10
                                я бы сказал «как мало строчек для готового веб-сервера». «Hello, world» это обычно больше настройка, чем бизнес-логика.
                                  +1
                                  Ваш комментарий — полная противоположность комментарию выше. :)
                                  Можно было и меньше. Но как пример, я думаю, предложенный вариант хорош (ООП, и всё такое).
                                    +4
                                    а сколько нужно поставить на сервере «борохла» что бы на том же php вывести это же hello world?
                                      0
                                      как ни странно — всего лишь php и веб-сервер
                                        –1
                                        сколько строк кода в php и в вебсервере?
                                          –1
                                          а в операционной системе?
                                            +2
                                            OS + Apache + PHP vs. OS + This C++ web server :-)
                                      +2
                                      Я, пожалуй, проясню этот момент. Это же не соревнование — кто меньше строк для Hello, world напишет.

                                      Этот пример скорее отражает, как будет приблизительно выглядеть приложение, если его по-нормальному, серьёзно, писать.
                                        0
                                        Ну по-крайней мере здесь показа огромная (ну может не огромная) часть айсберга, а не только маленькая верхушка! :)
                                          –2
                                          да, это вам не
                                          <? echo «Hello, world!» ?>
                                          +3
                                          На сервлеты похоже жавовские в данном примере. Только как то не очень красиво, имхо, получается — хэндлер создает внитри себя сервер и сам же устанавлевает колбэком себя ж в этом сервере. Если у Вас такой компактный код получается, то может три строчки работы с сервером вынести в main, а хэндлеру оставить обработку запроса и все?
                                            +1
                                            Да, можно было. Но здесь этот класс отражает именно всё приложение в целом.
                                            Но можно разделять логику как угодно, конечно же.

                                            P.S. Дизайн именно с джавовских сервлетов и был позаимствован :)
                                              0
                                              у Вас для каждого реквеста создается один трэд? В этом моменте, мне кажется FastCGI может и быстрее быть.

                                              Еще такой вопрос(заинтересовало как Вы сделали реализацию такой вещи, уж больно мне нравятся жавовские сервлеты): в Server.cpp у Вас делается select с таймаутом 0.5 с — зачем это, если все равно создается потом трэд? Сорри, если написал глупость не разобравшись до конца с кодом)
                                                0
                                                Таймаут задан для того, чтобы можно было выйти по Ctrl+C. Оно раз в полсекунды проверяет, а не пора ли заканчивать. Иначе это был бы блокирующий вызов, а он возвращался бы только тогда, когда пришёл новый запрос. Т.е. пришлось бы для завершения ждать, пока не прийдёт новый запрос.
                                                  +1
                                                  Нет, select просто завершился бы с EINTR, когда ему SIGTERM придёт.
                                                  Хотя это еще зависит от того, с какими опциями обработчик сигнала устанавливается.
                                                  0
                                                  Без трэдов не получится распараллеливания запросов, генерирующих динамический контент.

                                                  Для раздачи статики можно использовать и один поток (как в nginx). Кстати, это в планах.
                                                    0
                                                    это то понятно. Можно ведь заранее создать тредов и раздавать им по меренадобности реквесты
                                                      0
                                                      Можно. Пул тредов, то есть.
                                                      Но вроде оверхед на создание треда небольшой.
                                                      Стоит ли овчинка выделки?
                                                        0
                                                        Переключение контекстов довольно тяжелая операция для процессора. Была на эту тему статья «почему xbox не тормозит с навороченной графикой, а мой навороченный компьютер торможит».

                                                        обработка запросов пулом потоков очень оптимизирует работу с большой загрузкой.
                                                          0
                                                          Согласен. В идеале следует статику отдавать так, как nginx (т.е. конечный автомат), а динамический контент генерить тредами, причём треды берутся из пула.

                                                          Скорее всего, лучше уже ничего не предложить. :)
                                                            0
                                                            А почему динамику нельзя генерить в конечном автомате? Или по-другому: событийная машина и конечный автомат разве не одно и то же?
                                                              +1
                                                              Генерация динамики в основном потоке, обслуживающем все подключения, приведёт к его заморозке на всё время генерации.
                                                            0
                                                            А Вы случайно не найдёте ссылку на эту статью? Интересно.
                                                            0
                                                            Если раздавать очень много маленькой статики(кстати у вас картинки в файл менеджере, как я понимаю не кэшируются — вот наглядный пример — разом создается несколько трэдов) — думаю результат будет на лицо. Не зря ж у Apache есть куча вариантов резализации этого(Prefork и Worker например)
                                                              0
                                                              Кэшируются, вообще-то. :)
                                                                0
                                                                а, сорри. Я просто увидел, что в HttpRequest нет парсинга If-Modified-Since и E-tag
                                                                  0
                                                                  Зато клиенту отдаётся заголовок «Expires:».
                                                                  Как раз это и отрезает ненужные запросы.
                                                                  Иначе запросы будут, просто возвращаться будет «Not Modified» — а это всё равно будет кушать ресурсы.
                                                                    0
                                                                    тут не соглашусь. отдавать клиенту Expires — это клиентское кэширование, но должно же быть и серверное. Прочитать http хэдер, дату изменения файла — не архисложная задача, зато сократит трафик.
                                                                      0
                                                                      Согласен. Можете даже патч прислать, с удовольствием прикручу. И вообще, присоединяйтесь :)
                                                        • UFO just landed and posted this here
                                                            0
                                                            Наследие ООП ;-)

                                                            Я пока только одну библиотеку в духе libevent знаю, которая действительно красиво в этом плане работает — питоновый twisted.
                                                            • UFO just landed and posted this here
                                                                0
                                                                Erlang! Erlang! Серебряная пуля!
                                                                • UFO just landed and posted this here
                                                                  0
                                                                  В планах сделать раздачу статики мультиплексором, как в nginx. Динамику всё равно трэдами нужно.
                                                                  • UFO just landed and posted this here
                                                                      0
                                                                      Нужно, чтобы не останавливать основной рабочий поток для генерации динамики.
                                                                      • UFO just landed and posted this here
                                                                          0
                                                                          Распиливать на кусочки может быть очень неудобно.
                                                                          Я думаю, всё же для динамики трэды пафоснее :-D
                                                                          Обычно ж так и делают для высоконагруженных проектов — nginx-мультиплексор раздаёт статику, за ним Apache-многопоточный генерирует динамику.
                                                                          • UFO just landed and posted this here
                                                                              0
                                                                              20-30 мс? Довольно много. Сгодится только для слабонагруженных проектов. А для слабонагруженных… можно вообще в лоб — приняли подключение, полностью обработали — и ждём следующего подключения. :)

                                                                              А если и генерацию динамики в конечный автомат превращать… Такой ад будет. Никто в здравом уме на это не пойдёт. Гораздо удобнее трэдами.
                                                                                0
                                                                                Это не просто. Для начала перепишите свое приложение так, чтобы в нем не было блок. операций. Например, можно начать с библиотеки mysql для асинхронной работы :-)

                                                                                Про треды.

                                                                                Вообще современные ос способны легко держать тысячи тредов.

                                                                                Но если речь идет о десятках и сотнях тредов, тогда нужно использовать green threads.

                                                                                Переключением контекста можно принебречь в случае green threads(треды в user space).

                                                                                У тредов есть огромное преймущество. Код *сильно* проще. Можно использовать любые операции(в том числе блокирующие). Много ядер — много тредов. Просто и понятно.
                                                                                • UFO just landed and posted this here
                                                                                  • UFO just landed and posted this here
                                                                        0
                                                                        Универсального конечно автомата под любое веб-приложение не существует.
                                                            0
                                                            Присоединятся то можно. а где почитать про такой с++, с примерами адекватными?
                                                              0
                                                              все исходники открыты, результат доступен после компиляции. это конечно хуже подробной документации, зато дает наглядный пример кода.

                                                              вливайтесь
                                                            • UFO just landed and posted this here
                                                                +2
                                                                Ушли, потому что писать на том же PHP — проще.
                                                                Если сделать качественный фреймворк для С++ — то может и придут обратно.
                                                                • UFO just landed and posted this here
                                                                    0
                                                                    Дык вроде есть такие фреймворки… Тот же ctpp(кажется, его создатели что то еще в этом направлении делали) Показал бы кто-нибудь какой же выигрыш в скорости можно получить тут
                                                                      +1
                                                                      А если сделать хороший фреймворк (с эктиврекодами и прочей модной хренью) на C в виде расширения для PHP? Мне кажется баланс между скоростью/гибкостью в таком случае будет самым оптимальным (сам лично именно к этому и стремлюсь потихоньку).
                                                                    0
                                                                    Вот почему появился Ruby ©
                                                                      0
                                                                      Руби хорош, без сомнения. Но у С++ — другая цель, и другая аудитория.
                                                                      • UFO just landed and posted this here
                                                                          +3
                                                                          Цель C++ — компилируемые, быстрые как только возможно, приложения.
                                                                          Используется нынче в основном для системной разработки (драйверы, ядро ОС).

                                                                          Руби — язык скриптовый, и ориентирован на как можно более быструю разработку.

                                                                          Т.е. это вопрос выбора — скорость работы программы/скорость разработки программы.
                                                                            0
                                                                            Ядра большинства ОС написаны не на С++, а на чистом С.

                                                                            Ниша С++ — скорее нетривиальные пользовательские приложения. Например, то, с помощью которого вы просматриваете эту страницу :)
                                                                      +2
                                                                      из пушки по воробьям, но если уж очень хочеться, то лучше использовать шаблонизаторы, например ctpp2
                                                                        0
                                                                        Это смотря с какой стороны посмотреть.

                                                                        Если так подумать, огромный апач+пхп — это не из пушки по воробьям? :)
                                                                          +1
                                                                          без апача во многих местах не обойтись — гибкие настройки, аутентификация, виртуальные хосты и т.д. — если всю эту логику перенести на уровень приложения(хоть на C++, хоть на PHP) будет плохо
                                                                            0
                                                                            А с другой стороны, во многих местах можно как раз обойтись.
                                                                              0
                                                                              но все-таки, привидите пример где именно такой подход может пригодиться по Вашем мнению?
                                                                                0
                                                                                Пример Вы можете увидеть в статье (FileServer).
                                                                                Разве вам никогда не хотелось быстро поднять простой сервер, чтобы передать кому-то файл? (дабы не связываться с проблемами передачи файлов через мессенджеры)
                                                                                  +2
                                                                                  хотелось. всегда выкладывал через Апач. Мне как-то попадалась задача, которая на жавовских сервлетах делалась просто, но которую я не смог адекватно решить на Apache+PHP. А файл-сервер он и в апаче есть, и писать особо ничего не надо для этого
                                                                                    +1
                                                                                    Уместить тот же апач на роутере — уже сложнее. Он просто банально большой.
                                                                                    Конфиг очень большой и не очень дружественный.
                                                                                    Не очевидно, как применить пользовательский стиль.

                                                                                    P.S. На самом деле, разработка велась исходно именно для роутера, чтобы запустить на нём свой сайт. Поднимать там этих монстров (апач, пхп, да ещё и БД какое-то) мне не хотелось. :)
                                                                                      +1
                                                                                      Не говорите, что вы не знали про thttpd ;-)
                                                                            0
                                                                          +1
                                                                          время отклика веб-сервера меньше, да, может быть на целую секунду на тяжёлом скрипте :)
                                                                          а скорость разработки?

                                                                          и потом вы задолбаетесь писать эти response->Write("...") и придёте к использованию файлов шаблонов, а потом захотите добавить немного логики в шаблоны и изобретёте новый php :)

                                                                            0
                                                                            Кстати, у меня там по сути и есть уже файлы шаблонов :) Посмотрите на код FileServer.
                                                                            +5
                                                                            В случае серверов часто выгоднее пожертвовать быстродействием более низкоуровневого кода, чем безопасностью высокоуровневых песочниц. А удобная и отлаженная обёртка вокруг сокетов никак не гарантирует отсутствие ошибок работы с памятью в коде логики приложения.

                                                                            И если на пользовательской машине использование С++ разумно — редкий краш native приложения от краша чего-то в виртуальной машине как правило отличается только внешним видом сообщения об ошибке, то у такого рода сервера шансов упасть сразу для всех больше в столько раз, сколько у него пользователей.
                                                                              0
                                                                              Ох уж эта боязнь С++. Если писать правильно, заворачивая всю низкоуровневую работу с памятью в классы, ваша программа на С++ будет стабильна и безопасна как скала.
                                                                              Просто нужно осторожно и грамотно к этому подходить. :)

                                                                              Ваше замечание скорее относится к С — вот там действительно беда. :)
                                                                                +1
                                                                                Если где-то лежат грабли — рано, или поздно, кто-то на них наступит. Я ж не говорю что на С++ невозможно написать стабильное приложение, я говорю что в случае краша на сервере у нас последствия потенциально хуже. А согласно известному закону, или в приложении есть ошибки, или ошибкой было написание столь тривиального приложения :)

                                                                                Кстати, на С тоже можно писать в объектном стиле и заворачивать всю работу с памятью в группы функций. Только функци будут сделаны в стиле ClassName_Function(ClassName *me), года два так писал без нормального дебаггера, и не крашилось ничего. Но это ведь не показатель, все зависит от цены потенциального краша :)
                                                                              +9
                                                                              Думаю, если бы на момент создания nginx был хабр и Сысоев на нем написал анонс, то его бы забибкали с выкриками нафикнадо.

                                                                              Скептиков не слушайте. Развивайте свой проект.
                                                                                +1
                                                                                Поднять нгинкс одному, да еще и в качестве хобби, наверняка, было невыносимо трудно. А сколько таки-же отличнейших проектов умирают из-за лени? Хотя, я за автора обеими руками :)
                                                                                +1
                                                                                Создаете по треду на запрос? Ради интереса, померяйте RPS и максимальное число одновременных соединений.
                                                                                  +1
                                                                                  +1 epoll наше всё.
                                                                                    0
                                                                                    Почитайте эту ветку комментов.
                                                                                    Там как раз обсудили этот момент.
                                                                                      +3
                                                                                      По-моему, performance очень неплохой, а учитывая zero configuration…

                                                                                      *** HelloWorld/Main.cpp: (./HelloWorld >/dev/null (лог в пустоту отправляем вместо консоли, выигрыш 20-30%); ab -n 10000 -c 100)
                                                                                      100; 106ms; 0.352ms; 2839 Req/s

                                                                                      400; 160ms; 0.444ms; 2253 Req/s
                                                                                      500; 229ms; 0.459ms; 2178 Req/s
                                                                                      При 550 сервер, к сожалению, падает после обработки 9973 из 10000 запросов.

                                                                                      *** Nginx (default «Welcome to Nginx»):
                                                                                      100; 26ms; 0.260ms; 3841 Req/s
                                                                                      500; 133ms; 0.268 ms; 3753 Req/s

                                                                                      35%-70% проигрыша nginx'у, но…

                                                                                      *** Nginx + FastCGI на С (код из хабра чуть раньше, конфиг урезанный (поудалял лишние строки) отсюда):
                                                                                      100; 45ms; 0.451ms; 2215 Req/s
                                                                                      500; 478ms; 0.958ms; 1044 Req/s

                                                                                      Именно это и надо учитывать, ибо код-то какой-то внешний надо выполнять будет (что и делается в webtoolkit). Nginx + fastCGI на C проиграли madfish-webtoolkit'у на 30-100% (в смысле в два раза на 500 соединениях) серверу из статьи, правда при 550 конкурентах не упали. Справедливости ради надо сказать что fastcgi шел в один тред, хотя у nginxа два воркера работали. В результате nginx зажал 75% двух ядер (100% — заняты полностью оба ядра), а webtoolkit занял только 50%.

                                                                                      В общем, для многих простеньких приложений — самое оно. Особенно если приклепать к нему GigaBase и CTPP или что-то подобное.

                                                                                      Тест на Fedora 8 под VMWare(!) на Core2Duo / 4GB. Ни к nginxу, ни к webtoolkit'у никакого отношения не имею.
                                                                                        0
                                                                                        Эх, забыл — колонки идут так —
                                                                                        concurency; mean; mean across all requests; reqs/s.
                                                                                          0
                                                                                          а сравните ещё, пожалуйста, с
                                                                                          voituk.kiev.ua/2008/12/22/simple-reliable-java-http-server/
                                                                                          (нужно только кол-во коннектов увеличить в строчке HttpServer.create(new InetSocketAddress(80), 10);)
                                                                                            +1
                                                                                            Сожалею, но в Java ничего не понимаю. Попробовал сложить это в a.java и сделать javac a.java — ничего хорошего из этого не вышло (что-то там про source level 5.0). Если объясните как этот сервер запустить (на Linux) то попробую.
                                                                                              0
                                                                                              1) Вам нужно поставить Sun Java 6 JDK, на 5ке не будет работать.
                                                                                              2) Использовать нужно так: сохраняете в HttpServerEx.java(строчку с @Override можно убрать), компилите как javac HttpServerEx.java, запускаете как java HttpServerEx.
                                                                                                +3
                                                                                                Объяснения помогли:

                                                                                                *** Java

                                                                                                100; 54ms; .540; 1850 Req/s
                                                                                                500; 214ms; .429; 2333 Req/s; но 2% запросов — таймауты

                                                                                                На небольшой конкурентнсти — Webtoolkit в полтора раза выигрывает по скорости у Java, и оба варианта nginx'a выигрывают.

                                                                                                На 500 конкурентах идут таймауты (2% страниц не отдалось) и большое среднеквадратичное отклонение (разброс значений), что значит что результаты неоднородны (проще говоря — не примерно одинаково всем отдает, а одним — быстро, другим — медленно (до 3 секунд) — вообще говоря, это не есть хорошо, но в этом плане nginx еще хуже проявился — до 80 секунд).

                                                                                                Но если судить чисто по среднему значению — 500 конкурентов — на уровне с Webtoolkit, быстрее Nginx+fastcgi, медленнее Nginx «Welcome to nginx» (эта скорость, я подозреваю, может быть достигнута только написанием C модуля к nginx'у).

                                                                                                И еще: Java кушает 22MB оперативки, Webtoolkit 1.5MB; nginx + fastcgi едят 7.5Mb(2 воркера)+0.9(fastcgi c).

                                                                                                Интереса ради на этом же (VMware, напомню) запустил Hello World на Python's CherryPy WSGI+BaseHTTPRequestHandler,HTTPServer: не смог подняться выше 25 конкурентных запросов, но это больше проблема BaseHTTPRequestHandler,HTTPServer (без ThreadingMixIn).

                                                                                                  0
                                                                                                  о, отлично!
                                                                                                  и спасибо вам за интересные результаты — java, как и ожидалось, отработала оочень быстро, а ведь это простейший вебсервер в пару десятков строк.

                                                                                                  думаю, если слегка потюнить java (запускать, например, как java -server -Xms256m -Xmx512m)/пустить за nginx'ом для лучшего конкарренси/прибавить tcp-соединений HttpServer.create(new InetSocketAddress(80), 500);) то можно ещё раза в 1.5 ускорить.
                                                                                                    0
                                                                                                    yoihj, вы случайно не забываете смотреть ЛС? :)
                                                                                                      0
                                                                                                      Забываю :)
                                                                                              +2
                                                                                              Ваш комментарий можно заносить в книгу рекордов по информативности и полезности :) А чем тестировали?
                                                                                                +2
                                                                                                Ой. Туплю.
                                                                                                Раньше просто не знал про ab. :)
                                                                                                +1
                                                                                                Трудно судить как это работает без VMWare на данной платформе.

                                                                                                Могу сказать, что в yaws/mochiweb которые мы используем — RPS где-то 4500, количество одновременных коннектов — 10000 и выше. В happstack — RPS 7000, количество коннектов еще выше, так как памяти потребляет меньше.

                                                                                                К сожалению, не смог собрать этот тулкит, что бы сравнить. Но 550 клиентов — не особо впечатляет, ну и это примерно то, что и должно получаться при создании треда на коннект. Пул тредов в обычном виде проблему не решит.

                                                                                                В общем-то, я могу сказать, что результат 500 коннектов / 1500 — 2000 RPS — примерно тоже самое, что у нас получалось при использовании питона (при условии, что запросы к базе кэшированы), от которого в итоге отказались.

                                                                                                Т.е. по моему очевидно, что наивно реализованный HTTP сервер не дает выигрыша только от того, что написан на C++. Не надо, по моему, тянуть С++ в эту нишу.
                                                                                              +1
                                                                                              разработчики apache, lighthttp, nginx то и не вкурсе видимо что код можно так урезать.
                                                                                              для примера сойдет. но я бы побоялся такое в продакшене использовать.

                                                                                              предыдущая статья по fastsgi была интереснее т.к. c fastcgi возможно использовать различные компилируемые ЯП, например Ada или Free pascal — что по сравнению с плюсами — выглядит более разумно.
                                                                                                +1
                                                                                                ой а будто кода в ядре apache/lighttpd много. Смотрели хоть?
                                                                                                  0
                                                                                                  Смотрели. Много. Причём сишного и слабочитаемого для людей, разбалованных ООП и прочими вкуностями :)
                                                                                                    0
                                                                                                    тьфу. ну посмотрите в исходники bzr например. Мало или много? Или какой-нибудь веб-сервер на том же питоне. Мало кода?

                                                                                                    В апаче почти все вытряхнули в apr, в ядре кода осталось совсем чуть-чуть.
                                                                                                0
                                                                                                Мне кажется что каждому решению своё место. Есть задачи, где действительно надо на C++ писать web-приложения (встроенные решения).
                                                                                                По сути, если вы бирёте c++, то у вас есть почти совершенная гибкость, которой очень тяжело пользоваться именно из-за гибкости. И вы начинаете писать над C++'ными операторами и функциями STL свои оболочки, расширять их функциональноть, чтобы написать писать код вроде:

                                                                                                response->Write("Hello, world!");

                                                                                                Тут главное знать, где остановиться. Если вы будете расширять функциональность дальше, то напишите свой APACHE + PHP.
                                                                                                От C++ для больших проектов отказались именно из-за того, что на PHP разрабатывать проще. От чистого PHP отказались, потому что на симфони или ещё чём-то разрабатывать большие приложения ещё проще.
                                                                                                Всё определяет стоимость решения, а не то что считают ТРУЪ разработчики.
                                                                                                А решение на Ruby + мощный и дорогой сервер, может быть куда дешевле чем анологичное решение на C++ и на 486DX'е.
                                                                                                  0
                                                                                                  Вы абсолютно правы. Моя целевая аудитория — это именно встраиваемые решения. Когда производительность и размер в самом деле важны.

                                                                                                  Обычному разработчику куда проще и понятнее будет использовать готовые, годами проработанные технологии, вроде тех же Apache+PHP. Пусть даже они и медленнее.
                                                                                                    0
                                                                                                    Встраиваемые решения… Я вот думаю о высокопроизводительных web-сервисах. Одним словом не везде в вёбе нужны большие страшные структуры поднимать и рендериь HTML. Иногда достаточно сгенерировать картинку или JSON по запросу из базы.
                                                                                                      0
                                                                                                      Да, ещё это может пригодиться в high-load проектах.
                                                                                                  –1
                                                                                                  Чем-то это мне Apache Wicket напомнило. Не знакомы случаем? Если да, то может думаете двигаться дальше в плане архитектуры по тому, как это реализовано в Wicket?
                                                                                                    0
                                                                                                    Кстати, очень похоже на ASP.NET. Так же просто в случае неиспользования Web Forms. И так же просто можно реализовать веб формс с их файлом типа aspx и серверного кода aspx.cs(cpp). Если такое придумать, то было бы вообще круто, так же как и asp.net со всеми response.write() и шаблонами. Крутая вещь. Очень заинтересовало. Очень перспективно. Написание хендлера с использованием библиотеки напомнило написание хендлера на C#.
                                                                                                      +5
                                                                                                      Крути к этому lua. Крути хитро. Это должно будет сделать какую-то волшебную магию.
                                                                                                        +3
                                                                                                        Хабра кодеры на столько суровы что пишут под веб на C++;
                                                                                                        Все новое — хорошо забытое старое;)
                                                                                                          0
                                                                                                          А продолжение будет? :)
                                                                                                            +3
                                                                                                            Будет :)
                                                                                                              0
                                                                                                              Благодарю)
                                                                                                            0
                                                                                                            А я по старинке Klone юзаю.
                                                                                                            за статью спасибо — интересно для разнообразия
                                                                                                              0
                                                                                                              а бенчмарки-то где?
                                                                                                              +2
                                                                                                              Это просто бессмыслица. Взять один из самых сложных языков программирования и использовать его совершенно не по-назначению.

                                                                                                              С/С++ сегодня имеет свою нишу в web. Но это исключительно highload. И то можно сильно поспорить.

                                                                                                              Ваше приложение — это обычное CGI. Здесь можно было бы поставить точку, так как ни о каком highload уже речи быть не может. Но я дам ссылку на то, как такую идею правильно реализовывать: svn.havoc.ru/listing.php?repname=cas&path=%2Ftrunk%2F#_trunk_

                                                                                                                0
                                                                                                                А похоже был не прав.

                                                                                                                Вопрос к автору а где у вас реализован пул тредов, grep не помог :-(
                                                                                                                  0
                                                                                                                  Пула тредов увы нет пока. Почитайте эту ветку, здесь это всё неплохо уже обсудили.
                                                                                                                0
                                                                                                                В далёком 2006 году искал альтернативу пыхпыха и знаете тоже думал о вебе на С++ :) На самом деле, даже нашел какие-то технологии типа JSP и сервлетов, но только для С++. Уж не знаю как они там сейчас поживают, но имхо не надо извращаться. Посмотрите лучше Java и фрейворки типа Wicket или Tapestry5, последний, кстати, делался 5 лет, у вас есть столько времени? Может не будете изобретать велосипеды?
                                                                                                                  0
                                                                                                                  О бенчмарках:
                                                                                                                    0
                                                                                                                    есть у меня самописный черновик веб-сервера на Scheme (под Bigloo, если кому интересно), что называется, на коленке. Сравнил с сабжевым примером — получил такие результаты:

                                                                                                                    ab -n 1000 -c 100 localhost:8080/

                                                                                                                    C++: 4815.22 r/s
                                                                                                                    Scheme: 8657.86 r/s

                                                                                                                    ЧЯДНТ? ;-)
                                                                                                                      0
                                                                                                                      Видимо всё-таки надо делать пул тредов :)
                                                                                                                        0
                                                                                                                        только что покрутил опции оптимизации — получилось 9600+ запросов в секунду ;-) А треды нужны, да. У меня пул на 10 тредов по дефолту…
                                                                                                                          0
                                                                                                                          В смысле, опции оптимизации к С++?
                                                                                                                            0
                                                                                                                            нет, к компилятору схемы
                                                                                                                              0
                                                                                                                              У вас пул на 10 тредов — т.е. одновременно больше 10 запросов не выполняются? Так и проверяйте тогда ab при -c 10
                                                                                                                                0
                                                                                                                                ab -n 10000 -c 10 localhost:8080/

                                                                                                                                WTK C++: 12803.02 r/s
                                                                                                                                Scheme: 9957.43 r/s

                                                                                                                                Забавно, при увеличении числа конкурентных запросов, ваш пример HelloWorld начинает затыкаться, вероятно на моменте уничтожения тредов:

                                                                                                                                Percentage of the requests served within a certain time (ms)
                                                                                                                                50% 1
                                                                                                                                66% 1
                                                                                                                                75% 1
                                                                                                                                80% 1
                                                                                                                                90% 1
                                                                                                                                95% 19
                                                                                                                                98% 21
                                                                                                                                99% 21
                                                                                                                                100% 2106 (longest request)

                                                                                                                                Поэтому бенчмарк со 100 конкурентами можно считать невалидным. Но пул тредов определенно нужен.
                                                                                                                                  0
                                                                                                                                  Нужен, и я собираюсь его сделать. А для статики — мультиплексирование. И тогда, думаю, будет вообще замечательно. :)
                                                                                                                    0
                                                                                                                    Нужен скриптовый язык. Писать вот так вот прям на с++ это не серьёзно всё таки, если вопрос не о хомяке или мега крупном решении. Вариант с Lua что я предложил выше хорош, но думаю что он прожорлив. Нужен какой-то байт код, который будет один раз создаваться, а потом выполняться с не сильной потерей скорости.
                                                                                                                      0
                                                                                                                      Скриптовых решений уже и так хоть пруд пруди. Этот проект ориентируется в первую очередь на критичные к скорости или размеру приложения — для них чистый С++ — то, что надо.
                                                                                                                        0
                                                                                                                        бенчмарк выше показывает, что java(да и не только) выигрывает по скорости у вашего варианта плюсов, так что остаётся только вариант с размером.
                                                                                                                          0
                                                                                                                          Вы невнимательно смотрели бенчмарк. :) Наоборот.
                                                                                                                            +1
                                                                                                                            По крайней мере, на значениях одновременных подключений около 100. Если ограничить разумным числом количество потоков (чтобы не убивались ресурсы на переключения), всё будет так же шустро и на 500 и выше.
                                                                                                                              0
                                                                                                                              java-вариант ну ни разу не оптимизирован, да и 100 коннектов — это имхо небольшая нагрузка.
                                                                                                                              впрочем, я вечерком попробую тесты у себя дома погонять и посмотреть :)
                                                                                                                                0
                                                                                                                                А как там(в java) дефолтный сервер устроен внутри?
                                                                                                                                  0
                                                                                                                                  его сорцы, насколько я знаю, не очень открыты, поэтому я знаю только что он сделать через nio.
                                                                                                                            0
                                                                                                                            А быстрых скриптовых не так уж и много. Возможен даже хитрый симбиоз — транслятор скриптового языка в C++, после чего перекомпиляция, если код скрипта изменился, а исполняемый файл имеет более раннюю дату.
                                                                                                                              0
                                                                                                                              а нафига, если есть groovy->java?
                                                                                                                                +1
                                                                                                                                Да дело не в компиляции. Вот у php, к примеру, давно уже есть opcode cacher, который позволяет не интерпретировать код каждый раз, а кэшировать уже скомпилированный. Можно даже проверку на обновление файлов отключить и явно «говорить» когда кэш надо сбросить.

                                                                                                                                Все дело находится пониже. Тут у нас и GC, большой расход памяти(каждый элемент языка, представляет собой сткрутру, даже скаляр) и многое многое другое, что позволяет забыть о низком уровне. За это приходиться платить производительностью.
                                                                                                                                  0
                                                                                                                                  Вы только что изобрели фейсбуковый HipHop
                                                                                                                              0
                                                                                                                              Если уж писать на C++, то есть готовые фреймворки: www.tntnet.org и www.webtoolkit.eu. Либо для большей производительности на специфических задачах можно написать свой асинхронный сервер на основе библиотеки boost.
                                                                                                                                0
                                                                                                                                что ж, провёл и я парочку тестов на виртуалке
                                                                                                                                java-вариант, как и ожидалось, оказался сравнимым по скорости с WebToolkit-вариантом, но
                                                                                                                                при ab -n 10000 -c 100
                                                                                                                                WebToolkit-вариант в 4 случаях из 5 тест в конце «повисает» и/или фейлится с apr_socket_recv: Connection reset by peer (104) после 9900+ реквестов. Однако при уменьшении кол-ва реквестов до 5000 зависания случаются раза в 2 реже и WebToolkit начинает уже слегка опережать java.
                                                                                                                                Может быть автор объяснит причину этих зависаний чтобы можно было сделать честный тест?

                                                                                                                                зы virtualbox+xubuntu9.04(784mb ram) на macbookpro1,1 (1.86 core duo)
                                                                                                                                  0
                                                                                                                                  Попробуйте меньшее количество одновременных соединений. Скорее всего начинает валиться из-за большой конкурентности. Наверное стоит таки сделать пул потоков, и заставлять «лишние» подключения ждать — потому что на переключения контекстов тратится куча ресурсов.
                                                                                                                                    0
                                                                                                                                    пробовал 50 — практически ничего не менялось.
                                                                                                                                    меня больше удивляет тот факт, про зависания часто получаются в самом-самом конце, после 9990+ реквестов.
                                                                                                                                      0
                                                                                                                                      Вообще, единственное что может этот вызвать — у меня там стоит таймаут — если клиент в течение двух секунд ничего не прислал — отключить его. Попробуйте закомментировать эту строку в коде.
                                                                                                                                  0
                                                                                                                                  Вот ещё веб-сервер на Си, который в свои приложения легко можно встроить — code.google.com/p/mongoose/. Вдруг кому понадобится.
                                                                                                                                    +1
                                                                                                                                    Спасибо. Как раз мне и пригодится. А то куча проблем с низкоуровневым API — нужно ж ведь, что б кроссплатформенно было. Нужен пример.
                                                                                                                                    0
                                                                                                                                    Вопрос, который у меня появился после появления CUDA: возможно ли именно для веб-сервера, при обработке большого количества запросов, организовать множество тредов и пустить их на gpu?

                                                                                                                                    Я знаю, что такая схема имеет некоторые ограничения и неудобства, но если работу с данными, которые нужны для ответа на запросы, возможно запихнуть в рамки быстрой видеопамяти и кешей разного уровня, то даст ли оно ожидаемый рост производительности при высоких нагрузках?

                                                                                                                                    Скорее всего всё будет очень сильно зависеть от характера запросов и логики их обработки. Ну вот для примера, если взять задачу выдачи подсказок (suggests), при наборе в неком поле, — это же множество однотипных запросов, полный индекс данных для которорых можно постоянно держать в быстрой видео-памяти. Поможет ли в такой задаче gpu?
                                                                                                                                    • UFO just landed and posted this here
                                                                                                                                      • UFO just landed and posted this here

                                                                                                                                        Only users with full accounts can post comments. Log in, please.