Архитектура обработки входящих запросов в сервисе - PullRequest
3 голосов
/ 04 ноября 2011

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

Вот список моих целей:

  • Масштабируемость - должна иметь возможность распараллеливать архитектуру на нескольких процессорах или даже на нескольких серверах.
  • Способность справляться с огромным количеством параллельных соединений.
  • Не должна вызывать блокировкупроблемы, если обработка одного запроса занимает много времени.
  • Время обработки запроса должно быть минимальным.
  • Построен на основе .NET Framework (будет писать это в C #)

Моя предложенная архитектура и процесс довольно сложны, поэтому вот диаграмма моего начального дизайна:

Architecture Flow Chart

здесь это на tinypic на случай, если он плохо изменяет размер)

Идея состоит в том, что запросы поступают через сеть (хотя я еще не решил, будет ли лучше использовать TCP или UDP) и сразу же передаются высокоскоростной загрузке.балансировкаэ.Затем балансировщик нагрузки выбирает очередь запросов (RQ) для размещения запроса, используя генератор взвешенных случайных чисел.Веса выводятся из размера каждой очереди.Причина использования взвешенного ГСЧ, а не просто помещения запросов в наименее загруженную очередь, заключается в том, что она предотвращает блокировку всего сервера пустой, но заблокированной очередью (из-за зависшего запроса).Если все RQ превышают определенный размер, балансировщик нагрузки отбрасывает запрос и помещает ответ «сервер слишком занят» в очередь вывода (OPQ) - эта часть не показана на диаграмме .

Каждая очередь соответствует потоку, сходство которого установлено на одно ядро ​​ЦП на сервере.Эти потоки являются частью параллельного процессора запросов, который потребляет запросы из каждой очереди.Запросы подразделяются на три типа:

  1. Немедленно - Немедленные запросы, как следует из названия, обрабатываются немедленно.

  2. Отложенный - Отложенные запросы считаются низко приоритетными.Они обрабатываются немедленно во время низкой нагрузки или помещаются в очередь отложенных запросов (DRQ), если нагрузка высокая.Балансировщик нагрузки извлекает эти отложенные запросы из DRQ, отмечает их как немедленные, а затем помещает обратно в соответствующие RQ.

  3. Timed - синхронизированные запросы помещаются вочередь запросов по времени (TRQ) вместе с их целевой меткой времени.Эти запросы часто генерируются в результате другого запроса, а не отправляются явно клиентом.При превышении отметки времени запроса следующий доступный поток процессора запросов использует ее и обрабатывает.

Когда запрос обрабатывается, данные могут быть получены из кэша пар ключ / значение в памятикеш пары ключ / значение либо на диске, либо с выделенного сервера баз данных SQL.Кэшированные значения будут BSON, а индекс будет строкой.Я имею в виду использование Dictionary<T1,T2> для реализации этого в памяти и btree (или аналогичного) для дискового кэша.

Ответ создается по завершении обработки и помещается в очередь вывода(OPQ).Затем цикл принимает ответы от OPQ и передает их клиенту по сети.Если OPQ достигает 80% своего максимального размера, одна четверть потоков процессора запросов останавливается.Если OPQ достигает 90% своего максимального размера, половина потоков процессора запросов останавливается.Если OPQ достигает своего максимального размера, все потоки процессора запросов останавливаются.Это будет достигнуто с помощью семафора, который также должен предотвращать блокировку потоков отдельных запросов и оставление устаревших запросов.

Мне нужны предложения по нескольким областям:

  • Есть ли какие-то серьезные недостатки в этой архитектуре, которые я пропустил?
  • Что-то, что я должен рассмотреть, чтобы изменить по соображениям производительности?
  • Будет ли TCP или UDP более подходящим для запросов?Было бы очень полезно иметь «доказательство доставки», которое предлагает TCP, но привлекательный характер UDP тоже привлекателен.
  • Есть ли какие-то особые соображения, о которых мне следует подумать при работе с одновременными соединениями 100k +на сервере Windows?Я знаю, что стек TCP Linux хорошо работает, но я не очень уверен в Windows.
  • Есть ли еще вопросы, которые я должен задать?Я забыл обдумать что-нибудь?

Я знаю, что это было много, чтобы прочитать, и, вероятно, довольно много, чтобы спросить тоже, так что спасибо за ваше время.* Обновленная версия диаграммы здесь .

Ответы [ 3 ]

2 голосов
/ 04 ноября 2011

Также вы можете рассмотреть следующие вопросы:

  • Failover. Вы можете разработать подход для сохранения запросов во время возможных сбоев службы, поэтому все ожидающие запросы будут обрабатываться даже после перезапуска службы
  • Очередь ошибок. (также известный как Канал мертвой буквы * шаблон 1007 *)
  • Трубы и фильтры . Предоставляя такую ​​функцию, вы достигнете высокого уровня гибкости и расширяемости услуги
  • Запрос подтверждения. В некоторый предопределенный интервал времени клиент, который отправил запрос в службу, ожидающую Ack-сообщение с CorrelationId, установленным в начальный RequestId, таким образом, служба может уведомить клиентов о том, что конкретный запрос получен и помещен во входящую очередь, если клиент не получить Ack для только что отправленного запроса - он может отправить его повторно или пометить как неудачный.

PS: Также я бы предложил отличную книгу " Шаблоны интеграции предприятия "

1 голос
/ 04 ноября 2011

Я не понимаю, зачем вам нужно несколько очередей запросов. Мне кажется, вам нужна только одна очередь запросов, и многие процессоры все читают из нее. Это не должно быть проблемой с любой системой очередей. Наличие только одной очереди отделяет входные данные от процессоров, обеспечивая лучшую масштабируемость - при необходимости запускайте больше процессоров, больше никому об этом не нужно заботиться.

Что касается TCP против UDP - какую производительность вы ищете? И не лучше ли использовать какую-то существующую коммуникационную инфраструктуру, такую ​​как ZeroMQ, чтобы позаботиться об этих технических деталях для вас?

Итай.

0 голосов
/ 04 ноября 2011

Если вы хотите, чтобы это масштабировалось очень хорошо, вам нужно убедиться, что все компоненты масштабируемы - элементы обработки, элементы ввода / вывода и очереди.Если вы собираетесь делать это в стеке Microsoft, я бы настоятельно рекомендовал изучить Windows Azure, которая предлагает большинство, если не все, ключевые функции, которые вам понадобятся.Одна вещь, которую вы не упомянули - будет ли постоянный уровень хранения (например, база данных)?Если это так, будьте готовы масштабировать это тоже, иначе это станет вашей единственной точкой отказа.

...