Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Высоко-нагруженный сервер на ubuntu - С++ под Linux
|
|||
|---|---|---|---|
|
#18+
Здравствуйте! У меня стоит задача написать сервер на c++ под linux используя сокеты. Собственно, я его написал. Сейчас он выполняет следующие задачи: отправляет и принимает сообщения и файлы на клиенты и от них. Для поддержания множества клиентов использую потоки. Первый поток ожидает подключения новых клиентов. Далее для каждого нового клиента создаются два новых потока: первый для чтения сообщений от клиента, второй для отправки ему сообщений. Все работает замечательно. Но, так как сервер должен поддерживать не пару клиентов, а очень много (допустим 1000 и более), то я предполагаю, что это не лучшая реализация сервера. Поэтому у меня возник вопрос: как должен выглядеть высоко-нагруженный сервер. Сейчас есть вариант использовать библиотеку libevent. Буду рад любым идеям. Спасибо! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2014, 07:32 |
|
||
|
Высоко-нагруженный сервер на ubuntu - С++ под Linux
|
|||
|---|---|---|---|
|
#18+
как вариант взять готовое например тут ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2014, 07:54 |
|
||
|
Высоко-нагруженный сервер на ubuntu - С++ под Linux
|
|||
|---|---|---|---|
|
#18+
Есть библиотека ZMQ , по сути надстройка над TCP для обмена сообщениями. Бесплатная, кроссплатформенная. Быстрая и легкая. Вся логика для обслуживания большого количества соединений прописана внутри. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2014, 08:46 |
|
||
|
Высоко-нагруженный сервер на ubuntu - С++ под Linux
|
|||
|---|---|---|---|
|
#18+
La Franceдля каждого нового клиента создаются два новых потока: первый для чтения сообщений от клиента, второй для отправки ему сообщений. А зачем для отправки сообщений отдельный поток-то?.. Обслуживай несколько коннектов (до 10) одним потоком с помощью select() или её производных. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2014, 14:56 |
|
||
|
Высоко-нагруженный сервер на ubuntu - С++ под Linux
|
|||
|---|---|---|---|
|
#18+
Поток на каждое соединение - это не масштабируется на большое число соединений. Нужна архитектура, где небольшое число потоков (к примеру равное числу процессоров) обслуживают каждый большое число соединений. Тут как бы неминуемо приходим к асинхронному выполнению операций над сокетами, что предусматривает разбиение логики программы на множество колбэков - приготовьтес к этому, код станет запутанней чем с потоками, это плата за масштабируемость. Соответственно нужно выбрать библиотеку которая в полной мере поддерживает асинхронность и многопоточность. libevent - хороший выбор, если у вас на чистом С приложение. Если же у вас С++, то рекомендую не заморачиваться и использовать Boost.Asio Вот пример простого ECHO сервера на нем http://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio/example/echo/async_tcp_echo_server.cpp Там один поток, но несложно переделать в несколько потоков, чтобы использовать все ресурсы сервера. Вот полноценный HTTP сервер, который уже с потоками http://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio/example/http/server2/ ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2014, 15:22 |
|
||
|
Высоко-нагруженный сервер на ubuntu - С++ под Linux
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyПоток на каждое соединение - это не масштабируется на большое число соединений. Нужна архитектура, где небольшое число потоков (к примеру равное числу процессоров) обслуживают каждый большое число соединений. Тут как бы неминуемо приходим к асинхронному выполнению операций над сокетами, что предусматривает разбиение логики программы на множество колбэков - приготовьтес к этому, код станет запутанней чем с потоками, это плата за масштабируемость. Соответственно нужно выбрать библиотеку которая в полной мере поддерживает асинхронность и многопоточность. libevent - хороший выбор, если у вас на чистом С приложение. Если же у вас С++, то рекомендую не заморачиваться и использовать Boost.Asio Вот пример простого ECHO сервера на нем http://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio/example/echo/async_tcp_echo_server.cpp Там один поток, но несложно переделать в несколько потоков, чтобы использовать все ресурсы сервера. Вот полноценный HTTP сервер, который уже с потоками http://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio/example/http/server2/ А в Boost.Asio до сих пор используются обычная MP-MC очередь на mutex, для распределения дескрипторов "готовых" сокетов полученных при демультиплексировании select/kqueue/epoll - не поставили туда ещё boost::lockfree::queue<>, который быстрее в 2 раза, или не сделали там возможность настройки пакетного распределения - batch-инга? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2014, 15:50 |
|
||
|
Высоко-нагруженный сервер на ubuntu - С++ под Linux
|
|||
|---|---|---|---|
|
#18+
Вася Уткин, Если использовать схему "один io_service - один поток", то неважно какая там очередь, потоки не конкурируют между собой, а замыкание мютекса при отсутствии конкуренции это и есть lock-free :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2014, 16:01 |
|
||
|
Высоко-нагруженный сервер на ubuntu - С++ под Linux
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyВася Уткин, Если использовать схему "один io_service - один поток", то неважно какая там очередь, потоки не конкурируют между собой, а замыкание мютекса при отсутствии конкуренции это и есть lock-free :) А это оптимальная схема с точки зрения производительности - на один порт вешать несколько io_service-ов, и использовать на каждый "один io_service - один поток"? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2014, 20:37 |
|
||
|
Высоко-нагруженный сервер на ubuntu - С++ под Linux
|
|||
|---|---|---|---|
|
#18+
Вася УткинА это оптимальная схема с точки зрения производительности - на один порт вешать несколько io_service-ов, и использовать на каждый "один io_service - один поток"? Ну, на один порт не повесишь несколько сервисов. Там висит один отдельный сервис+поток, и он уже равномерно раскидывает новые соединения по пулу сервисов. Т.е. конкуренция между потоками есть - в момент создания нового соединения, но это имеет несущественное значение, т.к. основная работа с сервисом происходит все-таки в одном потоке и плюс конкурируют не более чем 2 потока. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2014, 21:33 |
|
||
|
Высоко-нагруженный сервер на ubuntu - С++ под Linux
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyТам висит один отдельный сервис+поток, и он уже равномерно раскидывает новые соединения по пулу сервисов. Кстати такая схема позволяет отказаться от асинхронности в коде accept - синхронный вариант быстрее работает, т.к. нет очереди, и связанного с ней оверхеда. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.01.2014, 21:42 |
|
||
|
Высоко-нагруженный сервер на ubuntu - С++ под Linux
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyВася УткинА это оптимальная схема с точки зрения производительности - на один порт вешать несколько io_service-ов, и использовать на каждый "один io_service - один поток"? Ну, на один порт не повесишь несколько сервисов. Там висит один отдельный сервис+поток, и он уже равномерно раскидывает новые соединения по пулу сервисов. Я так понимаю это - "отдельный сервис+поток, и он уже равномерно раскидывает новые соединения по пулу сервисов" скрыто за самой библиотекой Boost.Asio. А в моем коде будет выглядеть именно как несколько сервисов на одном порту? Anatoly MoskovskyТ.е. конкуренция между потоками есть - в момент создания нового соединения, но это имеет несущественное значение, т.к. основная работа с сервисом происходит все-таки в одном потоке и плюс конкурируют не более чем 2 потока. В смысле, какие 2 потока конкурируют, если и сервис и обработчик в одном потоке? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2014, 00:05 |
|
||
|
Высоко-нагруженный сервер на ubuntu - С++ под Linux
|
|||
|---|---|---|---|
|
#18+
Вася УткинЯ так понимаю это - "отдельный сервис+поток, и он уже равномерно раскидывает новые соединения по пулу сервисов" скрыто за самой библиотекой Boost.Asio. А в моем коде будет выглядеть именно как несколько сервисов на одном порту? Нет. В явном виде отдельный поток выполняющий accept. В смысле, какие 2 потока конкурируют, если и сервис и обработчик в одном потоке? Конкурирует поток accept попарно с N потоков пула сервисов обрабатывающих дальнейшие после accept события. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2014, 02:16 |
|
||
|
Высоко-нагруженный сервер на ubuntu - С++ под Linux
|
|||
|---|---|---|---|
|
#18+
Anatoly Moskovsky, можно привести пример передачи сокета в другой io_service? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2014, 09:23 |
|
||
|
Высоко-нагруженный сервер на ubuntu - С++ под Linux
|
|||
|---|---|---|---|
|
#18+
sherzod_Anatoly Moskovsky, можно привести пример передачи сокета в другой io_service? http://alexott.net/ru/cpp/BoostAsioNotes.html автор test-mcmt.cpp — реализует обработку данных в соответствии со стратегией Many Connections/Many Threads: запускается несколько нитей выполнения, которые по очереди принимают соединение и обрабатывают запросы в асинхронном режиме; Из начала очереди io_service переставляется в конец, по принципу round-robin: https://github.com/alexott/boost-asio-examples/blob/master/test-mcmt.cpp#L130 В потоке акцептора создается сокет в составе объекта connection, который передается текущему io_service: https://github.com/alexott/boost-asio-examples/blob/master/test-mcmt.cpp#L133 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2014, 13:20 |
|
||
|
Высоко-нагруженный сервер на ubuntu - С++ под Linux
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyКонкурирует поток accept попарно с N потоков пула сервисов обрабатывающих дальнейшие после accept события. А за какой ресурс они конкурируют? Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2014, 13:49 |
|
||
|
Высоко-нагруженный сервер на ubuntu - С++ под Linux
|
|||
|---|---|---|---|
|
#18+
sherzod_можно привести пример передачи сокета в другой io_service? Новый сокет изначально создается с нужным сервисом. Просто пока не пройдет accept никакие обработчики этого сокета не вызываются (сокет вообще изначально пустой, только после accept он инициализируется и для него вызывается async_rea/async_write). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2014, 15:07 |
|
||
|
Высоко-нагруженный сервер на ubuntu - С++ под Linux
|
|||
|---|---|---|---|
|
#18+
Dimitry SibiryakovAnatoly MoskovskyКонкурирует поток accept попарно с N потоков пула сервисов обрабатывающих дальнейшие после accept события. А за какой ресурс они конкурируют? Поток accept добавляет хендлер в очередь одного из сервисов в пуле, дальше все хендлеры добавляются уже из потока этого же сервиса. Т.е. конкуренция идет за очередь сервиса в момент accept. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2014, 15:10 |
|
||
|
Высоко-нагруженный сервер на ubuntu - С++ под Linux
|
|||
|---|---|---|---|
|
#18+
Anatoly MoskovskyПоток accept добавляет хендлер в очередь одного из сервисов в пуле, дальше все хендлеры добавляются уже из потока этого же сервиса. Т.е. конкуренция идет за очередь сервиса в момент accept. Anatoly MoskovskyТ.е. конкуренция между потоками есть - в момент создания нового соединения, но это имеет несущественное значение, т.к. основная работа с сервисом происходит все-таки в одном потоке и плюс конкурируют не более чем 2 потока. Но ведь в случае с web-сервером, например, каждый вызов страницы - это открытие и закрытие нового соединения. А если на web-сервере страницы статичные и быстро создаются, то нельзя сказать, что "основная работа с сервисом происходит все-таки в одном потоке" по сравнению с засыпанием acceptor-a на мьютексе и ожидания пока он снова проснется, ведь пока acceptor спит ни одно новое соединение не может быть создано. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2014, 16:03 |
|
||
|
Высоко-нагруженный сервер на ubuntu - С++ под Linux
|
|||
|---|---|---|---|
|
#18+
Вася УткинНо ведь в случае с web-сервером, например, каждый вызов страницы - это открытие и закрытие нового соединения. Вовсе не обязательно. Есть keep-alive. Вася Уткин А если на web-сервере страницы статичные и быстро создаются, то нельзя сказать, что "основная работа с сервисом происходит все-таки в одном потоке" по сравнению с засыпанием acceptor-a на мьютексе и ожидания пока он снова проснется, ведь пока acceptor спит ни одно новое соединение не может быть создано. Переведи ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2014, 16:48 |
|
||
|
Высоко-нагруженный сервер на ubuntu - С++ под Linux
|
|||
|---|---|---|---|
|
#18+
MasterZivВася УткинНо ведь в случае с web-сервером, например, каждый вызов страницы - это открытие и закрытие нового соединения. Вовсе не обязательно. Есть keep-alive. Вася Уткин А если на web-сервере страницы статичные и быстро создаются, то нельзя сказать, что "основная работа с сервисом происходит все-таки в одном потоке" по сравнению с засыпанием acceptor-a на мьютексе и ожидания пока он снова проснется, ведь пока acceptor спит ни одно новое соединение не может быть создано. Переведи ... Что непонятно, что эта очередь на мьютексе?Anatoly Moskovsky Поток accept добавляет хендлер в очередь одного из сервисов в пуле... Или что поток accept может на этом мьютексе заснуть (переключится контекст в ожидании освобождения мьютекса)? Или что поток accept ожидающий мьютекса не может принимать соединения? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2014, 17:21 |
|
||
|
Высоко-нагруженный сервер на ubuntu - С++ под Linux
|
|||
|---|---|---|---|
|
#18+
Вася Уткин, Я в упор тебя не понимаю. Этот accept ? http://msdn.microsoft.com/en-us/library/windows/desktop/ms737526(v=vs.85).aspx (или его POSIX-аналог) Почему он должен висеть на мьютексе ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2014, 17:59 |
|
||
|
Высоко-нагруженный сервер на ubuntu - С++ под Linux
|
|||
|---|---|---|---|
|
#18+
MasterZivВася Уткин, Я в упор тебя не понимаю. Этот accept ? http://msdn.microsoft.com/en-us/library/windows/desktop/ms737526(v=vs.85).aspx (или его POSIX-аналог) Почему он должен висеть на мьютексе ? Потому что надо читать сначала - мы говорим про Boost.Asio :) и в нем вызов async_write/async_read - это добавление хендлера в мьютексную очередь. Мы говорим не про функцию accept, а про весь поток-acceptor, который создает сокет, вызывает accept и отдает этот сокет в один из потоков в пуле. Anatoly Moskovsky Поток accept добавляет хендлер в очередь одного из сервисов в пуле... Когда Поток accept вызывает async_write/async_read - добавляет в мьютексную очередь, а один из сервисов в одном из потоков из пула потоков читает из этой очереди в хендлер для исполнения, что происходит? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2014, 18:17 |
|
||
|
Высоко-нагруженный сервер на ubuntu - С++ под Linux
|
|||
|---|---|---|---|
|
#18+
Вася Уткин, Не, эт я не понимаю. Эт к Анатолию. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2014, 18:36 |
|
||
|
Высоко-нагруженный сервер на ubuntu - С++ под Linux
|
|||
|---|---|---|---|
|
#18+
Вася Уткин, Вопросы увидел - отвечу позже, счас некогда вдумываться. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2014, 20:04 |
|
||
|
Высоко-нагруженный сервер на ubuntu - С++ под Linux
|
|||
|---|---|---|---|
|
#18+
По-моему так всё просто: Висишь на select-е (или poll/epoll) . Владеешь всеми хендлерами сокетов. select генерирует событие. по всем сработавшим сокетам (по каждому) создаём задачу на обработке в пуле коннектов, хватаем мьютекс очереди, пихаем задачи в очередь, отдаём мьютекс. Отдаными сокетами более не владеем. Взводим event/semaphore, что есть задачи. потоки пула просыпаются, каждый хвать мьютекс, хвать себе задачу. Отдать мьютекс и делать задачу (обрабатывать запрос). Если нужна новая задача, порождаемая обработкой, -- тот же механизм. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2014, 21:48 |
|
||
|
|

start [/forum/topic.php?fid=57&msg=38526906&tid=2019760]: |
0ms |
get settings: |
7ms |
get forum list: |
12ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
174ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
51ms |
get tp. blocked users: |
1ms |
| others: | 11ms |
| total: | 273ms |

| 0 / 0 |
