Sessões de mensagem

As sessões de Barramento de Serviço do Azure permitem o tratamento conjunto e ordenado de sequências não associadas de mensagens relacionadas. As sessões podem ser usadas em padrões PEPS (primeiro a entrar, primeiro a sair) e solicitação-resposta. Este artigo mostra como usar sessões para implementar esses padrões ao usar o Barramento de Serviço.

Observação

A camada básica do Barramento de Serviço não dá suporte a sessões. As camadas Standard e Premium dão suporte a sessões. Para conferir as diferenças entre essas camadas, consulte preços do Barramento de Serviço.

Padrão PEPS (primeiro a entrar, primeiro a sair)

Para que a sequência FIFO seja garantida no processamento de mensagens em filas ou assinaturas do Barramento de Serviço, use sessões. O Barramento de Serviço não é restritivo quanto à natureza da relação entre as mensagens e também não define um modelo específico para determinar onde uma sequência de mensagens começa ou termina.

Qualquer remetente pode criar uma sessão ao enviar mensagens a um tópico ou uma fila definindo a propriedade ID da sessão como um identificador definido pelo aplicativo que seja exclusivo da sessão. No nível do protocolo AMQP 1.0, esse valor é mapeado para a propriedade group-id.

Em filas ou assinaturas com reconhecimento de sessão, as sessões passam a existir quando há pelo menos uma mensagem na ID de sessão. Quando uma sessão existe, não há uma API ou tempo definido para quando a sessão expira ou desaparece. Teoricamente, uma mensagem pode ser recebida em uma sessão hoje, a próxima mensagem em um ano e se a ID de sessão corresponder, a sessão é a mesma da perspectiva do Barramento de Serviço.

Normalmente, no entanto, um aplicativo tem uma noção clara de onde um conjunto de mensagens relacionadas começa e termina. O Barramento de Serviço não define nenhuma regra específica. Por exemplo, o aplicativo pode definir a propriedade Label para a primeira mensagem como start, para as mensagens intermediárias como content e para a última mensagem como end. A posição relativa das mensagens de conteúdo pode ser computada como o delta de SequenceNumber da mensagem atual com relação ao SequenceNumber da mensagem start.

Importante

Quando as sessões são habilitadas em uma fila ou em uma assinatura, os aplicativos cliente não podem mais enviar/receber mensagens regulares. Todas as mensagens devem ser enviadas como parte de uma sessão (definindo a ID de sessão) e recebidas aceitando a sessão. Os clientes ainda podem espiar uma fila ou assinatura com sessões habilitadas. Confira Navegação por mensagens.

As APIs para sessões existem em clientes de fila e assinatura. Há um modelo imperativo que controla quando as sessões e mensagens são recebidas e um modelo baseado no manipulador, que oculta a complexidade do gerenciamento do loop de recebimento.

Para obter exemplos, use os links na seção Próximas etapas.

Recursos de sessão

As sessões fornecem demultiplexação simultânea de fluxos de mensagens intercaladas enquanto preserva e garante a entrega ordenada.

Diagram that shows how the Sessions feature preserves an ordered delivery.

Um receptor de sessão é criado por um cliente aceitando uma sessão. Quando a sessão é aceita e mantida por um cliente, o cliente mantém um bloqueio exclusivo em todas as mensagens com a ID de sessão dessa sessão na fila ou assinatura. Ele mantém bloqueios exclusivos em todas as mensagens com a ID de sessão que será entregue mais tarde.

O bloqueio é liberado quando você chama os métodos de fechamento no receptor ou quando o bloqueio expira. Também existem métodos no receptor para renovar os bloqueios. Em vez disso, você pode usar o recurso de renovação automática de bloqueios, em que é possível especificar a duração pela qual você deseja manter o bloqueio renovado. O bloqueio de sessão deve ser tratado como um bloqueio exclusivo em um arquivo, o que significa que o aplicativo deve fechar a sessão assim que não precisar mais dela e/ou não esperar nenhuma mensagem adicional.

Quando vários destinatários simultâneos efetuam o pull da fila, as mensagens que pertencem a uma sessão específica são expedidas para um destinatário específico que atualmente mantém o bloqueio para a sessão. Com essa operação, um fluxo de mensagens intercaladas em uma fila ou assinatura é corretamente desmultiplexado para diferentes destinatários e esses destinatários também podem residir em computadores cliente diferentes, uma vez que o gerenciamento de bloqueio ocorre no lado do servidor, dentro do Barramento de Serviço.

A ilustração anterior mostra três receptores de sessão concomitantes. Uma Sessão com SessionId = 4 não tem nenhum cliente proprietário e ativo, o que significa que nenhuma mensagem é entregue dessa sessão específica. Uma sessão atua de várias maneiras, como uma subfila.

O bloqueio da sessão mantido pelo destinatário da sessão é um abrangente para os bloqueios de mensagem usados pelo modo de liquidação de bloqueio de pico. Somente um destinatário pode ter um bloqueio em uma sessão. Um destinatário pode ter muitas mensagens em andamento, mas as mensagens são recebidas na ordem. Abandonar uma mensagem faz com que a mesma mensagem seja atendida novamente com a próxima operação de recebimento.

Gerenciar estado de sessão

Quando os fluxos de trabalho são processados em sistemas de nuvem de alta disponibilidade e grande escala, o manipulador de fluxo de trabalho associado a uma determinada sessão deve ser capaz de se recuperar de falhas inesperadas e de retomar o trabalho concluído parcialmente em um computador ou processo diferente do em que o trabalho começou.

O recurso de estado de sessão permite uma anotação definida pelo aplicativo de uma sessão de mensagem dentro do agente, de forma que o estado de processamento registrado relativo a essa sessão seja disponibilizado automaticamente quando a sessão é adquirida por um novo processador.

Da perspectiva do Barramento de Serviço, o estado de sessão da mensagem é um objeto binário opaco que pode conter dados do tamanho de uma mensagem, que é 256 KB para o Barramento de Serviço e 100 MB para o Barramento de Serviço Premium. O estado de processamento relativo a uma sessão pode ser mantido dentro do estado de sessão ou o estado de sessão pode apontar para um registro de banco de dados ou local de armazenamento que contém tal informação.

Você pode encontrar os métodos de gerenciamento do estado de sessão SetState e GetState no objeto do receptor da sessão. Uma sessão que não tinha um estado de sessão definido retorna uma referência nula para GetState. O estado de sessão definido anteriormente pode ser limpo passando NULL para o método SetState no receptor.

O estado de sessão permanece, desde que não tenha sido desmarcado (retornando nulo), mesmo que todas as mensagens em uma sessão sejam consumidas.

O estado de sessão mantido em uma fila ou em uma assinatura conta para a cota de armazenamento dessa entidade. Quando o aplicativo é finalizado com uma sessão, é recomendável que o aplicativo limpe o estado que foi retido para evitar custos de gerenciamento externo.

Impacto da contagem de entregas

A definição de contagem de entregas por mensagem no contexto de sessões varia um pouco da definição na ausência de sessões. Veja uma tabela que resume quando a contagem de entregas é incrementada.

Cenário A contagem de entregas da mensagem é incrementada
A sessão é aceita, mas o bloqueio de sessão expira (devido ao tempo limite) Sim
A sessão é aceita, as mensagens da sessão não são concluídas (mesmo se estiverem bloqueadas) e a sessão é encerrada Não
A sessão é aceita, as mensagens são concluídas e, depois, a sessão é fechada explicitamente N/A (é o fluxo padrão. Aqui, as mensagens são removidas da sessão)

Padrão de solicitação-resposta

O padrão solicitação-resposta é um padrão de integração bem estabelecido que permite ao aplicativo remetente enviar uma solicitação e fornece uma maneira de o destinatário enviar corretamente uma resposta de volta para o aplicativo remetente. Esse padrão normalmente precisa de uma fila ou tópico de curta duração para o aplicativo enviar respostas. Nesse cenário, as sessões fornecem uma solução alternativa simples com semântica comparável.

Vários aplicativos podem enviar suas solicitações a uma única fila de solicitações, com um parâmetro de cabeçalho específico definido para identificar exclusivamente o aplicativo remetente. O aplicativo destinatário pode processar as solicitações recebidas na fila e enviar respostas na fila habilitada para a sessão, definindo a ID da sessão como o identificador exclusivo que o remetente enviou na mensagem de solicitação. Depois, o aplicativo que enviou a solicitação poderá receber mensagens na ID de sessão específica e processar as respostas corretamente.

Observação

O aplicativo que envia as solicitações iniciais deve saber sobre a ID de sessão e usá-la para aceitar a sessão para bloquear a sessão em que está esperando a resposta. É uma boa ideia usar um GUID que identifique exclusivamente a instância do aplicativo como uma ID de sessão. Não deve haver manipulador de sessão nem tempo limite especificado no receptor da sessão na fila para garantir que as respostas estejam disponíveis para serem bloqueadas e processadas por destinatários específicos.

Sequenciamento versus sessões

O número de sequência, por si só, garante a ordem de enfileiramento e a ordem de extração das mensagens, mas não a ordem de processamento, que requer sessões.

Digamos que haja três mensagens na fila e dois consumidores.

  1. O consumidor 1 pega a mensagem 1.
  2. O consumidor 2 pega a mensagem 2.
  3. O Consumidor 2 termina de processar a mensagem 2 e pega a mensagem 3, enquanto o Consumidor 1 ainda não terminou de processar a mensagem 1.
  4. O consumidor 2 conclui o processamento da mensagem 3, mas o consumidor 1 ainda não concluiu o processamento da mensagem 1.
  5. Por fim, o consumidor 1 conclui o processamento da mensagem 1.

Portanto, as mensagens foram processadas nesta ordem: mensagem 2, mensagem 3 e mensagem 1. Se você precisar que as mensagens 1, 2 e 3 sejam processadas em ordem, será necessário usar sessões.

Se as mensagens só precisarem ser recuperadas em ordem, você não precisará usar sessões. Se as mensagens precisarem ser processadas em ordem, use sessões. A mesma ID de sessão deve ser definida em mensagens que são associadas, que podem ser as mensagens 1, 4 e 8 em um conjunto e 2, 3 e 6 em outro conjunto.

Expiração da mensagem.

Para filas habilitadas para sessão ou assinaturas de tópicos, as mensagens são bloqueadas no nível da sessão. Se a vida útil (TTL) de qualquer uma das mensagens expirar, todas as mensagens relacionadas a essa sessão serão descartadas ou com letras mortas, com base na letra morta habilitada na configuração de expiração de mensagens na entidade. Em outras palavras, se houver uma única mensagem na sessão que tenha passado o TTL, todas as mensagens na sessão expirarão. As mensagens expirarão somente se houver um ouvinte ativo. Para obter mais informações, consulte Expiração da mensagem.

Próximas etapas

Você pode habilitar sessões de mensagens ao criar uma fila usando o portal do Azure, o PowerShell, a CLI, modelo do ARM, o .NET, o Java, o Python e o JavaScript. Para obter mais informações, confira Habilitar sessões de mensagens.

Experimente os exemplos no idioma de sua escolha para explorar os recursos do Barramento de Serviço do Azure.