Мы обрабатываем сообщения с помощью различных сервисов (одно сообщение будет касаться, вероятно, 9 сервисов, прежде чем оно будет выполнено, каждое из которых выполняет определенную функцию, связанную с IO). Прямо сейчас у нас есть комбинация наихудшего случая (сериализация контракта данных XML) и наилучшего (производительность в памяти MSMQ) для производительности.
Характер сообщения означает, что наши сериализованные данные занимают около 12-15 килобайт, и мы обрабатываем около 4 миллионов сообщений в неделю. Постоянные сообщения в MSMQ были слишком медленными для нас, и по мере роста данных мы ощущаем давление со стороны отображаемых в памяти файлов MSMQ. Сервер использует 16 ГБ памяти и продолжает расти, просто для очередей. Производительность также страдает, когда использование памяти велико, так как машина начинает обмениваться. Мы уже выполняем самоочищение MSMQ.
Я чувствую, что есть часть, которую мы делаем неправильно здесь. Я пытался использовать RavenDB для сохранения сообщений и просто ставить в очередь идентификатор, но производительность там была очень медленной (в лучшем случае 1000 сообщений в минуту). Я не уверен, является ли это результатом использования версии для разработки или чего-то еще, но нам определенно нужна более высокая пропускная способность [1]. Концепция сработала очень хорошо в теории, но производительность не соответствовала задаче.
Шаблон использования имеет один сервис, выполняющий роль маршрутизатора, который выполняет все операции чтения. Другие сервисы будут прикреплять информацию, основанную на подключении сторонних производителей, и пересылать обратно к маршрутизатору. Большинство объектов касаются 9-12 раз, хотя около 10% вынуждены обходиться в этой системе некоторое время, пока третьи стороны не отреагируют соответствующим образом. Службы прямо сейчас учитывают это и имеют соответствующие спящие режимы, поскольку по этой причине мы используем поле приоритета сообщения.
Итак, мой вопрос: что такое идеальный стек для передачи сообщений между компьютерами с дискретной, но локальной сетью в среде C # / Windows? Я бы обычно начинал с BinaryFormatter вместо XML-сериализации, но это кроличья нора, если лучшим способом будет переложить сериализацию в хранилище документов. Отсюда и мой вопрос.
[1]: характер нашего бизнеса означает, что чем раньше мы обрабатываем сообщения, тем больше мы зарабатываем. Мы эмпирически доказали, что обработка сообщения в конце недели означает, что мы с меньшей вероятностью заработаем эти деньги. В то время как производительность «1000 в минуту» звучит достаточно быстро, нам действительно нужно это число выше 10k / мин. То, что я даю цифры в сообщениях в неделю, не означает, что у нас есть целая неделя для обработки этих сообщений.
=============== изменить:
Дополнительная информация
Основываясь на комментариях, я добавлю некоторые разъяснения:
Я не уверен, что сериализация является нашим узким местом. Я провел сравнительный анализ приложения, и хотя сериализация действительно отображается на графике, она отвечает только за 2,5-3% загрузки ЦП службы.
Меня больше всего беспокоит постоянство наших сообщений и потенциальное неправильное использование MSMQ. Мы используем нетранзакционные, непостоянные сообщения, чтобы мы могли поддерживать производительность в очереди, и мне бы очень хотелось, чтобы по крайней мере постоянные сообщения оставались после перезагрузки.
Добавление дополнительной оперативной памяти является мерой временного ограничения. Машина уже ушла с 4 ГБ -> 16 ГБ ОЗУ, и становится все труднее снимать ее, чтобы продолжать добавлять больше.
Из-за паттерна маршрутизации «звезда» приложения, половина времени, когда объект извлекается, а затем помещается в очередь, не меняется вообще. Это снова позволяет (IMO) хранить его в каком-либо хранилище значений ключей в другом месте и просто передавать идентификаторы сообщений.
Шаблон звездообразной маршрутизации является неотъемлемой частью приложения и не изменится. Мы не можем применять его к многоножкам, потому что каждая часть в процессе работы работает асинхронно (методом опроса), и мы хотим централизовать поведение повторов в одном месте.
Логика приложения написана на C #, объекты являются неизменяемыми POCO, целевая среда развертывания - Windows Server 2012, и нам разрешено устанавливать дополнительные компьютеры, если конкретный фрагмент программного обеспечения поддерживается только в Linux.
Мои цели - поддерживать текущую пропускную способность, уменьшая объем памяти и повышая отказоустойчивость при минимальных затратах капитала.