Я выполнил последовательную обработку сообщений в кластере в довольно большом масштабе - 1,5 миллиона + сообщений в день, используя комбинацию паттерна «Конкурирующие потребители» и паттерна аренды.
Но вот что интересно: ваше требование, чтобы вы могли обрабатывать только одну транзакцию за раз, будет удерживать вас от достижения ваших целей. У нас было одно и то же основное требование - сообщения нужно было обрабатывать по порядку. По крайней мере, мы так думали. Затем нас осенило - когда мы больше задумались над проблемой, мы поняли, что не нуждаемся в полном упорядочивании. На самом деле нам требовался заказ только внутри каждого аккаунта. Следовательно, мы могли распределить нагрузку между серверами в кластере, назначив диапазоны учетных записей различным серверам в кластере. Затем каждый сервер отвечал за обработку сообщений для данной учетной записи по порядку.
Вот вторая умная часть - мы использовали шаблон аренды, динамически назначающий диапазоны учетных записей различным серверам в кластере. Если один сервер в кластере выйдет из строя, другой возьмет на себя аренду и возьмет на себя ответственность первого сервера.
Это сработало для нас, и процесс жил в производстве около 4 лет, прежде чем был заменен из-за слияния компаний.
Редактировать:
Я объясняю это решение более подробно здесь: http://coders-log.blogspot.com/2008/12/favorite-projects-series-installment-2.html
Редактировать:
Хорошо, понял. Вы уже выполняете обработку на нужном вам уровне, но, поскольку вы развертываете кластер, вам необходимо убедиться, что только один экземпляр вашего MDB активно извлекает сообщения из очереди. Кроме того, вам нужно простейшее работоспособное решение.
Я не думаю, что вам не нужно отказываться от вашего механизма MDB, который у вас есть сейчас. По сути, то, о чем мы здесь говорим, - это требование для механизма распределенной блокировки, если не использовать слишком причудливую фразу.
Итак, позвольте мне предложить это. В момент, когда ваш MDB регистрируется для получения сообщений из очереди, он должен проверить распределенную блокировку и посмотреть, сможет ли он ее захватить. Первый MDB, который захватит блокировку, побеждает, и только он зарегистрируется для получения сообщений. Итак, теперь у вас есть сериализация. Какую форму должен принимать этот замок? Есть много возможностей. Ну как насчет этого. Если у вас есть доступ к базе данных, ее транзакционная блокировка уже дает вам кое-что из того, что вам нужно. Создайте таблицу с одной строкой. В строке указан идентификатор сервера, на котором в данный момент находится блокировка, и время истечения срока действия. Это аренда сервера. У каждого сервера должен быть способ сгенерировать свой уникальный идентификатор, например, имя сервера плюс идентификатор потока.
Если сервер может получить доступ к обновлению строки, а срок аренды истек, он должен получить ее. В противном случае он сдается. Если он получает аренду, ему необходимо обновить строку, указав время в ближайшем будущем, например, пять минут или около того, и зафиксировать обновление. Активный сервер должен обновить аренду до истечения ее срока. Я рекомендую обновлять его, когда остается половина времени, поэтому каждые 2-1 / 2 минуты, если срок аренды истекает через пять. Теперь у вас есть аварийное переключение. Если активный MDB умирает, его возьмет на себя другой MDB (и только один).
Думаю, это должно быть довольно просто. Теперь вы хотите, чтобы бездействующие MDB время от времени проверяли блокировку, чтобы видеть, освобождена ли она.
Таким образом, активный MDB и бездействующий MDB должны периодически что-то делать. Для этого вы можете создать отдельный поток. Многие поставщики движков приложений будут недовольны, если вы сделаете это, но добавление одного потока не представляет большого труда, тем более что большую часть времени он проводит в спящем режиме. Другой вариант - привязать к механизму таймера, который предоставляют многие движки, и периодически просыпать ваш MDB для проверки аренды.
Да, и между прочим - убедитесь, что администраторы сервера используют NTP для разумной синхронизации часов.
person
Don Branson
schedule
11.09.2009