Благодаря постоянному развитию бизнес-потенциала,Нам все чаще приходится отделяться и работать асинхронно в крупных компаниях.,В это времяочередь Показаны преимущества сообщений, мы будем отправлять бизнес-сообщения для обработки в свою очередь. сообщенийсередина,проходитьочередь Сообщение Асинхронные операции завершают обработку бизнеса, тем самым улучшая возможности обработки бизнеса, а затем сообщений Как гарантироватьИдемпотентность потребленияШерстяная ткань,Целью данной статьи является изучение того, как обеспечитьочередь Идемпотентность сообщений
Возьмем, к примеру, бизнес по обработке заказов пользователей на потребление.,Если пользователь инициирует несколько запросов на создание заказа одновременно (конечно,,Это также можно сделать через интерфейсное обсуждение.,Здесь рассматривается, как передать бэкэнд-суждение),Затем в это время отправляется несколько запросов,очень просто,мы можем сначаласуждениеТекущий статус заказа пользователяБыло ли оно обновлено?,Если он уже был обновлен, нам не нужно обновлять его снова.,Но здесь будет проблема,Если бизнес по обработке заказов требуетзанимает много времени,В параллельном сценарии на сервер одновременно поступает несколько запросов.,Возможно, статус сейчас обновляется.,Но по факту суждение не вступает в силу,Поэтому самый простой методДело обременительноене работает в сценариях, где
Тогда мы подумали,Так как нет возможности обновить первое обсуждение,Почему бы нам просто не добавить замок?,непосредственно при поступлении первого запроса,Просто добавьте блокировку в код, который обрабатывает бизнес.,Это гарантирует, что даже если будут отправлены другие запросы,Это не приведет к повторному выполнению текущего бизнеса.,без сомнения,Это гарантирует, что одно и то же задание будет выполнено только один раз, даже если оно будет отправлено несколько раз.,носуществоватьВысокий параллелизмВ сцене,Это будет значительноуменьшатьЭффективность общего ведения бизнеса。
Возьмите две ветки оптимистичного замка. блокировкаипессимистический замок Пример,Если мы используемпессимистический замок,Когда приходит первый запрос, сразу весь бизнес блокируется.,Затем, когда приходят другие запросы,Просто нужно подождать,Это улучшает производительность других сервисов.,Выигрыш перевешивает потерю,и Если мы используемоптимистичная блокировка,когда придет первый запрос,Выполнять каждый раз,Чтобы гарантировать, что бизнес может быть выполнен только один раз,Мы должны добавить несколько полей номера версии, чтобы гарантировать, что это действие не будет выполняться повторно.,Это увеличивает сложность кода,очевидно,Использовать блокировкусуществовать Высокий Это не лучшее решение в сценарии параллелизма.
Фактически, чтобы получить этот бизнес-код, выполните его только один раз.очень просто,Нам нужно сделать это только тогда, когда бизнес-запрос отправляется впервые.,установитьполе статусаУказывает, что текущий бизнес-код верен.существоватьосуществлятьсередина,Таким образом, даже если будут отправлены последующие запросы, текущий запрос будет выполнен только один раз.,Но если этот запрос завершится неудачно во время выполнения,Итак, как мы можем гарантировать, что этот запрос может быть успешно выполнен?
Здесь мы можем использовать базу данныхсерединаизТранзакция + вставка таблицы сообщенийрешать,Мы можем создать дополнительную таблицу базы данных в виде таблицы сообщений.,Когда мы выполняем бизнес-код,Для выполнения запроса выполните следующий процесс:
Здесь мы анализируем две ситуации успешного и неудачного выполнения запроса:
Выполнено успешно:Если текущий запрос Выполнено успешно, тогда будет вставлен запрос, содержащий Выполнено. успешноновости,Затем, когда тот же запрос снова отправляется на сервер для выполнения,При вставке сообщения произойдет ошибка.,В это время服务器可以认为当前请求已经Выполнено успешноПонятно,Таким образом, вы можете вернуться напрямую,Гарантирует, что запрос будет успешно выполнен только один раз.
Выполнение не удалось:По запросусуществоватьосуществлять过程середина Происходит сбой,Тогда в силу особенностей транзакции происходит откат и выполняется заново.,до Выполнено До тех пор, пока успех не будет достигнут, это гарантирует идемпотентность запроса.
Таким образом, это решение гарантирует, что запрос может быть выполнен идемпотентно.
но,Главный герой этой статьи — как обеспечить идемпотентность с помощью очередей потребления.,Использование операций транзакций базы данных определенно может удовлетворить,Но если вы не используете реляционную базу данных, такую как MySQL,СкорееRedisЭтот видНет механизма транзакциинереляционная база данных,Или, может быть, мы хотимВыполнение запросов к базам данных,Так как же мы можем обеспечить идемпотентность?
Чтобы удовлетворить идемпотентность в более широком смысле, мы можем использовать очереди сообщений в сочетании с ранее упомянутыми стратегиями для реализации решения, обеспечивающего идемпотентность потребления:
В этом плане,мы все еще используем Понятно上面提到изУстановить статус、Вставить таблицу сообщенийДругие планы,不同из是существовать Здесь мы добавляем ПонятноодинЗадержка потреблениямодуль,существоватьочередь сообщенийсерединатакже можно назватьЗадержка очереди,Задержка очередь может вызывать повторный запрос запросов в очереди время от времени, таким образом гарантируя, что даже если запрос сделан для Выполнения не удалось, также может быть выполнено снова до успешного завершения, обеспечивая тем самым идемпотентность. потребления
Но является ли приведенное выше решение идеальным? Представьте себе экстремальную ситуацию, если во время выполнения запроса произошел даунтайм, запрос был выполнен неудачно или возникла проблема с самим бизнес-кодом, и он дает сбой даже при многократном выполнении, то не приведет ли это к бесконечный цикл?
решатьметодочень просто,мы можем добавитьСтратегия повторной попыткиизбегать Этот вид Состояние,Например, когда начинается потребление,СразуустановитьМаксимальное время выполнения запроса,Если время ожидания истекло, будет возвращена ошибка:
Или добавьтеКоличество повторов(RocketMQПовторная попытка по умолчанию16Второсортный),Таким образом, даже если произойдет ошибка выполнения бизнес-кода, он не попадет в бесконечный цикл.,也Сразурешать Понятно Идемпотентность потребления
При вставке таблицы состояния и выполнении операций в таблицу сообщений нам не обязательно использовать базу данных для завершения операции вставки. Мы можем использовать другие носители данных, такие как Redis, для завершения операции вставки, что также может повысить производительность. .
Хорошо, это все об использовании очередей сообщений для обеспечения идемпотентности потребления. Надеюсь, это будет вам полезно! ! !