Projeto e implementação do Seata-go TCC

Autor: Liu Yuecai

Este artigo apresenta principalmente a ideia de design, o tratamento de exceções e o uso real do TCC no Seata-Go.

Seata é uma solução de transação distribuída de código aberto, dedicada a fornecer serviços de transação distribuída de alto desempenho e fáceis de usar para transações distribuídas sob a arquitetura moderna de microsserviços. A Seata fornecerá aos usuários vários modos de transação, como AT, TCC, SAGA e XA, para ajudar os usuários a resolver problemas de negócios em diferentes cenários. Ao mesmo tempo, o Seata também suporta programação em vários idiomas e fornece uma interface de API simples, documentação rica e exemplos de projetos de amostra de início rápido, que também podem ajudar os desenvolvedores a começar e usar o Seata.

O Seata-go é a implementação da linguagem golang no ecossistema multilíngue da Seata, dedicado a ajudar os desenvolvedores golang a usar os recursos da Seata para resolver cenários de transações distribuídas. O Seata-go reutiliza os recursos do Seata TC e as funções do cliente são consistentes com o Seata. Atualmente, o Seata-go tem suporte para os modos TCC e AT, o modo XA está sendo testado e deve ser lançado em maio. O modo Saga está sendo projetado e planejado e será consistente com a função Saga da Seata no futuro.

Este artigo apresenta principalmente o design e o uso do modo TCC no Seata-go a partir das seguintes perspectivas:

  • Princípio de implementação do Seata-go TCC
  • Manipulação de exceção Sata-go TCC
  • Outlook para Seata-go

Princípio de implementação do Seata-go TCC

Seata-go usa getty para comunicação de rede TCP e implementa totalmente o protocolo de comunicação Seata. A camada inferior implementa o centro de configuração e o centro de registro e também suporta o acesso de muitos frameworks de terceiros, como dubbo, grpc, gorm, etc., e está se comunicando ativamente com várias comunidades para dar suporte ao acesso de mais frameworks. O diagrama de arquitetura do sistema simples do Seata-go é o seguinte:

imagem.png

Primeiro, vamos revisar brevemente o significado do modo TCC. TCC é uma implementação de um esquema de transação distribuída. Ele adota um protocolo de confirmação de duas fases. O nome completo do TCC é Try-Confirm-Cancel. Try é uma operação de recurso reservado, Confirm é uma operação de confirmação e Cancel é uma operação de reversão . Na primeira fase do TCC, todas as sub-transações são acionadas primeiro para executar a operação Try. Se a primeira fase de todas as sub-transações for executada com sucesso, então a segunda fase de todas as sub-transações é acionada para executar a operação Confirm, caso contrário, a segunda fase executa a operação Cancelar, para garantir a consistência de cada estado da subtransação.

O TCC é um esquema intrusivo de transações distribuídas, cuja lógica dos três estágios de Tentar, Confirmar e Cancelar precisa ser implementada pelo usuário. Fazer isso significa mais código e é muito intrusivo para os negócios; a vantagem é que é mais flexível e pode ser usado pelos usuários para resolver cenários de transações distribuídas mais complexos.

Antes de apresentar o modo TCC do Seata-go, vamos revisar as três funções principais do Seata, ou seja, TC, TM e RM . TC é o coordenador da transação, responsável por manter o estado da transação global e disparar o commit e rollback das transações da filial; TM é o gerenciador da transação, responsável pelo arranjo das subtransações e pelo commit e rollback das transações globais; RM é um servidor de gerenciamento de recursos, gerencia recursos para processamento de transações de filiais, como a operação do banco de dados MySQL, etc.

Depois de entender essas três funções principais, você pode entender aproximadamente o processo de transação do TCC, que pode ser dividido nas seguintes etapas:

  • O TM envia uma solicitação ao TC para iniciar a transação global e o lado do TC registra as informações de status da transação global;
  • TM envia requisições para todos os RMs respectivamente, e RM irá registrar transações de ramificação com TC, e então executar a lógica da fase Try;
  • Se um dos RMs retornar ao TM que a execução da fase Try falhou, o TM enviará uma solicitação de "rollback global transaction" ao TC. Após o TC recebê-lo, ele enviará um comando Rollback para todos os RMs que executaram o Try, acionando o RM para executar a lógica Cancel;
  • Se todos os RMs retornarem ao TM que a execução da fase Try foi bem-sucedida, o TM enviará uma solicitação de "commit global transaction" ao TC. Após o TC recebê-lo, ele enviará um comando Commit para todos os RMs que executaram o Try, acionando o RM para executar a lógica Commit.

Até agora, uma transação distribuída completa foi executada. A seguir está o fluxograma deste processo:

imagem

No Seata-go, para comodidade dos usuários, são disponibilizados dois métodos de definição dos serviços TCC, um deles é a implementação da interface TwoPhaseInterface, conforme segue:

imagem.png

A outra é definir o serviço TCC por tag, que é relativamente complicado mas mais flexível:

imagem.png

A segunda solução de tag é principalmente para atender alguns cenários especiais, por exemplo, o servidor e o cliente do dubbo-go são definidos por tags, neste momento é necessário usar tags para definir os serviços TCC. Em geral, é recomendável usar o primeiro método de herança da interface, que é relativamente simples.

No uso real, os usuários só precisam fazer o seguinte:

  • Para definir o seu próprio serviço de TCC, pode recorrer a um dos dois métodos descritos acima;
  • Chame o método proxy NewTCCServiceProxy do TCC para encapsular o serviço TCC em um proxy;
  • Organize suas próprias subtransações e passe-as para o método de entrada WithGlobalTx da transação distribuída.

Aqui está uma captura de tela para mostrar um exemplo. Para amostras mais detalhadas, consulte o projeto seata-go-samples no endereço: https://github.com/seata/seata-go-samples

imagem.png

Tratamento de exceções Seata-go TCC

Ao utilizar de fato o TCC, devido a fatores como o tempo de execução da lógica da rede ou do código de negócio, podem ocorrer os seguintes problemas:

  • Idempotência: Na primeira e segunda fases da transação, devido a atraso na rede ou outros motivos, RM não respondeu a TC ou TM a tempo, resultando em RM sendo repetidamente acionado para executar a lógica da primeira e segunda fases. tempo, a idempotência do negócio precisa ser considerada;
  • Reversão vazia: devido a atraso de rede ou outros motivos, RM recebeu uma solicitação de reversão sem receber uma solicitação Try, resultando em um problema de reversão vazia;
  • Pendurado: devido ao atraso da rede ou outros motivos, RM recebeu uma solicitação de reversão sem receber uma solicitação Try e recebeu uma solicitação Try após processar a solicitação Rollback. Neste momento, a transação global foi finalizada, o que fará com que os recursos reservados pela transação não possam ser liberados.

No Seata-go, duas soluções são fornecidas para ajudar os usuários a resolver esse problema.

O princípio do primeiro método é o mesmo da lógica de processamento do Seata Java, que é feito com a ajuda da tabela de status da transação tcc_fence_log:

imagem.png

Os usuários precisam criar esta tabela em seu próprio banco de dados de negócios. Quando o RM envia o SQL de negócios, ele insere um registro nessa tabela ao mesmo tempo. Esses dois SQLs são concluídos em uma transação local. Como o "ID da transação global + ID da transação da filial" nesta tabela é uma chave primária conjunta, ela falhará quando for executada repetidamente, resolvendo assim o problema de idempotência da fase Try. Nas etapas de Confirmação e Cancelamento, primeiro será consultado o status da transação de ramificação nesta tabela, depois a lógica real será executada e o status será atualizado por último. Isso também garante a idempotência das fases Commit e Cancel.

Vamos dar uma olhada em como o Seata-go resolve os problemas de suspensão de transações e reversão vazia. Se vier uma solicitação de Rollbback, o RM verifica a tabela tcc_fence_log e descobre que não há registro (porque o RM não recebeu a solicitação Try), neste momento, ele inserirá um registro na tabela tcc_fence_log, marcará o status como suspenso e em seguida, saia diretamente sem executar a lógica de reversão, evitando assim o problema de reversão vazia. Se o RM receber uma requisição Try posteriormente, pois já existe um registro na tabela tcc_fence_log, a transação SQL não pode ser submetida e falha (tcc_fence_log terá um problema de conflito de chave primária), evitando assim o problema de anti-hanging.

Para alcançar este método, você precisa usar a fonte de dados proxy fornecida pelo Seata-go. Essas operações serão concluídas pela fonte de dados proxy. Os usuários só precisam ligar o switch e prestar atenção ao seu próprio SQL de negócios. Esta função tem foi realizado e será executado posteriormente Versão da edição.

O segundo método é realizado manualmente pelo usuário. O princípio é semelhante ao acima, mas a lógica de operação de tcc_fence_log precisa ser implementada pelo usuário. A captura de tela abaixo descreve o método de uso geral. Para obter detalhes, consulte o código de amostra:

https://github.com/seata/seata-go-samples/tree/main/tcc/fence

imagem

Seata-go Outlook

A comunidade Seata-go alcançou recentemente a cooperação com muitos frameworks de microsserviços de linguagem go domésticos e comunidades de desenvolvimento por trás do framework ORM. Por exemplo, o framework GORM foi integrado ao Sample, e mais frameworks ORM serão integrados ao Seata-go-Samples projeto no futuro. meio. A cooperação com a comunidade MOSN também está avançando para realizar uma verdadeira malha de transação baseada em Seata.

O modo XA do Seata-go será lançado em maio, e o Seata-go suportará os modos de transação TCC, XA e AT. O centro de acompanhamento do Seata-go será o desenvolvimento das funções do modo Saga.

O modo Saga atual realiza apenas os recursos de reversão direta e reversa da orquestração de serviço, e a orquestração de serviço adicional pode realizar DAG, tarefas cronometradas e agendamento de tarefas em lote, abrangendo todos os processos de fluxo de trabalho e melhorando a experiência do usuário na plataforma Seata. Atualmente o Seata-go depende do TC do Seata Java, de acordo com este plano de trabalho, pode ser necessário implementar um agendamento de TC mais potente em uma versão futura do Seata-go.

A comunidade Seata-go está crescendo rapidamente. Esperamos que mais amigos interessados ​​em código aberto se juntem à nossa comunidade e ajudem Seata-go a crescer juntos!

{{o.name}}
{{m.name}}

Acho que você gosta

Origin my.oschina.net/u/3874284/blog/8863949
Recomendado
Clasificación