Este artigo descreve os diferentes tipos de mensagens e as entidades que participam de uma infraestrutura de mensagens. Com base nos requisitos de cada tipo de mensagem, o artigo recomenda serviços de mensagens do Azure. As opções incluem o Barramento de Serviços do Azure, a Grade de Eventos do Azure e o Hubs de Eventos do Azure. Para comparação de produtos, consulte Comparar os serviços de mensagens.
Em um nível de arquitetura, uma mensagem é um datagrama criado por uma entidade (produtor), para distribuir informações para que outras entidades (consumidores) possam estar cientes e agir de acordo. O produtor e o consumidor podem se comunicar diretamente ou opcionalmente por meio de uma entidade intermediária (agente de mensagens). Este artigo se concentra em mensagens assíncronas usando um agente de mensagens.
Podemos classificar as mensagens em duas categorias principais. Se o produtor espera uma ação do consumidor, essa mensagem é um comando. Se a mensagem informar ao consumidor que uma ação ocorreu, ela será um evento.
Comandos
O produtor envia um comando com a intenção de que os consumidores executem uma operação dentro do escopo de uma transação comercial.
Um comando é uma mensagem de alto valor e deve ser entregue pelo menos uma vez. Se um comando for perdido, toda a transação comercial poderá falhar. Além disso, um comando não deve ser processado mais de uma vez. Isso pode causar uma transação errônea. Um cliente pode receber pedidos duplicados ou cobrado duas vezes.
Os comandos geralmente são usados para gerenciar o fluxo de trabalho de uma transação de negócios de várias etapas. Dependendo da logica de negócios, o produtor pode esperar que o consumidor reconheça a mensagem e relate os resultados da operação. Com base na mensagem, o produtor pode escolher um curso de ação apropriado.
Eventos
Um evento é um tipo de mensagem que um produtor cria para anunciar fatos.
O produtor (conhecido como fornecedor neste contexto) não tem expectativas de que os eventos resultem em qualquer ação.
O(s) consumidor(es) interessado(s) pode(m) se inscrever, escutar eventos e realizar ações, dependendo do seu cenário de consumo. Eventos podem ter vários assinantes ou nenhum assinante. Dois assinantes diferentes podem reagir a um evento com ações diferentes e não estar cientes uns dos outros.
O produtor e o consumidor são livremente acoplados e gerenciados de forma independente. O produtor não espera que o consumidor reconheça o evento de volta para o produtor. Um consumidor que não esteja mais interessado nos eventos pode cancelar a assinatura, o que remove o consumidor do pipeline sem afetar o produtor ou a funcionalidade geral do sistema.
Há duas categorias de eventos:
O produtor gera eventos para anunciar fatos distintos. Um caso de uso comum é a notificação de evento. Por exemplo, o Azure Resource Manager gera eventos quando cria, modifica ou exclui recursos. Um assinante desses eventos pode ser um Aplicativo Lógico que envia emails de alerta.
O produtor gera eventos relacionados em uma sequência, ou um fluxo de eventos, durante um período. Normalmente, um fluxo é consumido para avaliação estatística. A avaliação pode ocorrer em uma janela temporal ou à medida que os eventos chegam. A telemetria é um caso de uso comum (por exemplo, monitoramento da integridade e da carga de um sistema). Outro caso é o streaming de eventos de dispositivos IoT.
Um padrão comum para implementar mensagens de evento é o padrão Editor-Assinante.
Função e benefícios de um agente de mensagens
Um corretor de mensagens intermediário fornece a funcionalidade de mover mensagens do produtor para o consumidor e pode oferecer mais benefícios.
Desacoplamento
Um agente de mensagens separa o produtor do consumidor na lógica que gera e usa as mensagens, respectivamente. Em um fluxo de trabalho complexo, o agente pode incentivar operações de negócios a serem desacopladas e ajudar a coordenar o fluxo de trabalho.
Por exemplo, uma única transação comercial requer operações distintas executadas em uma sequência lógica de negócios. O produtor emite um comando que sinaliza um consumidor para iniciar uma operação. O consumidor reconhece a mensagem em uma fila separada reservada para alinhar respostas para o produtor. Somente depois de receber a resposta, o produtor envia uma nova mensagem para iniciar a próxima operação na sequência. Um consumidor diferente processa essa mensagem e envia uma mensagem de conclusão para a fila de resposta. Usando mensagens, os serviços coordenam o fluxo de trabalho da transação entre si.
Um agente de mensagens fornece desacoplamento temporal. O produtor e o consumidor não precisam ser executados simultaneamente. Um produtor pode enviar uma mensagem ao agente de mensagens independentemente da disponibilidade do consumidor. Por outro lado, o consumidor não é restrito pela disponibilidade do produtor.
Por exemplo, a interface do usuário de um aplicativo Web gera mensagens e usa uma fila como o agente de mensagens. Quando o consumidor estiver pronto, ele poderá recuperar as mensagens da fila e executar o trabalho. A desacoplamento temporal ajuda a interface do usuário a permanecer responsiva. Ele não é bloqueado enquanto as mensagens são tratadas de forma assíncrona.
Determinadas operações poderão levar muito tempo para serem concluídas. Após a emissão de um comando, o produtor não deve ter que esperar até que o consumidor o conclua. Um agente de mensagens ajuda no processamento assíncrono de mensagens.
Balanceamento de carga
Os produtores podem postar um grande número de mensagens atendidas por muitos consumidores. Use um agente de mensagens para distribuir o processamento entre servidores e melhorar a taxa de transferência. Os consumidores podem ser executados em servidores diferentes para espalhar a carga. Os consumidores podem ser adicionados dinamicamente para dimensionar o sistema quando necessário ou removidos de outra forma.
O padrão Consumidores Concorrentes explica como fazer para processar várias mensagens simultaneamente para otimizar a taxa de transferência, melhorar a escalabilidade e a disponibilidade e equilibrar a carga de trabalho.
Nivelamento de carga
O volume de mensagens geradas pelo produtor ou por um grupo de produtores pode ser variável. Às vezes, pode haver um grande volume causando picos nas mensagens. Em vez de adicionar consumidores para lidar com esse trabalho, um agente de mensagens pode agir como um buffer, e os consumidores gradualmente drenam mensagens em seu próprio ritmo sem enfatizar o sistema.
O padrão Nivelamento de Carga baseado em Filas fornece mais informações.
Mensagens confiáveis
Um agente de mensagens ajuda a garantir que as mensagens não sejam perdidas mesmo se a comunicação falhar entre o produtor e o consumidor. O produtor poderá postar mensagens no agente de mensagens e o consumidor poderá recuperá-las quando a comunicação for restabelecida. O produtor não é bloqueado, a menos que perca a conectividade com o agente de mensagens.
Mensagens resilientes
Um agente de mensagens pode adicionar resiliência aos consumidores em seu sistema. Se um consumidor falhar ao processar uma mensagem, outra instância do consumidor poderá processar essa mensagem. O reprocessamento é possível porque a mensagem persiste no agente.
Opções de tecnologia para um agente de mensagens
O Azure fornece vários serviços do agente de mensagens, cada um com uma variedade de recursos. Antes de escolher um serviço, determine a intenção e os requisitos da mensagem.
Messaging do Barramento de Serviço do Azure
As filas de mensagens do Barramento de Serviços do Azure são adequadas para a transferência de comandos de produtores para consumidores. Aqui estão algumas considerações.
Modelo de pull
Um consumidor de uma fila do Barramento de Serviço consulta constantemente o Barramento de Serviço para verificar se novas mensagens estão disponíveis. Os SDKs do cliente e o gatilho do Azure Functions para Barramento de Serviço abstraem esse modelo. Quando uma nova mensagem está disponível, o retorno de chamada do consumidor é invocado e a mensagem é enviada para o consumidor.
Entrega garantida
O Barramento de Serviço permite que um consumidor espie a fila e bloqueie uma mensagem de outros consumidores.
É responsabilidade do consumidor relatar o status do processamento da mensagem. Somente quando o consumidor marca a mensagem como consumida é que o Barramento de Serviço do Azure remove a mensagem da fila. Se ocorrer uma falha, tempo limite ou falha, o Barramento de Serviço desbloqueará a mensagem para que outros consumidores possam recuperá-la. Dessa forma, as mensagens não se perdem na transferência.
Um produtor pode enviar acidentalmente a mesma mensagem duas vezes. Por exemplo, uma instância de produtor falha depois de enviar uma mensagem. Outro produtor substitui a instância original e envia a mensagem novamente. As filas do Barramento de Serviço do Azure fornecem uma funcionalidade interna de eliminação de duplicação que detecta e remove mensagens duplicadas. Ainda há uma chance de uma mensagem ser entregue duas vezes. Por exemplo, se um consumidor falhar durante o processamento, a mensagem será retornada para a fila e recuperada pelo mesmo ou por outro consumidor. A logica de processamento de mensagens no consumidor deve ser idempotente para que, mesmo se o trabalho for repetido, o estado do sistema não seja alterado.
Ordenação de mensagens
Se você deseja que os consumidores recebam as mensagens na ordem em que foram enviadas, as filas do Barramento de Serviço do Azure garantem a entrega ordenada primeiro a entrar, primeiro a sair (FIFO) utilizando sessões. Uma sessão pode ter uma ou mais mensagens. As mensagens estão correlacionadas com a propriedade SessionId. Mensagens que fazem parte de uma sessão nunca expiram. Uma sessão pode ser bloqueada para um consumidor para impedir que suas mensagens sejam manipuladas por um consumidor diferente.
Para obter mais informações, confira Sessões de mensagem.
Persistência da mensagem
As filas do Barramento de Serviço dão suporte ao desacoplamento temporal. Mesmo quando um consumidor não está disponível ou não consegue processar a mensagem, ele permanece na fila.
Transações de longa execução do ponto de verificação
As transações comerciais podem ser executadas por muito tempo. Cada operação na transação pode ter várias mensagens. Use o ponto de verificação para coordenar o fluxo de trabalho e fornecer resiliência caso uma transação falhe.
As filas do Barramento de Serviço permitem o ponto de verificação por meio da funcionalidade de estado da sessão. As informações de estado são registradas incrementalmente na fila (SetState) para mensagens que pertencem a uma sessão. Por exemplo, um consumidor pode acompanhar o progresso verificando o estado (GetState) de vez em quando. Se um consumidor falhar, outro consumidor poderá usar informações de estado para determinar o último ponto de verificação conhecido para retomar a sessão.
DLQ (fila de mensagens mortas)
Uma fila do Barramento de Serviço tem uma subconsulta padrão, chamada DLQ (fila de mensagens mortas) para armazenar mensagens que não puderam ser entregues ou processadas. O Barramento de Serviço ou a lógica de processamento de mensagens no consumidor podem adicionar mensagens ao DLQ. O DLQ mantém as mensagens até que elas sejam recuperadas da fila.
Aqui estão alguns exemplos de quando uma mensagem pode acabar ficando no DLQ:
Uma mensagem suspeita é uma mensagem que não pode ser tratada porque está malformada ou contém informações inesperadas. Nas filas do Barramento de Serviço, você pode detectar mensagens venenosas definindo a propriedade MaxDeliveryCount da fila. Se o número de vezes que a mesma mensagem for recebida exceder esse valor de propriedade, o Barramento de Serviço do Azure moverá a mensagem para o DLQ.
Uma mensagem poderá não ser mais relevante se não for processada dentro de um período. As filas do Barramento de Serviço permitem que o produtor poste mensagens com um atributo de tempo de vida útil. Se esse período expirar antes do recebimento da mensagem, a mensagem será colocada no DLQ.
Examine as mensagens no DLQ para determinar o motivo da falha.
Solução híbrida
O Barramento de Serviço conecta sistemas locais e soluções de nuvem. Os sistemas locais geralmente são difíceis de alcançar devido a restrições de firewall. Tanto o produtor quanto o consumidor (podem ser locais ou na nuvem) podem usar o ponto de extremidade da fila do Barramento de Serviço como o local de retirada e entrega para mensagens.
O padrão Ponte de Mensagens é outra maneira de lidar com esses cenários.
Tópicos e assinaturas
O Barramento de Serviço dá suporte ao padrão Editor-Assinante por meio de tópicos e assinaturas do Barramento de Serviço.
Esse recurso fornece uma maneira de o produtor transmitir mensagens para vários consumidores. Quando um tópico recebe uma mensagem, ele é encaminhado para todos os consumidores inscritos. Opcionalmente, uma assinatura poderá ter critérios de filtro que permitem ao consumidor obter um subconjunto de mensagens. Cada consumidor recupera mensagens de uma assinatura de maneira semelhante a uma fila.
Para obter mais informações, confira Tópicos do Barramento do Serviço do Azure.
Grade de Eventos do Azure
Recomendamos a Grade de Eventos do Azure para eventos discretos. A Grade de Eventos segue o padrão Editor-Assinante. Quando as fontes de eventos disparam os eventos, eles são publicados em Tópicos da Grade de Eventos. Os consumidores desses eventos criam assinaturas da Grade de Eventos especificando tipos de evento e manipulador de eventos que processarão os eventos. Se não houver assinantes, os eventos serão descartados. Cada evento pode ter várias assinaturas.
Modelo de push
A Grade de Eventos propaga mensagens para os assinantes em um modelo de push. Suponha que você tenha uma assinatura na Grade de Eventos com um webhook. Quando um novo evento chega, a Grade de Eventos posta o evento no ponto de extremidade do webhook.
Integrado com o Azure
Escolha a Grade de Eventos se quiser receber notificações sobre recursos do Azure. Muitos serviços do Azure atuam como fontes de eventos que têm tópicos internos da Grade de Eventos. A Grade de Eventos também dá suporte a vários serviços do Azure que podem ser configurados como manipuladores de eventos. É fácil assinar esses tópicos para rotear eventos para manipuladores de eventos de sua escolha. Por exemplo, você pode usar a Grade de Eventos para invocar uma Função do Azure quando um armazenamento de blobs é criado ou excluído.
Tópicos personalizados
Crie tópicos personalizados da Grade de Eventos do Azure se desejar enviar eventos do seu aplicativo ou de um serviço do Azure que não esteja integrado à Grade de Eventos.
Por exemplo, para ver o progresso de uma transação comercial inteira, você deseja que os serviços participantes gerem eventos à medida que processam suas operações comerciais individuais. Um aplicativo Web mostra esses eventos. Uma maneira de realizar essa tarefa é criar um tópico personalizado e adicionar uma assinatura com seu aplicativo Web registrado por meio de um WebHook HTTP. Conforme os serviços comerciais enviam eventos para o tópico personalizado, a Grade de Eventos os envia por push para seu aplicativo Web.
Eventos filtrados
Você pode especificar filtros em uma assinatura para instruir a Grade de Eventos para rotear apenas um subconjunto de eventos para um manipulador de eventos específico. Você especifica os filtros no esquema de assinatura. Qualquer evento enviado ao tópico com valores que correspondem ao filtro é encaminhado automaticamente para essa assinatura.
Por exemplo, o conteúdo em vários formatos é carregado no Armazenamento de Blobs. Cada vez que um arquivo é adicionado, um evento é gerado e publicado na Grade de Eventos. A assinatura do evento pode ter um filtro que envia apenas eventos para imagens para que um manipulador de eventos possa gerar miniaturas.
Para obter mais informações sobre filtragem, confira Filtrar eventos para Grade de Eventos.
Alta taxa de transferência
A Grade de Eventos pode rotear 10.000.000 eventos por segundo por região. As primeiras 100.000 operações por mês são gratuitas. Para considerações de custo, confira Quanto custa a Grade de Eventos?
Entrega resiliente
Embora a entrega bem-sucedida de eventos não seja tão fundamental quanto os comandos, talvez você ainda queira alguma garantia dependendo do tipo de evento. A Grade de Eventos oferece recursos que você pode habilitar e personalizar, como políticas de repetição, tempo de expiração e letras mortas. Para saber mais, confira Event Grid message delivery and retry (Entrega e repetição de mensagens da Grade de Eventos).
O processo de repetição da Grade de Eventos pode ajudar na resiliência, mas não é à prova de falhas. No processo de repetição, a Grade de Eventos poderá entregar a mensagem mais de uma vez, ignorar ou atrasar algumas novas tentativas se o ponto de extremidade não responder por muito tempo. Para obter mais informações, consulte Agendamento da repetição.
Você pode persistir eventos não entregues em uma conta de armazenamento de blobs habilitando o uso de mensagens mortas. Há um atraso na entrega da mensagem para o ponto de extremidade de armazenamento de blobs e, se esse ponto de extremidade não responder, a Grade de Eventos descartará o evento. Para obter mais informações, consulte Definir o local das mensagens mortas e política de repetição.
Hubs de Eventos do Azure
Quando estiver trabalhando com um fluxo de eventos, o Hubs de Eventos do Azure é o agente de mensagens recomendado. Basicamente, é um grande buffer capaz de receber grandes volumes de dados com baixa latência. Os dados recebidos podem ser lidos rapidamente por meio de operações simultâneas. Você pode transformar os dados recebidos usando qualquer provedor de análise em tempo real. Os Hubs de Eventos também fornecem a capacidade de armazenar eventos em uma conta de armazenamento.
Ingestão rápida
Os Hubs de Eventos são capazes de ingerir milhões de eventos por segundo. Os eventos são anexados somente ao fluxo e são ordenados por tempo.
Modelo de pull
Assim como a Grade de Eventos, os Hubs de Eventos também oferecem recursos de Editor-Assinante. Uma diferença importante entre a Grade de Eventos e os Hubs de Eventos está na maneira como os dados de eventos são disponibilizados para os assinantes. O Grade de Eventos envia por push os dados ingeridos para os assinantes, enquanto o Hubs de Eventos disponibiliza os dados em um modelo de pull. Conforme os eventos são recebidos, os Hubs de Eventos os anexa ao fluxo. Um assinante gerencia seu cursor e pode avançar e voltar no fluxo, selecionar um deslocamento de tempo e reproduzir uma sequência em seu ritmo.
Os processadores de fluxo são assinantes que obtém dados dos Hubs de Eventos para fins de transformação e análise estatística. Use o Azure Stream Analytics e o Apache Spark para processamento complexo, como agregação ao longo de janelas de tempo ou detecção de anomalias.
Se desejar agir em cada evento por partição, você pode efetuar pull dos dados utilizando o Host do processador de eventos ou usando um conector interno, como o Aplicativos Lógicos do Azure, para fornecer a lógica de transformação. Outra opção é usar Azure Functions.
Particionamento
Uma partição é uma parte do fluxo de eventos. Os eventos são divididos usando uma chave de partição. Por exemplo, vários dispositivos IoT enviam dados do dispositivo para um hub de eventos. A chave de partição é o identificador do dispositivo. Conforme os eventos são ingeridos, os Hubs de Eventos os movem para partições separadas. Dentro de cada partição, todos os eventos são ordenados por tempo.
Um consumidor é uma instância de código que processa os dados do evento. Os Hubs de Eventos seguem um padrão de consumidor particionado. Cada consumidor lê somente uma partição específica. Ter várias partições resulta em processamento mais rápido porque o fluxo poderá ser lido simultaneamente por vários consumidores.
Instâncias do mesmo consumidor compõem um único grupo de consumidores. Vários grupos de consumidores podem ler o mesmo fluxo com intenções diferentes. Suponha que um fluxo de eventos tenha dados de um sensor de temperatura. Um grupo de consumidores pode ler o fluxo para detectar anomalias, como um aumento na temperatura. Outro pode ler o mesmo fluxo para calcular uma temperatura média móvel em uma janela temporal.
Os Hubs de Eventos dão suporte ao padrão Editor-Assinante permitindo vários grupos de consumidores. Cada grupo de consumidores é um assinante.
Para obter mais informações sobre o particionamento de Hubs de Eventos, consulte Partições.
Capturar Hubs de Eventos
O recurso Capturar permite que você armazene o fluxo de eventos em um armazenamento de Blobs do Azure ou Data Lake Storage. Essa maneira de armazenar eventos é confiável porque, mesmo se a conta de armazenamento não estiver disponível, o Captura mantém seus dados por um período e grava no armazenamento depois que ele estiver disponível.
Os serviços de armazenamento também podem oferecer recursos adicionais para analisar eventos. Por exemplo, aproveitando as camadas de acesso de uma conta de armazenamento de blobs, você pode armazenar eventos em uma camada quente para dados que precisam de acesso frequente. Você pode usar esses dados para visualização. Como alternativa, você pode armazenar dados na camada de arquivo e recuperá-los ocasionalmente para fins de auditoria.
A captura armazena todos os eventos ingeridos pelos Hubs de Eventos e é útil para processamento em lote. Você pode gerar relatórios nos dados usando uma função MapReduce. Os dados capturados também podem servir como a fonte da verdade. Se determinados fatos tiverem sido perdidos ao agregar os dados, você poderá consultar os dados capturados.
Para obter detalhes sobre este recurso, confira Capturar eventos por meio dos Hubs de Eventos do Azure no Armazenamento de Blobs do Azure ou no Azure Data Lake Storage.
Suporte para clientes do Apache Kafka
Os Hubs de Eventos fornecem um ponto de extremidade para clientes do Apache Kafka. Os clientes existentes podem atualizar sua configuração para apontar para o ponto de extremidade e começar a enviar eventos aos Hubs de Eventos. Você não precisa fazer nenhuma alteração no código.
Para saber mais, consulte Hubs de Eventos para o Apache Kafka.
Cenários de crossover
Em alguns casos, é vantajoso combinar dois serviços de mensagem.
Combinar serviços pode aumentar a eficiência do sistema de mensagens. Por exemplo, em sua transação comercial, você usa filas do Barramento de Serviço do Azure para lidar com mensagens. As filas que ficam ociosas em sua maior parte e recebem mensagens ocasionalmente são ineficientes, porque o consumidor está constantemente pesquisando a fila em busca de novas mensagens. Você pode configurar uma assinatura da Grade de Eventos com uma Função do Azure como manipulador de eventos. Sempre que a fila recebe uma mensagem e não há consumidores escutando, a Grade de Eventos envia uma notificação, que invoca a Função do Azure que drena a fila.
Para obter detalhes sobre como conectar o Barramento de Serviço à Grade de Eventos, confira Visão geral do Barramento de Serviço do Azure para integração da Grade de Eventos.
A arquitetura de referência Integração Enterprise utilizando filas de mensagens e eventos mostra uma implementação da integração entre o Barramento de Serviço do Azure e a Grade de Eventos.
Veja outro exemplo: A Grade de Eventos recebe um conjunto de eventos em que alguns eventos exigem um fluxo de trabalho, enquanto outros são para notificação. Os metadados da mensagem indicam o tipo de evento. Uma maneira de diferenciar é verificar os metadados utilizando o recurso de filtragem na assinatura do evento. Se exigir um fluxo de trabalho, a Grade de Eventos o enviará para a fila do Barramento de Serviço do Azure. Os receptores dessa fila podem tomar as ações necessárias. Os eventos de notificação são enviados aos Aplicativos Lógicos para enviar emails de alerta.
Padrões relacionados
Considere estes padrões ao implementar mensagens assíncronas:
- Padrão de consumidores concorrentes. É possível que vários consumidores precisem competir para a leitura de mensagens de uma fila. Este padrão explica como processar várias mensagens simultaneamente para otimizar a taxa de transferência, melhorar a escalabilidade e a disponibilidade e equilibrar a carga de trabalho.
- Padrão de fila de prioridade. Nos casos em que a lógica de negócios exige que algumas mensagens sejam processadas antes de outras, esse padrão descreve como as mensagens postadas por um produtor com prioridade mais alta são recebidas e processadas mais rapidamente por um consumidor ao invés das mensagens de prioridade mais baixa.
- Padrão de nivelamento de carga baseado em fila. Esse padrão usa um agente de mensagens para atuar como um buffer entre um produtor e um consumidor para ajudar a minimizar o impacto na disponibilidade e na capacidade de resposta de cargas pesadas intermitentes para ambas as entidades.
- Padrão de repetição. Um produtor ou consumidor pode não conseguir se conectar a uma fila, mas os motivos dessa falha podem ser temporários e passar rapidamente. Esse padrão descreve como lidar com essa situação para adicionar resiliência a um aplicativo.
- Padrão Supervisor do Agente Agendador. Muitas vezes, o sistema de mensagens é usado como parte de uma implementação de fluxo de trabalho. Este padrão demonstra como o sistema de mensagens pode coordenar um conjunto de ações em um conjunto distribuído de serviços e outros recursos remotos e permitir que um sistema recupere e repita ações que falham.
- Padrão de coreografia. Este padrão mostra como os serviços podem usar mensagens para controlar o fluxo de trabalho de uma transação comercial.
- Padrão de Verificação de Declarações. Este padrão mostra como dividir uma mensagem grande em uma verificação de declaração e um payload.
Recursos da comunidade
Postagem no blog de Jonathon Oliver: Idempotência
Postagem no blog de Martin Fowler: O que você quer dizer com "Controlado por evento"?