6 решений для возможной согласованности распределенных транзакций, объясненных сразу
6 решений для возможной согласованности распределенных транзакций, объясненных сразу

представлять

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

В разных бизнес-сценариях решения будут разными. Общие методы:

  • блокировка повторной попытки;
  • 2шт, 3шт традиционные дела;
  • Используйте очереди и фоновую асинхронную обработку;
  • Компенсация TCC имеет значение;
  • таблица локальных сообщений(Асинхронное обеспечение);
  • MQ дела。

В этой статье основное внимание уделяется нескольким другим вопросам. В Интернете уже есть много информации о традиционных делах 2PC и 3PC, поэтому я не буду их здесь повторять.

2

блокировка повторной попытки

В существующей микро-служебной архитектуре более распространенным способом является блокировка повторной попытки.

Пример псевдокода:

Язык кода:javascript
копировать
m := db.Insert(sql)

err := request(B-Service,m)

func request(url string,body interface{}){
  for i:=0; i<3; i ++ {
    result, err = request.POST(url,body)
    if err == nil {
        break 
    } else {
      log.Print()
    }
  }
}

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

Такой подход приведет к следующим проблемам:

  • вызов B Служба выполнена успешно, но из-за тайм-аута сети текущая служба считает, что произошел сбой, и продолжает попытки снова, поэтому B сервис будет генерировать 2 такой жеизданные。
  • вызов B Служба не удалась из-за B Сервис недоступен, попробуйте еще раз 3 По-прежнему каждый раз происходит сбой. Текущий код «Служитьсуществовать» вставляется в предыдущий код. DB из Одна запись становится грязными данными.
  • Повторная попытка увеличит задержку восходящего канала для этого сеанса.,Если нисходящая нагрузка велика,Повторные попытки усиливают давление ниже по течению.

Первая проблема: решена за счет поддержки идемпотентности API сервиса B.

Второй вопрос: вы можете исправить данные с помощью фоновых шагов синхронизации, но это не очень хороший метод.

Третий вопрос: это необходимая жертва ради улучшения согласованности, доступности и улучшения согласованности.

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

3

асинхронная очередь

В процессе развития решений введение очередей является распространенным и лучшим способом. Пример:

Язык кода:javascript
копировать
m := db.Insert(sql)

err := mq.Publish("B-Service-topic",m)

Записать данные в текущий сервис DB После этого отправьте сообщение на MQ, потребляемый независимыми сервисами MQ Обрабатывать бизнес-логику. иблокировка повторной По сравнению с попыткой, хотя MQ Стабильность гораздо выше, чем у обычных бизнес-сервисов, но при отправке сообщений на MQ Все еще существуют возможности сбоя, такие как проблемы с сетью, текущий простой и т. д. Таким образом вы все равно столкнетесь с блокировкой повторной попытка такая же, как и из проблемы, т.е. DB Запись прошла успешно, но отправка не удалась.

Теоретически, в распределенной системе такая ситуация возникнет в коде, включающем несколько вызовов служб. При длительной работе обязательно возникнут сбои вызовов. Это также одна из трудностей проектирования распределенных систем. Кроме того, ищите учеников по ИТ-коду в общедоступных учетных записях в WeChat, отправляйте информацию в фоновом режиме и получайте видеоуроки объемом 2000 ГБ и новейшие упражнения для собеседований.

4

Компенсация TCC имеет значение

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

TCC делит вызов каждой услуги на 2 этапа и 3 операции:

  • Шаг 1. Попробуйте Операция: обнаружение бизнес-ресурсов、Резервирование ресурсов, например инвентаризация、Удержание.
  • Этап 2, Подтверждение Действие: Отправить подтверждение Попробуйте выполнить операцию резервирования ресурсов. Например, обновите удержание запасов на вычет.
  • Этап 2, Отмена Операция: Попробуйте После операции неудача,Освободите его удерживающие ресурсы. Например, добавьте обратно удержание запасов.

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

Например, приложению торгового центра необходимо вызвать службу инвентаризации A, службу суммы B и службу точек C, как показано в следующем псевдокоде:

Язык кода:javascript
копировать
m := db.Insert(sql)
aResult, aErr := A.Try(m)
bResult, bErr := B.Try(m)
cResult, cErr := C.Try(m)
if cErr != nil {
    A.Cancel()
    B.Cancel()
 C.Cancel()
} else {
    A.Confirm()
    B.Confirm()
    C.Confirm()
}

В коде API-интерфейсы служб A, B и C вызываются соответственно для проверки и резервирования ресурсов. Если все они возвращаются успешно, отправляется операция подтверждения (Confirm). Если операция Try службы C завершается неудачно, API-интерфейсы отмены; из A, B и C вызываются соответственно для освобождения своих резервирований.

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

пустой выпуск

Если вызов C.Try() в приведенном выше коде действительно завершится неудачно, избыточный вызов C.Cancel() ниже освободит ресурс, не блокируя его. Это связано с тем, что текущая служба не может определить, действительно ли неудачный вызов заблокировал ресурс C. Если вы не вызовете его, он действительно завершится успешно, но возврат не удастся по сетевым причинам. Это приведет к тому, что ресурс C будет заблокирован и никогда не будет освобожден.

пустой часто появляется выпусксуществовать в производственной среде, Служитьсуществовать реализацию TCC дела API пустой должен поддерживаться, когда выпущен осуществлять。

Тайминг

В приведенном выше коде, если C.Try() Если не получится, позвоните C.Cancel() действовать. По сетевым причинам могут быть C.Cancel() Запросы на первом месте C Сервис, C.Try() После поступления запроса это приведет к пустой проблема с выпуском, вызванная одновременно C Ресурсы заблокированы и никогда не освобождаются.

так C Служба должна отказаться освобождать ресурс после Try() действовать. С точки зрения конкретной реализации, уникальный идентификатор дела можно использовать для различения с первого раза. Try() Или после релиза? Try()。

Не удалось позвонить

Во время процесса вызова «Отмена» и «Подтверждение» по-прежнему будут возникать сбои, например, по обычным сетевым причинам.

Сбой операции Cancel() или Confirm() приведет к тому, что ресурс будет заблокирован и никогда не будет освобожден. Общие решения этой ситуации включают в себя:

  • блокировка повторной попытки. Но у него также есть проблемы, такие как простои、Всегданеудачаиз Состояние。
  • Запись в журнал и в очередь,Тогда вам придется самостоятельно выполнять асинхронную обработку автоматически или вручную. Но проблемы все равно будут,При написании логов и очередей,Будет существоватьсуществоватьнеудачаиз Состояние。

Теоретически, неатомарные свойства и свойства дела — это два фрагмента кода.,Будет промежуточное состояние существования,иметь Промежуточное состояние будетиметьнеудачаизвозможность。

5

таблица локальных сообщений

таблица локальных сообщений Первоначально это было ebay рейз из, это делает таблицу локальных Таблицы сообщений и бизнес-данных находятся в одной индивидуальной базе данных, так что местные дела могут быть использованы для соответствия характеристикам дел.

Конкретный метод заключается в вставке бизнес-данных в местные дела.,Также вставьте данные сообщения. Затем существуют последующие операции,Если другие операции успешны,затем удалить сообщение, если оно неудачное, то не удалять;,Асинхронно прослушать это индивидуальное сообщение,Продолжайте пытаться еще раз.

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

Сотрудничать с МК

Пример псевдокода:

Язык кода:javascript
копировать
messageTx := tc.NewTransaction("order")
messageTxSql := tx.TryPlan("content")

m,err := db.InsertTx(sql,messageTxSql)
if err!=nil {
 return err
}

aErr := mq.Publish("B-Service-topic",m)
if aErr!=nil { // подтолкнуть к MQ неудача
 messageTx.Confirm() // Обновить сообщение о статусе confirm
} else {
 messageTx.Cancel() // Удалить сообщение
}

// Асинхронная обработка confirm изMessage, продолжайте нажимать
func OnMessage(task *Task){
   err := mq.Publish("B-Service-topic", task.Value())
   if err==nil {
     messageTx.Cancel()
   }
}

Код выше содержит messageTxSql это таблица вставки локальных сообщенийизабзац SQL :

Язык кода:javascript
копировать
insert into `tcc_async_task` (`uid`,`name`,`value`,`status`)
values ('?','?','?','?')

это и бизнес SQL существоватьтакой жеиндивидуальныйдела Входитьосуществлять,Либо добиться успеха,Илинеудача。

В случае успеха он будет помещен в очередь. Если отправка успешна, он будет вызван. messageTx.Cancel() Удалите локальное сообщение; если отправка не удалась, пометьте сообщение как confirm。таблица локальных сообщенийсередина status иметь 2 состояние try、confirm, Независимо от того, гдесостояниесуществовать OnMessage можно отслеживать и инициировать повторную попытку.

Локальные дела гарантируют, что сообщения и услуги будут записаны в базу данных,этотназадизосуществлять Независимо от времени простоядасетевой толчокнеудача,Асинхронное прослушивание можно обработать позже,Это гарантирует, что сообщение будет отправлено в MQ.

и MQ Тогда гарантия обязательно дойдет до сервисной службы, воспользовавшись MQ из QOS Стратегия,Потребители Служить обязательно с этим справятся,или продолжает доставляться в следующую индивидуальную бизнес-очередь,Целостность дел гарантируется со стороны и.

Сотрудничать с сервисными вызовами

Пример псевдокода:

Язык кода:javascript
копировать
messageTx := tc.NewTransaction("order")
messageTxSql := tx.TryPlan("content")

body,err := db.InsertTx(sql,messageTxSql)
if err!=nil {
    return err
}

aErr := request.POST("B-Service",body)
if aErr!=nil { // вызов B-Service неудача
 messageTx.Confirm() // Обновить сообщение о статусе confirm
} else {
 messageTx.Cancel() // Удалить сообщение
}
Язык кода:javascript
копировать
// Асинхронная обработка confirm или try изMessage, продолжить вызов B-Service
func OnMessage(task *Task){
  // request.POST("B-Service",body)
}

Это таблица локальных сообщений + вызовдругой Служитьизпример,безиметь MQ из Введено. При этом используются асинхронные повторы и таблица. локальных сообщений гарантирует надежность сообщения и решает проблему блокировки повторной забота приносит проблемы,существование относительно распространено в повседневном развитии. кроме того,WeChat ищет публичную учетную запись ученика ИТ-кода,существуют Backend отправка: информация,Получите 2000 ГБ видеоуроков и новейшие упражнения для собеседований.

Если локально нет, напишите DB вне работы, вы можете просто написать таблицу локальных сообщений,такой жесуществовать Обработано в OnMessage:

Язык кода:javascript
копировать
messageTx := tc.NewTransaction("order")
messageTx := tx.Try("content")
aErr := request.POST("B-Service",body)
// ....

Срок действия сообщения истекает

Конфигурациятаблица локальных сообщенийиз Try и Confirm информацияизпроцессор:

Язык кода:javascript
копировать
TCC.SetTryHandler(OnTryMessage())
TCC.SetConfirmHandler(OnConfirmMessage())

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

Язык кода:javascript
копировать
func OnConfirmMessage(task *tcc.Task) {
if time.Now().Sub(task.CreatedAt) > time.Hour {
    err := task.Cancel() // Удалите сообщение и прекратите повторные попытки.
   // doSomeThing() Сигнализация, ручное вмешательство
    return
 }
}

существовать Try В функции обработки также необходимо отдельно определить, не существует ли слишком короткое хранилище текущей задачи сообщения, поскольку Tryсостояниеизинформация,Вероятно, только что созданный,Отправка еще не подтверждена. Это повторит обычное выполнение бизнес-логики.,означает успех извызов,также будет повторена попытка избежать этой ситуации;,Может определить, очень ли короткое время создания сообщения,Короткие слова можно пропустить.

Механизм повтора должен полагаться на нижестоящие API существоватьбизнес-логикаиз Идемпотентность,Хотя можно и без обработки,Тем не менее, дизайн все равно должен стараться не мешать обычным запросам.

независимая служба обмена сообщениями

независимая служба обмена сообщениямидатаблица локальных сообщенийиз Обновил версию, поставил таблицу локальных сообщенийразделить на одининдивидуальныйнезависимыйиз Служить。Местоиметьдействоватьдосуществоватьинформация Служитьдобавить виндивидуальныйинформация,назад Продолжениедействоватьуспехно Удалить сообщение,неудачано Отправить подтверждениеинформация。

Затем используйте асинхронную логику для прослушивания сообщений.,Сделайте соответствующую обработку,Логика обработки итаблицы локальных сообщений в основном такая же. Но так как добавление сообщения в сообщение Служить,Невозможно поместить локальную операцию в файл,так сохранит существование сообщение успешно добавлено,назад Продолжениенеудача,Тогда из сообщения на данный момент это индивидуальная бесполезная новость.

Следующий пример сценария:

Язык кода:javascript
копировать
err := request.POST("Message-Service",body)
if err!=nil {
  return err
}

aErr := request.POST("B-Service",body)
if aErr!=nil {
  return aErr
}

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

6

MQ дела

иметьнекоторый MQ из реализации поддерживает такие дела, как RocketMQ 。MQ издела можно прочитать как независимая служба обмена сообщениямииз Специальная реализация с полностью последовательной логикой.

Местоиметьдействоватьдосуществовать MQ Отправьте сообщение и последующие операции пройдут успешно. Confirm Подтвердите сообщение об отправке и нажмите «Отмена»,чтобы удалить сообщение в случае неудачи. МК делатакже Будет существоватьсуществовать подготовить статус, требуется MQ Логика обработки потребления для подтверждения успешности бизнеса.

7

Подвести итог

С точки зрения практики распределенных систем,Сценарии для обеспечения согласованности данных,Необходимо внедрить дополнительные механизмы обработки.

TCC Преимущество из заключается в том, что он действует на бизнес-уровне, не полагается на конкретного человека, не связан с конкретной структурой, а степень детализации блокировки ресурсов является относительно гибкой, что делает его очень подходящим для сценариев микро-обслуживания. Недостаток в том, что каждый индивидуальный Служить должен быть реализован. 3 индивидуальный API,Для делового вмешательства и больших перемен,иметь дело с различныминеудачааномальный。Разработчикам сложно полностью справиться с различными Состояние,Поиск зрелого человека из рамок может значительно снизить стоимость,Например Али из Фескара.

таблица локальных Преимущество сообщений в том, что они просты, не зависят от других модификаций Служитьиз и могут быть очень хороши в Сотрудничать. с сервисными вызовамии MQ используются вместе,существование более практично в большинстве бизнес-сценариев. Недостатком является то, что в локальной базе данных больше таблиц сообщений.,и Бизнес-столы, спаренные существуют вместе.

в текстетаблица локальных Метод сообщений из примера из индивидуальной библиотеки автора, заинтересованные студенты могут обратиться к следующим https://github.com/mushroomsir/tcc

MQ делаинезависимая служба обмена Преимущество сообщений состоит в том, чтобы извлечь одну индивидуальную публикацию из Служить, чтобы решить деловую проблему и избежать каждого отдельного человека. альный Служить иметь таблицу сообщений, а Служить в сочетании существуют вместе, увеличивая саму Служить из-за сложности обработки. Недостаток в том, что он поддерживает делаиз. MQ Редко и звонил перед каждой операцией; API добавить виндивидуальныйинформация,Увеличит общую задержку вызовов.,существует Подавляющее большинство нормальных ответов из бизнес-сценариев,Это своего рода лишние расходы.

boy illustration
Углубленный анализ переполнения памяти CUDA: OutOfMemoryError: CUDA не хватает памяти. Попыталась выделить 3,21 Ги Б (GPU 0; всего 8,00 Ги Б).
boy illustration
[Решено] ошибка установки conda. Среда решения: не удалось выполнить первоначальное зависание. Повторная попытка с помощью файла (графическое руководство).
boy illustration
Прочитайте нейросетевую модель Трансформера в одной статье
boy illustration
.ART Теплые зимние предложения уже открыты
boy illustration
Сравнительная таблица описания кодов ошибок Amap
boy illustration
Уведомление о последних правилах Points Mall в декабре 2022 года.
boy illustration
Даже новички могут быстро приступить к работе с легким сервером приложений.
boy illustration
Взгляд на RSAC 2024|Защита конфиденциальности в эпоху больших моделей
boy illustration
Вы используете ИИ каждый день и до сих пор не знаете, как ИИ дает обратную связь? Одна статья для понимания реализации в коде Python общих функций потерь генеративных моделей + анализ принципов расчета.
boy illustration
Используйте (внутренний) почтовый ящик для образовательных учреждений, чтобы использовать Microsoft Family Bucket (1T дискового пространства на одном диске и версию Office 365 для образовательных учреждений)
boy illustration
Руководство по началу работы с оперативным проектом (7) Практическое сочетание оперативного письма — оперативного письма на основе интеллектуальной системы вопросов и ответов службы поддержки клиентов
boy illustration
[docker] Версия сервера «Чтение 3» — создайте свою собственную программу чтения веб-текста
boy illustration
Обзор Cloud-init и этапы создания в рамках PVE
boy illustration
Корпоративные пользователи используют пакет регистрационных ресурсов для регистрации ICP для веб-сайта и активации оплаты WeChat H5 (с кодом платежного узла версии API V3)
boy illustration
Подробное объяснение таких показателей производительности с высоким уровнем параллелизма, как QPS, TPS, RT и пропускная способность.
boy illustration
Удачи в конкурсе Python Essay Challenge, станьте первым, кто испытает новую функцию сообщества [Запускать блоки кода онлайн] и выиграйте множество изысканных подарков!
boy illustration
[Техническая посадка травы] Кровавая рвота и отделка позволяют вам необычным образом ощипывать гусиные перья! Не распространяйте информацию! ! !
boy illustration
[Официальное ограниченное по времени мероприятие] Сейчас ноябрь, напишите и получите приз
boy illustration
Прочтите это в одной статье: Учебник для няни по созданию сервера Huanshou Parlu на базе CVM-сервера.
boy illustration
Cloud Native | Что такое CRD (настраиваемые определения ресурсов) в K8s?
boy illustration
Как использовать Cloudflare CDN для настройки узла (CF самостоятельно выбирает IP) Гонконг, Китай/Азия узел/сводка и рекомендации внутреннего высокоскоростного IP-сегмента
boy illustration
Дополнительные правила вознаграждения амбассадоров акции в марте 2023 г.
boy illustration
Можно ли открыть частный сервер Phantom Beast Palu одним щелчком мыши? Супер простой урок для начинающих! (Прилагается метод обновления сервера)
boy illustration
[Играйте с Phantom Beast Palu] Обновите игровой сервер Phantom Beast Pallu одним щелчком мыши
boy illustration
Maotouhu делится: последний доступный внутри страны адрес склада исходного образа Docker 2024 года (обновлено 1 декабря)
boy illustration
Кодирование Base64 в MultipartFile
boy illustration
5 точек расширения SpringBoot, супер практично!
boy illustration
Глубокое понимание сопоставления индексов Elasticsearch.
boy illustration
15 рекомендуемых платформ разработки с нулевым кодом корпоративного уровня. Всегда найдется та, которая вам понравится.
boy illustration
Аннотация EasyExcel позволяет экспортировать с сохранением двух десятичных знаков.