Conception et mise en œuvre de Seata-go TCC

Auteur : Liu Yuecai

Cet article présente principalement l'idée de conception, la gestion des exceptions et l'utilisation réelle de TCC dans seata-go.

Seata est une solution de transaction distribuée open source, dédiée à la fourniture de services de transaction distribuée hautes performances et faciles à utiliser pour les transactions distribuées dans le cadre de l'architecture microservice moderne. Seata fournira aux utilisateurs divers modes de transaction tels que AT, TCC, SAGA et XA pour aider les utilisateurs à résoudre les problèmes commerciaux dans différents scénarios. Dans le même temps, Seata prend également en charge la programmation multilingue et fournit une interface API simple, une documentation riche et des exemples de projets à démarrage rapide, qui peuvent également aider rapidement les développeurs à démarrer et à utiliser Seata.

Seata-go est l'implémentation du langage golang dans l'écosystème multilingue de Seata. Il est dédié à aider les développeurs golang à utiliser les capacités de Seata pour résoudre des scénarios de transactions distribuées. Seata-go réutilise les capacités de Seata TC, et les fonctions du client sont cohérentes avec Seata. Actuellement, Seata-go prend en charge les modes TCC et AT, le mode XA est en cours de test et devrait être publié en mai. Le mode Saga est en cours de conception et de planification, et il sera compatible avec la fonction Saga de Seata à l'avenir.

Cet article présente principalement la conception et l'utilisation du mode TCC dans Seata-go sous les angles suivants :

  • Principe de mise en œuvre du Seata-go TCC
  • Gestion des exceptions Sata-go TCC
  • Perspectives pour Seata-go

Principe de mise en œuvre du Seata-go TCC

Seata-go utilise getty pour la communication réseau TCP et implémente entièrement le protocole de communication de Seata. La couche inférieure implémente le centre de configuration et le centre d'enregistrement, et prend également en charge l'accès à de nombreux frameworks tiers, tels que dubbo, grpc, gorm, etc., et communique activement avec diverses communautés pour prendre en charge l'accès à davantage de frameworks. Le schéma d'architecture système simple de Seata-go est le suivant :

image.png

Tout d'abord, rappelons brièvement la signification du mode TCC. TCC est une implémentation d'un schéma de transaction distribué. Il adopte un protocole de validation en deux phases. Le nom complet de TCC est Try-Confirm-Cancel. Try est une opération de ressource réservée, Confirm est une opération de validation et Cancel est une opération de restauration. . Dans la première phase de TCC, toutes les sous-transactions sont d'abord déclenchées pour exécuter l'opération Essayer. Si la première phase de toutes les sous-transactions est exécutée avec succès, la deuxième phase de toutes les sous-transactions est déclenchée pour exécuter l'opération Confirmer. sinon, la deuxième phase exécute l'opération d'annulation, pour assurer la cohérence de chaque état de sous-transaction.

TCC est un schéma de transaction distribué intrusif. La logique des trois étapes de Try, Confirm et Cancel doit être implémentée par l'utilisateur. Cela signifie plus de code et est très intrusif pour l'entreprise ; l'avantage est qu'il est plus flexible et peut être utilisé par les utilisateurs pour résoudre des scénarios de transactions distribuées plus complexes.

Avant de présenter le mode TCC de Seata-go, passons en revue les trois rôles principaux de Seata, à savoir TC, TM et RM . TC est le coordinateur de transaction, responsable du maintien de l'état de la transaction globale et du déclenchement de la validation et de l'annulation des transactions de branche ; TM est le gestionnaire de transactions, responsable de l'organisation des sous-transactions, ainsi que de la validation et de l'annulation des transactions globales ; RM est un serveur de gestion des ressources, gère les ressources pour le traitement des transactions de branche, telles que le fonctionnement de la base de données MySQL, etc.

Après avoir compris ces trois rôles principaux, vous pouvez comprendre approximativement le processus de transaction de TCC, qui peut être grossièrement divisé en les étapes suivantes :

  • TM envoie une demande à TC pour démarrer la transaction globale, et le côté TC enregistre les informations d'état de la transaction globale ;
  • TM envoie des demandes à tous les RM respectivement, et RM enregistrera les transactions de succursale avec TC, puis exécutera la logique de la phase d'essai ;
  • Si l'un des RM retourne au TM que l'exécution de la phase Try échoue, alors le TM envoie une demande de « rollback global transaction » au TC. Une fois que le TC l'a reçu, il enverra une commande Rollback à tous les RM qui ont exécuté l'essai, déclenchant l'exécution par le RM de la logique d'annulation ;
  • Si tous les RM retournent à TM que l'exécution de la phase d'essai est réussie, alors TM envoie une requête de "commit global transaction" à TC. Une fois que le TC l'a reçu, il enverra une commande Commit à tous les RM qui ont exécuté l'essai, déclenchant le RM pour exécuter la logique Commit.

Jusqu'à présent, une transaction distribuée complète a été exécutée. Voici l'organigramme de ce processus :

image

Dans Seata-go, pour la commodité des utilisateurs, deux méthodes de définition des services TCC sont fournies, l'une consiste à implémenter l'interface TwoPhaseInterface, comme suit :

image.png

L'autre consiste à définir le service TCC par tag, ce qui est relativement compliqué mais plus souple :

image.png

La deuxième solution de balises est principalement de répondre à certains scénarios particuliers. Par exemple, le serveur et le client de dubbo-go sont définis par des balises. À ce stade, il est nécessaire d'utiliser des balises pour définir les services TCC. En général, il est recommandé d'utiliser la première méthode d'héritage de l'interface, qui est relativement simple.

En utilisation réelle, les utilisateurs n'ont qu'à faire les choses suivantes :

  • Pour définir votre propre service TCC, vous pouvez vous référer à l'une des deux méthodes décrites ci-dessus ;
  • Appelez la méthode proxy NewTCCServiceProxy de TCC pour encapsuler le service TCC dans un proxy ;
  • Organisez vos propres sous-transactions et transmettez-les à la méthode de saisie WithGlobalTx de la transaction distribuée.

Voici une capture d'écran pour vous montrer un exemple. Pour des exemples plus détaillés, veuillez vous référer au projet seata-go-samples à l'adresse : https://github.com/seata/seata-go-samples

image.png

Gestion des exceptions Seata-go TCC

Lors de l'utilisation réelle de TCC, en raison de facteurs tels que le temps d'exécution de la logique réseau ou du code métier, les problèmes suivants peuvent survenir :

  • Idempotence : dans les première et deuxième phases de la transaction, en raison d'un retard du réseau ou d'autres raisons, RM n'a pas répondu à TC ou TM à temps, ce qui a entraîné le déclenchement répété de RM pour exécuter la logique des première et deuxième phases. temps, l'idempotence de l'entreprise doit être prise en compte ;
  • Restauration vide : en raison d'un retard du réseau ou d'autres raisons, RM a reçu une demande de restauration sans recevoir de demande d'essai, ce qui a entraîné un problème de restauration vide ;
  • Suspension : en raison d'un retard du réseau ou d'autres raisons, RM a reçu une demande de restauration sans recevoir de demande d'essai, et a reçu une demande d'essai après avoir traité la demande de restauration. A ce moment, la transaction globale est terminée, ce qui empêchera la libération des ressources réservées par la transaction.

Dans Seata-go, deux solutions sont fournies pour aider les utilisateurs à résoudre ce problème.

Le principe de la première méthode est le même que la logique de traitement de Seata Java, qui s'effectue à l'aide de la table d'état des transactions tcc_fence_log :

image.png

Les utilisateurs doivent créer cette table dans leur propre base de données métier. Lorsque RM soumet le SQL métier, il insère un enregistrement dans cette table en même temps. Ces deux SQL sont complétés dans une transaction locale. Étant donné que "l'ID de transaction global + l'ID de transaction de branche" dans cette table est une clé primaire conjointe, elle échouera lorsqu'elle sera exécutée à plusieurs reprises, résolvant ainsi le problème idempotent de la phase Try. Dans les étapes de validation et d'annulation, le statut de la transaction de succursale dans cette table sera d'abord interrogé, puis la logique réelle sera exécutée et le statut sera enfin mis à jour. Cela garantit également l'idempotence des phases Commit et Cancel.

Voyons comment Seata-go résout les problèmes de suspension des transactions et de restauration vide. Si une demande de restauration arrive, RM vérifie la table tcc_fence_log et constate qu'il n'y a pas d'enregistrement (parce que RM n'a pas reçu la demande d'essai), à ce moment, il insère un enregistrement dans la table tcc_fence_log, marque l'état comme suspendu, et puis quittez directement sans exécuter la logique de restauration, évitant ainsi le problème de restauration vide. Si RM reçoit une demande Try plus tard, puisqu'il existe déjà un enregistrement dans la table tcc_fence_log, la transaction SQL ne peut pas être soumise et échoue (tcc_fence_log aura un problème de conflit de clé primaire), évitant ainsi le problème d'anti-hanging.

Pour réaliser cette méthode, vous devez utiliser la source de données proxy fournie par Seata-go. Ces opérations seront effectuées par la source de données proxy. Les utilisateurs n'ont qu'à activer le commutateur et à faire attention à leur propre SQL métier. Cette fonction a été réalisé et sera réalisé ultérieurement Version d'émission.

La deuxième méthode est réalisée manuellement par l'utilisateur. Le principe est similaire à celui ci-dessus, mais la logique de fonctionnement de tcc_fence_log doit être implémentée par l'utilisateur. La capture d'écran ci-dessous décrit la méthode d'utilisation générale. Pour plus de détails, veuillez vous référer aux exemples de code :

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

image

Perspectives Seata-go

La communauté Seata-go a récemment conclu une coopération avec de nombreux frameworks de microservices et communautés de développement en langage go nationaux derrière le framework ORM. Par exemple, le framework GORM a été intégré dans Sample, et d'autres frameworks ORM seront intégrés dans Seata-go-Samples. projet dans le futur. La coopération avec la communauté MOSN progresse également pour réaliser un véritable Transaction Mesh basé sur Seata.

Le mode XA de Seata-go sera lancé en mai et Seata-go prendra en charge les modes de transaction TCC, XA et AT. Le centre de suivi de Seata-go portera sur le développement des fonctions du mode Saga.

Le mode Saga actuel ne réalise que les capacités de restauration avant et arrière de l'orchestration des services, et une orchestration plus poussée des services peut réaliser le DAG, les tâches chronométrées et la planification des lots de tâches, couvrant tous les processus de flux de travail et améliorant l'expérience utilisateur sur la plate-forme Seata. Actuellement Seata-go dépend du TC de Seata Java. Selon ce plan de travail, il pourrait être nécessaire d'implémenter une planification TC plus puissante dans une future version de Seata-go.

La communauté Seata-go est actuellement en pleine croissance. Nous espérons que davantage d'amis intéressés par l'open source rejoindront notre communauté et aideront Seata-go à grandir ensemble !

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

Je suppose que tu aimes

Origine my.oschina.net/u/3874284/blog/8863949
conseillé
Classement