DEV Community

Cover image for Brighter: Migração do MySQL Outbox para a V10
Rafael Andrade
Rafael Andrade

Posted on

Brighter: Migração do MySQL Outbox para a V10

Neste artigo, vou focar especificamente no processo de migração do outbox MySQL.

Requisitos

Recapitulação do Brighter

Antes de continuar falando sobre a configuração do outbox MySQL, vamos recapitular o que já sabemos sobre o Brighter.

Requisição (Comando/Evento)

Defina mensagens usando IRequest:

public class OrderPlaced() : Event(Id.Random())
{
    public string OrderId { get; set; } = string.Empty;
    public decimal Value { get; set; }
}
Enter fullscreen mode Exit fullscreen mode
  • Comandos: Operações para um único destinatário (ex: SendEmail).
  • Eventos: Notificações de broadcast (ex: OrderShipped).

Mapeador de Mensagens (Opcional)

Traduz entre mensagens do Brighter e objetos da sua aplicação. Por padrão, o Brighter usará um serializador JSON.

public class OrderPlacedMapper : IAmAMessageMapper<OrderPlaced>, IAmAMessageMapperAsync<OrderPlaced>
{ ... }
Enter fullscreen mode Exit fullscreen mode

Manipulador de Requisições

Processa mensagens recebidas:

public class OrderPlaceHandler(ILogger<OrderPlaceHandler> logger) : RequestHandler<OrderPlaced>
{
    public override Greeting Handle(Greeting command)
    {
        logger.LogInformation("{OrderId} placed with value {OrderValue}", command.OrderId, command.Value);
        return base.Handle(command);

    }
}
Enter fullscreen mode Exit fullscreen mode

Usando o Outbox no Brighter

Antes de configurar o outbox, entenda como interagir com ele:

Publicando Mensagens através do Outbox

O Brighter fornece o método DepositPostAsync para armazenar mensagens no outbox

await commandProcessor.DepositPostAsync(
    new OrderPlaced { OrderId = "ORD-123", Value = 99.99m }, 
    cancellationToken: cancellationToken);
Enter fullscreen mode Exit fullscreen mode

Isso armazena a mensagem na sua tabela MySQL do outbox para processamento posterior.

Configuração do pacote outbox

1. Garanta que a tabela existe

Primeiro, crie a tabela do outbox no seu banco de dados MySQL. O Brighter não gerenciará esta tabela para você - você é responsável por criá-la e adicionar os índices necessários:

CREATE TABLE outboxmessages ( 
   `MessageId`VARCHAR(255) NOT NULL , 
   `Topic` VARCHAR(255) NOT NULL , 
   `MessageType` VARCHAR(32) NOT NULL , 
   `Timestamp` TIMESTAMP(3) NOT NULL , 
   `CorrelationId`VARCHAR(255) NULL ,
   `ReplyTo` VARCHAR(255) NULL ,
   `ContentType` VARCHAR(128) NULL , 
   `PartitionKey` VARCHAR(128) NULL , 
   `WorkflowId` VARCHAR(255) NULL ,
   `JobId` VARCHAR(255) NULL ,
   `Dispatched` TIMESTAMP(3) NULL , 
   `HeaderBag` TEXT NOT NULL , 
   `Body` TEXT NOT NULL , 
   `Source`  VARCHAR(255) NULL,
   `Type`  VARCHAR(255) NULL,
   `DataSchema`  VARCHAR(255) NULL,
   `Subject`  VARCHAR(255) NULL,
   `TraceParent`  VARCHAR(255) NULL,
   `TraceState`  VARCHAR(255) NULL,
   `Baggage`  TEXT NULL,
   `Created` TIMESTAMP(3) NOT NULL DEFAULT NOW(3),
   `CreatedID` INT(11) NOT NULL AUTO_INCREMENT, 
   UNIQUE(`CreatedID`),
   PRIMARY KEY (`MessageId`)
 ) ENGINE = InnoDB;
Enter fullscreen mode Exit fullscreen mode

2. Configurar o outbox

Configure o outbox na sua configuração de injeção de dependência:

var conn = new RelationalDatabaseConfiguration(connectionString, "brightertests", "outboxmessages");

services
  .AddSingleton<IAmARelationalDatabaseConfiguration>(conn)
  .AddConsumers(opt => { ... }) // Ou AddBrighter
  .AddProducers(opt => 
  {
     opt.ConnectionProvider = typeof(MySqlUnitOfWork);
     opt.TransactionProvider = typeof(MySqlUnitOfWork);
     opt.Outbox = new MySqlOutbox(outbox);
    ... 
  })
Enter fullscreen mode Exit fullscreen mode

3. Configurar o Sweeper (Varredor)

Configure o varredor do outbox na sua configuração de injeção de dependência:

services
  .AddSingleton<IAmARelationalDatabaseConfiguration>(conn)
  .AddConsumers(opt => { ... }) // Ou AddBrighter
  .UseOutboxSweeper(opt => { opt.BatchSize = 10; })
Enter fullscreen mode Exit fullscreen mode

Observação: Se estiver executando em um ambiente multi-máquina, garanta que apenas uma instância execute o varredor ou configure o bloqueio distribuído no Brighter para evitar entrega duplicada de mensagens.

4. Configurar o Arquivamento do Outbox

Após as mensagens serem enviadas com sucesso, você pode querer arquivá-las:

services
  .AddSingleton<IAmARelationalDatabaseConfiguration>(conn)
  .AddConsumers(opt => { ... }) // Ou AddBrighter
  .UseOutboxArchiver<DbTransaction>(new NullOutboxArchiveProvider(),
                    opt => opt.MinimumAge = TimeSpan.FromMinutes(1));
Enter fullscreen mode Exit fullscreen mode

Principais Diferenças Entre o Brighter V9 e V10

Outbox como Serviço Singleton

No Brighter V10, o outbox é implementado como um serviço singleton, o que representa uma mudança arquitetônica significativa:

  • V9: O outbox era escopo por requisição, permitindo compartilhamento de transação entre o código da aplicação e o outbox
  • V10: O outbox é um singleton, o que melhora o desempenho, mas significa que você não pode mais compartilhar transações diretamente

Se a publicação atômica de mensagens em várias mensagens for crítica para sua aplicação, você precisará implementar uma solução personalizada ou considerar abrir uma discussão no repositório GitHub do Brighter.

Mudanças na Configuração do Banco de Dados

No Brighter V10, o outbox é um singleton, então agora não é possível compartilhar transações (talvez exista uma solução alternativa que eu não tenha encontrado), tornando impossível ter uma publicação atômica de mensagens, como se algo falhar não enviar nenhuma mensagem. Se você sentir que isso é uma limitação em sua aplicação, por favor abra uma discussão/issue no GitHub do Brighter.

Mudanças na Configuração do Banco de Dados

Os parâmetros do construtor RelationalDatabaseConfiguration foram alterados:

// V9
new RelationalDatabaseConfiguration(connectionString, "outboxmessages");

// V10
new RelationalDatabaseConfiguration(connectionString, "database_name", "outboxmessages");
Enter fullscreen mode Exit fullscreen mode

O segundo parâmetro agora especifica o nome do banco de dados em vez do nome da tabela do outbox, o que suporta capacidades aprimoradas de telemetria.

Mudanças no Esquema da Tabela

O esquema da tabela do outbox V10 inclui várias novas colunas em comparação com o V9:

  • Colunas TraceParent, TraceState e Baggage para melhor rastreamento distribuído
  • Colunas Source, Type, DataSchema e Subject para metadados mais ricos das mensagens

Conclusão

Migrar seu outbox MySQL para o Brighter V10 requer atenção a várias mudanças-chave na arquitetura e configuração. Embora a implementação do outbox singleton melhore o desempenho, ela requer ajustar sua abordagem para o gerenciamento de transações. O esquema aprimorado fornece melhor suporte para rastreamento distribuído e metadados de mensagens mais ricos, alinhando o Brighter mais estreitamente com práticas modernas de observabilidade.

Lembre-se de:

  • Atualizar seu esquema da tabela para incluir as novas colunas
  • Ajustar sua configuração do banco de dados para especificar tanto o nome do banco de dados quanto o nome da tabela
  • Reconsiderar sua estratégia de transação devido à implementação do outbox singleton
  • Configurar o varredor e o arquivador com parâmetros apropriados para seu ambiente

Com essas mudanças implementadas, sua aplicação estará pronta para aproveitar o desempenho e recursos aprimorados no Brighter V10, mantendo a entrega confiável de mensagens através do padrão outbox MySQL.

Top comments (0)