Общая база данных с заданиями в ней - PullRequest
0 голосов
/ 20 февраля 2019

Вопрос проистекает из обсуждения с коллегой.

TLDR : мне кажется, что мы, вероятно, не первая компания / команда, имеющая проблему с несколькими заданиями на чтение серверовиз базы данных, и мне интересно, что такое «правильная» архитектура - это предлагаемое решение (каждый сервер записывает свой идентификатор в запрос в БД, а затем только заботится о своих собственных запросах) правильный путь или есть лучшие архитектурыдля этой проблемы?Я предложил всем серверам позаботиться обо всех заданиях и пометить записи как «выполняющиеся» или заблокировать их или что-то в этом роде)?И действительно ли это такая новая и экзотическая особенность, что база данных возвращает только незафиксированные записи?Как это было сделано до того, как появилась эта функция?


Задача, которую необходимо решить :

  • служба получает запросы: запрос в основном говорит "пожалуйстасообщите мне, когда сделка X будет завершена ".Транзакция выполняется третьей стороной, недоступной для того, кто вызывает службу.
  • Как только транзакция X завершена, вызывающий службу должен быть отозван.

Это неподвижные детали, которые требуются клиенту, как это.

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

Решение в том виде, в каком оно реализуется :

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

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

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

Для меня это кажется неправильным - ИМХО : не важно, какая служба написала запрос вБД.Я думаю, что каждый синхронизируемый компонент должен иметь возможность обрабатывать любые запросы, ожидающие обработки.Но коллега сказал, что это невозможно, потому что как сервер узнает, обрабатывается запись или нет?Я думал, что запись должна быть просто заблокирована или помечена как «в процессе», если сервер работает над этим.Но утверждалось, что тогда другой сервер будет заблокирован в ожидании этого ожидающего запроса - обсуждение проходило взад и вперед, и я обнаружил, что на самом деле можно запросить только неблокированные записи (например, здесь: Выбрать только разблокированные строки mysql).Затем утверждалось, что это, вероятно, очень новая и экзотическая особенность, и, вероятно, просто безопаснее, проще и лучше использовать подход «каждый сервер обрабатывает только запросы, которые сам записан в базу данных».Другим вопросом обсуждения было то, должен ли сервер получать все ожидающие запросы или только один запрос - в варианте, где каждый сервер получает только свои собственные запросы, все они должны быть извлечены одновременно.Мы можем предположить, что это будет довольно большой нагрузкой (вероятно, порядка нескольких сотен или даже тысяч запросов, записываемых в БД в секунду), поэтому производительность является проблемой.

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

...