Критически эффективный сервер - PullRequest
3 голосов
/ 21 мая 2009

Я разрабатываю клиент-серверное приложение для финансовых предупреждений, где клиент может установить значение в качестве предупреждения для выбранного финансового инструмента, и когда это значение будет достигнуто, сервер мониторинга каким-то образом оповестит клиента (электронная почта, смс ... не важно). Сервер будет следить за обновлениями, которые приходят из программы генератора данных. Теперь сервер должен быть очень эффективным, поскольку он должен обрабатывать множество клиентов (возможно более 50-100 000 предупреждений, с обновлениями, приходящими через 1,2 секунды). Я писал серверы раньше, но никогда с такими навязанными характеристиками, и я Я просто боюсь, что базовый подход (как и раньше) просто не сделает этого. Итак, как мне спроектировать сервер? Какие структуры данных лучше всего подходят? .. Как насчет многопоточности? .... В общем, что я должен делать (и что не должен делать), чтобы выжать каждую каплю производительности из это?

Спасибо.

Ответы [ 9 ]

3 голосов
/ 21 мая 2009

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

Такие проекты, как Apache ActiveMQ или RabbitMQ уже широко используются и хорошо настроены и должны поддерживать тип нагрузки, о которой вы говорите, вне коробки.

3 голосов
/ 21 мая 2009

Я работал на таких серверах раньше. Все они были написаны на C (или довольно простом C ++). Но их производительность была еще выше - они обрабатывали 20 тыс. Обновлений в секунду (все обновления с большинства крупных бирж).

Мы бы сосредоточились на том, чтобы не копировать память. Мы были очень осторожны в том, какие классы STL мы использовали. Что касается обновлений, то каждый финансовый инструмент будет объектом, и любые клиенты, которые хотят услышать об этом инструменте, подпишутся на него (т.е. будут добавлены в список).

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

РЕДАКТИРОВАТЬ: Да, и, прежде чем я забуду, количество финансовых транзакций растет в геометрической прогрессии. Этот сервер со скоростью 20 Кбит / с едва успевал за работой, и архитекторы были обеспокоены тем, что делать в следующем году. Я слышал, что все крупные финансовые фирмы сталкиваются с похожими проблемами.

0 голосов
/ 22 мая 2009

Вероятно, платформа сетевого приложения Apache Mina , а также Apache Camel для маршрутизации сообщений являются хорошей отправной точкой. Также Kilim фреймворк для передачи сообщений выглядит очень многообещающе.

0 голосов
/ 22 мая 2009

Вам следует попытаться найти способ упорядочить оповещения в виде дерева и быстро решить, какие оповещения могут быть вызваны обновлением.

Например, давайте предположим, что предупреждение - это уровень определенного индикатора. Указанный индикатор может иметь диапазон 0, n. Я бы сгруппировал клиентов, которые хотят получать уведомления об уровне указанного индикатора, в виде двоичного дерева. Таким образом, вы можете масштабировать его должным образом (вы можете реализовать поддерево как процесс на другом компьютере), и количество совпадений, необходимое для поиска подходящего подмножества клиентов, всегда будет логарифмическим.

0 голосов
/ 21 мая 2009

Один поток для получения обновлений прибора, который обработает обновление и поместит его в BlockingQueue.

Один поток, чтобы взять обновление из BlockingQueue и передать его процессу, который обрабатывает этот инструмент или набор инструментов. Этот процесс должен будет сериализовать события для инструмента, чтобы клиент не получал уведомления вне очереди.

Этот процесс (Поток) должен будет повторяться в списке зарегистрированных клиентов, чтобы получать уведомления и создавать список клиентов, которых следует уведомлять на основе их критериев. Затем процесс должен передать список другому процессу, который уведомит клиента об изменении.

Процесс уведомления должен проходить по списку и отправлять каждое событие уведомления другому процессу, который обрабатывает, как клиент хочет получать уведомления (электронная почта и т. Д.).

Одной из проблем будет то, что при 100 000 клиентов синхронизируется доступ к списку клиентов и их критериям для мониторинга.

0 голосов
/ 21 мая 2009

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

Итак, во-первых, отделите процесс мониторинга обновлений от процесса оповещения. DougN описывает наличие отдельных потоков для каждого, это начало. Как только один процесс отвечает за мониторинг обновлений, пусть он передает эти обновления по протоколу сокетного типа по вашему выбору каждому из масштабируемого числа дронов-оповещателей, каждый из которых отвечает за некоторое подмножество предупреждений, которые должны быть отправлены. Тогда вы готовы отправить миллион предупреждений за одно обновление, ничего не замедляя.

Конечно, если вы делаете все это в одном окне, то ваш фактический механизм оповещения (почтовый сервер и т. Д.) Может стать узким местом.

0 голосов
/ 21 мая 2009

Остерегайтесь любой архитектуры, которой требуются кластерные серверы приложений, чтобы получить разумную степень производительности. У Лондонской фондовой биржи недавно была такая проблема , когда они вытянули существующую систему на базе Tandem и заменили ее кластерными серверами .Net.

У вас будет много проблем с получением такого типа производительности с одного сервера Java или .Net - вам действительно нужно рассмотреть C или C ++. Кластерная архитектура гораздо более подвержена ошибкам при построении и развертывании, и ее труднее гарантировать время безотказной работы.

Для действительно больших объемов вы должны думать об использовании асинхронного ввода-вывода для работы в сети (например, poll (), select () и асинхронных записей или их эквивалентов в Windows), возможно, с пулом рабочих потоков. Прочтите о проблеме C10K, чтобы узнать больше об этом.

Существует очень зрелая среда C ++, называемая ACE (Adaptive Communications Environment), которая была разработана для серверных приложений большого объема в телекоммуникациях. Это может быть хорошей основой для вашего продукта - он поддерживает множество моделей параллелизма и имеет дело с большинством основных моментов синхронизации в рамках. Возможно, вы поймете, что время, потраченное на изучение управления этой платформой, окупается затратами на разработку и упрощение внедрения и тестирования.

0 голосов
/ 21 мая 2009

Лучший совет - спроектировать сервер так, чтобы он масштабировался горизонтально.

Это означает, что ваши входные события рассылаются на один или несколько серверов (на одном и том же или разных компьютерах), которые индивидуально решают, нужно ли им обрабатывать определенное сообщение.

Будете ли вы поддерживать 50 000 клиентов в первый день? Тогда это должно быть ваше внимание: как легко вы можете определить потребности одного клиента, и сколько клиентов вы можете поддерживать на одном сервере?

Второй лучший совет - не искусственно ограничивать себя. Если вы говорите «мы не можем позволить себе иметь более одной машины», то вы уже настроили себя на неудачу.

0 голосов
/ 21 мая 2009

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...