Практика распределенных транзакций микросервисов

задняя часть Микросервисы Go
Практика распределенных транзакций микросервисов

задний план

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

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

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

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

Go-zero и dtm объединили свои усилия для запуска минималистского решения для беспрепятственного доступа к dtm в go-zero, что делает использование распределенных транзакций проще, чем когда-либо.

запустить пример

Давайте посмотрим на исполняемый пример, а затем посмотрим, как самостоятельно разработать полную распределенную транзакцию.

Далее в качестве центра регистрации используется etcd.Вы можете запустить пример go-zero следующим образом:

  • настроить дтм
MicroService:
    Driver: 'dtm-driver-gozero' # 配置dtm使用go-zero的微服务协议
    Target: 'etcd://localhost:2379/dtmservice' # 把dtm注册到etcd的这个地址
    EndPoint: 'localhost:36790' # dtm的本地地址
  • начать и т. д.
# 前提:已安装etcd
etcd
  • начать дтм
# 前提:已配置好dtm的数据库链接
go run app/main.go dev
  • Запуск службы с нуля
git clone github.com/yedf/dtmdriver-clients && cd dtmdriver-clients
cd gozero/trans && go run trans.go
  • Инициировать транзакцию dtm с помощью go-zero
# 在dtmdriver-clients的目录下
cd gozero/app && go run main.go

Когда видишь в логах транс

2021/12/03 15:44:05 transfer out 30 cents from 1
2021/12/03 15:44:05 transfer in 30 cents to 2
2021/12/03 15:44:05 transfer out 30 cents from 1
2021/12/03 15:44:05 transfer out 30 cents from 1

Это означает, что транзакция завершена нормально

доступ к развитию

Ссылаться наyedf/dtmdriver-clientsкод

// 下面这行导入gozero的dtm驱动
import _ "github.com/yedf/dtmdriver-gozero"

// 使用dtm的客户端dtmgrpc之前,需要执行下面这行调用,告知dtmgrpc使用gozero的驱动来如何处理gozero的url
err := dtmdriver.Use("dtm-driver-gozero")
// check err

// dtm已经通过前面的配置,注册到下面这个地址,因此在dtmgrpc中使用该地址
var dtmServer = "etcd://localhost:2379/dtmservice"

// 下面从配置文件中Load配置,然后通过BuildTarget获得业务服务的地址
var c zrpc.RpcClientConf
conf.MustLoad(*configFile, &c)
busiServer, err := c.BuildTarget()

  // 使用dtmgrpc生成一个消息型分布式事务并提交
	gid := dtmgrpc.MustGenGid(dtmServer)
	msg := dtmgrpc.NewMsgGrpc(dtmServer, gid).
    // 事务的第一步为调用trans.TransSvcClient.TransOut
    // 可以从trans.pb.go中找到上述方法对应的Method名称为"/trans.TransSvc/TransOut"
    // dtm需要从dtm服务器调用该方法,所以不走强类型,而是走动态的url: busiServer+"/trans.TransSvc/TransOut"
		Add(busiServer+"/trans.TransSvc/TransOut", &busi.BusiReq{Amount: 30, UserId: 1}).
		Add(busiServer+"/trans.TransSvc/TransIn", &busi.BusiReq{Amount: 30, UserId: 2})
	err := msg.Submit()

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

Меры предосторожности

В процессе разработки доступа найдите*.pb.goв файлеgrpcПри доступе к пути метода обязательно найдитеinvokeмаршрут

Глубокое понимание динамического вызова

Когда go-zero использует распределенные транзакции dtm, многие вызовы инициируются с серверов dtm, таких как TCC.Confirm/Cancel,SAGA/MSGвсех звонков.

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

Вызов grpc может быть аналогичен HTTP POST, где:

  • c.BuildTarget()Произведенная цель аналогична хосту в URL-адресе.
  • /trans.TransSvc/TransOutЭквивалентно пути URL
  • &busi.BusiReq{Amount: 30, UserId: 1}Эквивалент всплывающих окон в POST
  • pb.ResponseОтвет эквивалентен HTTP-запросу

Через следующую часть кода dtm получает полную информацию и может инициировать полный вызов.

Add(busiServer+"/trans.TransSvc/TransOut", &busi.BusiReq{Amount: 30, UserId: 1})

более полный пример

Восторженные одноклассники сообществаMikaelПомог написать более богатый пример в сочетании с практическими приложениями и барьерами для подтранзакций, полной демонстрацией распределенной транзакции, фактически работающей в Интернете, заинтересованные студенты могут обратиться к:

GitHub.com/Мика очень голоден…

Доступ другими способами

микросервисы go-zero также имеют не-etcdдругими способами, мы объясним их методы доступа в свою очередь

прямая связь

Для прямого подключения таким образом вам просто нужно вышеdtmизetcdИсходя из конфигурации,TargetПросто установите его в пустую строку.

В случае прямого подключения нет необходимостиdtmЗарегистрируйтесь в реестре.

K8S

заK8SТаким образом, вам нужно только вершинуdtmизetcdИсходя из конфигурации,TargetПросто установите его в пустую строку.

существуетK8S, зарегистрируйте службу с помощьюK8S, отdeployment.yamlЗавершено внутри приложения, регистрация не требуется.

Предварительный просмотр живого обмена

Автор go-zero и я (автор dtm) будем в 21:00 22 декабря по адресуGo 夜读, совместная трансляция в прямом эфире «практики распределенных транзакций go-zero», которая приведет к все более и более углубленным обсуждениям. Все приглашаются к участию.

Живой адрес:live.bilibili.com/11171965

резюме

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

Добро пожаловать в использованиеgo-zeroиdtmИспользуя наш роднойМикросервисное решение для распределенных транзакцийstarПоддерживать нас!

Группа обмена WeChat

обрати внимание на"Практика микросервисов』Общедоступный номер и нажмитегруппа обменаПолучите QR-код группы сообщества.