Асинхронные серверы
Primary tabs
Forums:
Добрый день, сегодня немного упомяну об асинхронной серверной архитектуре. Это вводная статья, не привязанная к конкретным языкам, серверам и фраемворкам. Далее я буду рассказывать об проектрировании и написании приложений на Python Tornado. А пока, определимся, а что-же такое асинхронный Web сервер?
--
В литературе асинхронные серверы также называются неблокирующими. Но чтобы понять чтоже это такое, вспомним историю:
Изначально были и есть многопоточные серверы, в которых создаётся пул (некое заранее выделенное, созданное, количество) процессов или потоков и каждый процесс или поток отводился на обработку одного соединения.
Для программиста это выглядило как написание обычного однопоточного приложения, которое о своих прошлых запусках или о запусках своих собратов узновало только из базы данных. Проблемы были лишь в том случае когда не хотелось чтобы все потоки лезли в БД за какими нибудь общими и довольно небольшими данными, скажем кэш, в этом случае нужно было использовать разделяемые ресурсы, обычно это отдельные сервер кэширования.
Но какие проблемы в производительности: Во-первых нагрузка на планировщик - много потоков или , теб паче, процессов (хотя это самый маленький и ничтожный недостаток можно про него забыть). Во-вторых, если у нас пул из 100 процессов, то при 100 подключений 101 будет отброшено - это не всегда хорошо, тем более если мы используем технологию long polling. А крупные игроки в сети столкнулись с проблемой 10k. Бот неты подбросили DDOS.
И как с этим справиться? От части помогла асинхронная архитектура, которая гласит:
У нас будет основная петля (очередь) куда будут помещаться все запросы и один процесс, которыя будет эту очередь обслуживать и он будет стараться почти мгновенно обрабатывать каждый запрос, если же запрос требудет долгого выполнения мы отправляем его в очередь к другому процессу, а все блокирующие операции (такие как запрос к базе данных или к другому серверу) мы будем производить асинхронно.
Так как сейчас существуют 12-ти ядерные процессоры, то не всегда актуально держать один процесс для работы с основной петлёй, поэтому существуют расширения архитектуры на несколько процессов. Обычно общее количество процессов не должно превышать количество ядер процессора.
Более подробно об асинхроннной архитектуре можно почитать по ссылке:
http://habrahabr.ru/post/150788/
А я тем врменем перейду к основному:
Достоинства и недостатки асинхронной архитектуры по сравнению с многопоточной. Рекомендации к выбору архитектуры.
-- Достоинства:
- 1) Решение проблемы 10k.
- 2) Более высокая отзывчивость легковестных приложений.
- 3) Более эффективное использование процессорного времени.
- 4) Усложнение реализации DOS и DDOS атак, теперь просто открыть большое количество долгих соединений не достаточно.
- 5) Возможно гибкое управление нагрузкой, Пока "Большие запросы" выполняются асинхронно и тупят, "Маленькие" свободно выполняются.
-- Недостатки:
- 1) Если уж система начала тупить, то она тупит для всех одинакого.
- 2) Высокая нагрузка на разработчика, теперь надо в ручную поддерживать многопоточность для обработки "Больших" запросов и использовать либо асинхронные библиотеки для блокирующих запросов, либо вручную реализовывать асинхронную обработку. Для маленьких и простых проектов данные неудобства малозаметны, но для специфичных задач это может породить массу проблем, к примеру не так легко разобраться с "асинхронными сокетами".
- 3) Более высокий порог вхождения. Нет права ошибиться в архитектуре web приложения. Нужен опыт в построении высокопроизводительных систем иначе придётся не раз всё переделывать.
--Рекомендации к использованию: (опираясь на данную литературу: ссылка)
- 1) Для тех кто любит "модно. молодёжно, современно"
- 2) Актуально при разработки высоконагруженных веб-серверов.
- 3) При использовании большого количества блокирующих вызовов.
- 4) Если используете Long polling
- 5) Если используете Web sockets
- 6) Если используете Comet
- 7) Актуально. если необходимо увеличить устойчивость системы при DOS атаке.
- 8) Если в вашей системе огромное количество маленьких "лёгких" запросов от огромного количества клиентов - то рекомендую асинхронную архитектуру.
- Log in to post comments
- 9119 reads
vedro-compota
Wed, 01/22/2014 - 21:25
Permalink
Для программиста это
ммм...ну это же просто многопоточный сервер? да? многопоточность - она же в принципе "параллельна", а потому асинхронна? разве нет?
_____________
матфак вгу и остальная классика =)
humanmashine
Wed, 01/22/2014 - 22:00
Permalink
Не совсем так
Для понимания я советую прочитать тут: http://habrahabr.ru/post/150788/
Я эту ссылку не случайно дал.
Но чтобы было понятнее приведу пример того как обрабатывается запрос.
----- Классическая многопоточная архитектура:
1) У нас пул из 100 процессов. Клиент присылает запрос, установив соединение. Клиент занимает один процесс и у нас остаются 99 свободных, к которым будут обращаться другие клиенты.
2) Во время обработки запроса наш серверный процесс обращается к базе данных. На время обращения он блокируется и засыпает и не обрабатывает других клиентов и не закрывает соединение с клиентом. Поэтому для обработки остальных запросов у нас по прежнему 99 потоков.
3) Когда БД возвращает ответ процесс серверный заканчивает обработку запроса, отправляет данные клиенту и закрывает соединение, вуаля, он снова готов принимать запросы.
Подытожим. Наш сервер блокируется при запросе к БД. По сути сервер многопоточная архитектура - это много экземпляров нашего сервера, чтобы в то время как заблокируется один его работу выполнили другие экземпляры.
------- Асинхронная архитектура.
1) У нас главная петля - очередь, и один главный процесс.
2) Клиент отправляет запрос. Запрос становится в очередь.
3) Главный процесс смотрит, если этот запрос можно почти моментально выполнить - выполняем и берём следующий из очереди. (Пока мы смотрели могло ещё несколько запросов придти)
4) Если запрос выполнить сразу не получается (скажем опять запрос к БД), то главный процесс отправляет этот запрос на выполнение асинхронно (в другом потоке, или ещё как нибудь - не важно, главное чтобы параллельно и не блокироваться). И приступает к обработке следующего запроса (Тут вся фишка..), а запрос к БД выполняется где-то на фоне.
5) Запрос к БД выполнился и асинхронный обработчик поместил его в конец очереди (петли)
6) Главный процесс добрался до выполненного запроса, передал данные клиенту и закрыл соединение.
Вот отличия грубо. По настоящему всё может быть немного иначе в асинхронной архитектуре - это один из вариантов. Можно по разному её реализовать.