Как следует использовать Disruptor (Шаблон прерывателя) для построения реальных систем сообщений? - PullRequest
28 голосов
/ 04 августа 2011

Поскольку RingBuffer заранее выделяет объекты данного типа, как вы можете использовать один кольцевой буфер для обработки сообщений различных типов?

Невозможно создать новые экземпляры объектов для вставки вringBuffer и это лишило бы цели начального распределения.

Таким образом, вы можете иметь 3 сообщения в шаблоне асинхронного обмена сообщениями:

  1. NewOrderRequest
  2. NewOrderCreated
  3. NewOrderRejected

Итак, мой вопрос: как вы собираетесь использовать шаблон Disruptor для реальных систем сообщений?

Спасибо

Ссылки: http://code.google.com/p/disruptor-net/wiki/CodeExamples

http://code.google.com/p/disruptor-net

http://code.google.com/p/disruptor

Ответы [ 3 ]

32 голосов
/ 04 августа 2011

Один из подходов (наш самый распространенный шаблон) заключается в сохранении сообщения в его маршалированной форме, то есть в виде байтового массива.Для входящих запросов, например, Fix сообщения, двоичное сообщение, быстро извлекаются из сети и помещаются в кольцевой буфер.Распаковка и отправка различных типов сообщений обрабатываются EventProcessors (Потребителями) в этом кольцевом буфере.Для исходящих запросов сообщение сериализуется в предварительно выделенный байтовый массив, который формирует запись в кольцевом буфере.

Если вы используете некоторый байтовый массив фиксированного размера в качестве предварительно выделенной записи, для обработки переполнения требуется некоторая дополнительная логикадля больших сообщений.Т.е. выбрать разумный размер по умолчанию и, если он превышен, выделить временный массив, который больше.Затем отбросьте его, когда запись используется повторно или используется (в зависимости от вашего варианта использования), возвращаясь к исходному предварительно выделенному байтовому массиву.

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

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

6 голосов
/ 04 апреля 2012

Существует библиотека под названием Javolution (http://javolution.org/)), которая позволяет вам определять объекты как структуры с полями фиксированной длины, такими как строка [40] и т. Д., Которые полагаются на байтовые буферы внутри, а не на объекты переменного размера ..., что позволяет Token Ring должен быть инициализирован объектами фиксированного размера и, таким образом (будем надеяться), смежными блоками памяти, которые позволяют кешу работать более эффективно.

Мы используем это для передачи событий / сообщений и используем стандартные строки и т. Д. Для нашей бизнес-логики.

0 голосов
/ 17 марта 2018

Вернуться к пулам объектов.

Следующая гипотеза.

Если у вас будет 3 типа сообщений (A, B, C), вы можете сделать 3 массива из этих предварительно распределенных. Это создаст 3 зоны памяти A, B, C.

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

Таким образом, запись кольцевого буфера может иметь 1 ссылку на общего предка или интерфейс A & B & C.

Проблема заключается в выборе экземпляра в пулах; самое простое - иметь длину массива, равную длине кольцевого буфера. Это подразумевает много потраченных впустую объединенных объектов, поскольку только одна из 3-х когда-либо используется в любой записи, например: запись кольцевого буфера 1234 может использовать сообщение B [1234], но A [1234] и C [1234] не используются и не могут использоваться кем угодно.

Вы также можете создать суперпозицию со всеми 3 экземплярами A + B + C и указать тип некоторым байтом или перечислением. Точно так же расточительно по объему памяти, но выглядит немного хуже из-за жирности записи. Например, читатель, работающий только с сообщениями C, будет иметь меньшую локальность кэша.

Надеюсь, я не слишком ошибаюсь с этой гипотезой.

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