Gatilho de Fila

Concluído

Uma fila de mensagens é um componente de software usado para lidar com mensagens entre processos, threads ou aplicativos. Uma fila pode armazenar uma mensagem e as funções de trabalho podem buscar a mensagem quando for um bom momento.

Na nuvem, as filas de mensagens podem gerar eventos com um conteúdo. Um serviço como o Azure Functions pode escutar essa mensagem e executar seu código quando uma mensagem é publicada.

Trabalhar com filas de mensagens

Para que uma função do Azure possa consumir uma mensagem de uma fila de mensagens, ela precisa de um gatilho e, possivelmente, de uma associação.

Uma função do Azure precisa escutar uma fila específica para que seu código seja disparado quando uma nova mensagem for publicada nessa fila. Para configurar um gatilho, você precisa fornecer as credenciais apropriadas para que o código do gatilho saiba como se conectar à fila de mensagens. Você cria uma entrada no arquivo function.json para a função que está escutando a fila. No elemento bindings, especifique essas propriedades em uma entrada:

Propriedade Valor
name Um nome que você pode consultar no código
type queueTrigger
direction in
queueName Como a fila é chamada
connection Uma variável de configuração em local.settings.json

Uma entrada de exemplo pode ser definida desta forma:

{
    "name": "myQueueItem",
    "type": "queueTrigger",
    "direction": "in",
    "queueName": "messages-incoming",
    "connection": "AzureWebJobsStorage"
  }

Se essa fila residir em uma conta de armazenamento, o valor AzureWebJobsStorage será o valor da cadeia de conexão.

Você não precisa estritamente de uma associação ao consumir uma mensagem de uma fila. No entanto, se você quiser gravar em uma fila, será necessária uma associação de saída. Com essa associação, você obterá uma referência à fila pretendida.

Observação

Atualmente, somente as vinculações de saída têm suporte para filas.

Desenvolver localmente

Como desenvolvedor, você deseja ciclos curtos de comentários. Você também deseja garantir que sua experiência de desenvolvimento seja a mais próxima possível de um ambiente de produção. Uma maneira de atingir esses dois objetivos é usando um emulador de fila.

Um emulador de fila permite que você simule mensagens reais de fila que sua função do Azure responderá. Para usar o emulador:

  1. Instale o emulador. Pesquise Azurite no Visual Studio Code, ou faça o download da extensão do Azurite.

  2. Para usar a funcionalidade do emulador, inicie-a selecionando Azure: Iniciar Serviço de Fila na paleta de comandos.

    A execução desse comando inicia um ouvinte chamado Gerenciador de Armazenamento do Azure, que outro aplicativo pode detectar. O Gerenciador de Armazenamento é um aplicativo cliente que permite navegar pelos recursos de nuvem e usar a funcionalidade do emulador.

  3. Baixe o Gerenciador de Armazenamento do Microsoft Azure. Em seguida, abra o aplicativo e você verá a seguinte indicação de que o emulador está funcionando:

    Screenshot that shows the emulator in Azure Storage Explorer.

  4. Crie uma fila no emulador. Você usará essa fila como parte da configuração do ponto de extremidade da função. Clicando com o botão direito do mouse no elemento fila, você pode criar uma nova fila.

  5. Para garantir que seu aplicativo do Functions use o emulador, você precisa definir corretamente a cadeia de conexão. Abra local.settings.json, localize o elemento AzureWebJobsStorage e dê a ele o valor "UseDevelopmentStorage=true".

    Observação

    Lembre-se de definir essa propriedade de forma diferente à medida que você se move para a nuvem. Ele deve apontar para um recurso real no Azure quando estiver em produção.

Compilar a função

Agora você tem um emulador local definido, com uma fila nele. Você também configurou seu projeto para apontar para o emulador local. Agora você precisa criar uma função para manipular um gatilho de fila.

Criar um ponto de extremidade de função

Você está pronto para criar uma função que possa manipular mensagens de fila de entrada. Crie uma pasta para sua função e nomeie-a, por exemplo, como queueTrigger. Em seguida, crie o arquivo function.json e dê a ele o seguinte conteúdo:

{
  "bindings": [{
    "name" "queueItem",
    "type": "queueTrigger",
    "direction": "in",
    "queueName" : "items",
    "connection": "AzureWebJobsStorage"
  }]
}

O valor do elemento name é importante, pois você o consultará posteriormente em seu código para analisar os dados de entrada da fila. Ele precisa ser do tipo queueTrigger para que a fila seja acionada quando há uma nova mensagem.

O elemento queueName identifica exclusivamente com qual fila você está interagindo. Tudo o que você inserir aqui precisa corresponder a como você chama a fila no emulador, ou a como você chamará posteriormente sua fila real no Azure.

O elemento connection aponta para o valor do elemento AzureWebJobsStorage em local.settings.json.

Manipular uma mensagem da fila

Para manipular uma mensagem da fila de entrada, você precisa escrever um código que possa analisar a mensagem que você precisa. Nesse ponto, você pode decidir o que fazer em seguida. Por exemplo, você pode iniciar uma solicitação da Web, colocar essa mensagem em outra fila ou enviá-la para um banco de dados.

Configurar uma rota

Você precisa de uma rota para manipular solicitações de entrada. O Azure Functions manipulará solicitações para uma fila na raiz. Quando você configurar uma rota da forma descrita a seguir, sua solicitação será invocada como http://localhost:<port>/queueTrigger:

http.HandleFunc("/queueTrigger", handleQueueTrigger)

Decodificar uma solicitação

Quando a mensagem da fila é enviada para você, ela tem esta forma:

{
  "Data": {
    "queueItem": "your message"
  },
  "Metadata": {
    "DequeueCount": 1,
    "ExpirationTime": "2019-10-16T17:58:31+00:00",
    "Id": "800ae4b3-bdd2-4c08-badd-f08e5a34b865",
    "InsertionTime": "2019-10-09T17:58:31+00:00",
    "NextVisibleTime": "2019-10-09T18:08:32+00:00",
    "PopReceipt": "AgAAAAMAAAAAAAAAAgtnj8x+1QE=",
    "sys": {
      "MethodName": "QueueTrigger",
      "UtcNow": "2019-10-09T17:58:32.2205399Z",
      "RandGuid": "24ad4c06-24ad-4e5b-8294-3da9714877e9"
    }
  }
}

Como parte da decodificação dessa solicitação de entrada, você precisa de uma estrutura auxiliar que modele a mensagem anterior. Ele deverá ser parecido com:

type InvokeRequest {
   Data map[string]json.RawMessage
   Metadata map[string]interface{}
}

Comece a escrever o código para fazer essa solicitação de entrada e decodificá-la:

func handleQueueTrigger(w http.ResponseWrite, r *http.Request) {
   var invokeRequest InvokeRequest
   d := json.NewDecoder(r.Body)
   d.Decode(&invokeRequest)
}

Agora você está em um ponto em que a solicitação foi decodificada, mas você precisa analisar a própria mensagem da fila.

Analisar uma mensagem da fila

Depois que a solicitação for decodificada, a mensagem da fila poderá ser recuperada da solicitação na propriedade Data. Você também precisa consultar a mensagem pelo valor da propriedade name que você configurou no arquivo function.json. O código para recuperar a mensagem é uma linha como esta:

invokeRequest.Data["queueItem"]

Como você precisa ser capaz de ler essa mensagem em texto claro, você usará uma biblioteca JSON e a analisará. A biblioteca JSON usará um método Unmarshal() que utiliza dois parâmetros: a mensagem a ser analisada e a variável na qual colocá-la. Então, seu código precisa ter a seguinte aparência:

var parsedMessage string
json.Unmarshal(invokeRequest.Data["queueItem"], &parsedMessage)

Neste ponto, o parsedMessage contém sua mensagem. Se você quiser imprimi-lo no console, use o seguinte código:

fmt.Println(parsedMessage) // your message

Observação

Se sua mensagem for algo mais avançado do que uma cadeia de caracteres, então o parsedMessage precisará ter uma estrutura que corresponda à forma para a qual o queueMessage está apontando.

Disparar uma mensagem

Para testar seu aplicativo, você pode usar o Gerenciador de Armazenamento do Azure. No painel direito da ferramenta, selecione o botão Adicionar Mensagem para criar uma mensagem na fila.

Screenshot that shows the button for adding a message on the queue.

Se você tiver seu aplicativo do Functions e ele estiver em execução neste momento, ele irá disparar a associação e seu código será invocado.