Как распределенная транзакция обеспечивает упорядоченность запросов интерфейса?

Java задняя часть
Как распределенная транзакция обеспечивает упорядоченность запросов интерфейса?

Эта статья участвовала в "Проект «Звезда раскопок»”, чтобы выиграть творческий подарочный пакет и бросить вызов творческим поощрительным деньгам.

предисловие

Давайте сначала подумаем об этом: как в распределенной системе обеспечить упорядоченность нескольких запросов? Например, есть две системы, A/B. Система A отправляет три запроса в систему B в рамках одной бизнес-обработки заказа. Сначала вставьте операции заказа, затем изменить статус заказа и, наконец, увеличить очки пользователя.

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

image.png

Итак, как нам избежать этой ситуации, нам нужно понять, что сказал сегодня брат Хуа:Как обеспечить упорядоченность запросов в распределенных сервисах.

Добавить услугу доступа

Мы можем добавить службу доступа между системами A и B. Например, в приведенном выше сценарии полный бизнес содержит три запроса. В каждом запросе уникальный идентификатор передается в качестве идентификатора службе доступа. Служба доступа распределяет все соответствующие запросы к определенной машине в соответствии с идентификатором, чтобы все три запроса могли быть выполнены одной и той же службой.

image.png

добавить очередь

После добавления [Службы доступа] запросы с одним и тем же id можно будет раздавать на одну и ту же машину.Пока система А отправляет последовательно, система Б тоже будет последовательно получать, но все равно будет проблема, т.е. система B многопоточная. При обработке полученного запроса таким же образом все равно будет проблема порядка потребления.

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

image.png

Распределенные блокировки гарантируют последовательность

В целом вышеперечисленные два шага в основном соответствуют нашим бизнес-потребностям, но на самом деле все же бывают крайние случаи, приводящие к последовательным проблемам, например, в процессе распределения услуги доступа заказ аномально распределяется на систему Б. Для некоторых систем, требующих 100% гарантии порядка интерфейса, мы можем добиться этого путем доступа к распределенным блокировкам.

image.png

Как показано на рисунке выше, теперь все три запроса поступили в систему B. Помимо уникального id, каждый запрос также несет в себе порядковый номер ord этого запроса, и перед тем, как каждый запрос выполнит бизнес-логику, он будет запрашивать у zookeeper lock.Выполняться может только поток, получивший блокировку:

  • Если запрос на удаление сначала получает блокировку, перед выполнением бизнес-логики он обращается к базе данных, чтобы определить, были ли завершены новый запрос и запрос на изменение, и если нет, то блокировка будет снята;
  • Затем новый запрос получает блокировку.Он решает, что порядок выполнения текущего запроса ord=1 и может быть выполнен, поэтому он вставит данные в базу данных и снимет блокировку;
  • Затем, если запрос на удаление получает блокировку, он все равно обращается к базе данных для запроса и обнаруживает, что запрос на изменение не завершил операцию, поэтому он продолжает освобождать текущие ресурсы блокировки;
  • Запрос модификации получает блокировку и обнаруживает, что запись уже существует в базе данных, поэтому статус заказа изменяется и блокировка снимается;
  • Запрос на удаление получает блокировку, завершает операцию удаления и, наконец, освобождает блокировку.

дефект

С помощью трех вышеуказанных шагов можно добиться 100% последовательности потребления, но после этой операции пропускная способность системы серьезно снижается, особенно введение распределенных блокировок, которые стали узким местом параллелизма системы.

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