Partilhar via


Tutorial: Criar um cache write-behind usando o Azure Functions e o Cache do Azure para Redis

O objetivo deste tutorial é usar uma instância do Cache Redis do Azure como um cache write-behind. O padrão write-behind neste tutorial mostra como as gravações no gatilho de cache correspondentes gravam em um banco de dados SQL (uma instância do serviço Banco de Dados SQL do Azure).

Use o gatilho Redis para o Azure Functions para implementar essa funcionalidade. Nesse cenário, você verá como usar o Cache Redis do Azure para armazenar informações de inventário e preços, enquanto faz backup dessas informações em um banco de dados SQL.

Cada novo item ou novo preço gravado no cache é então refletido em uma tabela SQL no banco de dados.

Neste tutorial, irá aprender a:

  • Configure um banco de dados, um gatilho e cadeias de conexão.
  • Valide se os gatilhos estão funcionando.
  • Implante código em um aplicativo de função.

Pré-requisitos

Criar e configurar um novo banco de dados SQL

O banco de dados SQL é o banco de dados de suporte para este exemplo. Você pode criar um banco de dados SQL por meio do portal do Azure ou por meio do seu método preferido de automação.

Para obter mais informações sobre como criar um banco de dados SQL, consulte Guia de início rápido: criar um único banco de dados - Banco de Dados SQL do Azure.

Este exemplo usa o portal:

  1. Insira um nome de banco de dados e selecione Criar novo para criar um novo servidor para armazenar o banco de dados.

    Captura de ecrã da criação de um recurso SQL do Azure.

  2. Selecione Usar autenticação SQL e insira uma entrada e senha de administrador. Lembre-se dessas credenciais ou escreva-as. Quando estiver implantando um servidor em produção, use a autenticação do Microsoft Entra.

    Captura de ecrã das informações de autenticação de um recurso SQL do Azure.

  3. Vá para a guia Rede e escolha Ponto de extremidade público como um método de conexão. Selecione Sim para ambas as regras de firewall exibidas. Este ponto de extremidade permite o acesso a partir do seu aplicativo de função do Azure.

    Captura de tela da configuração de rede para um recurso SQL do Azure.

  4. Após a conclusão da validação, selecione Rever + criar e, em seguida, Criar. O banco de dados SQL começa a ser implantado.

  5. Após a conclusão da implantação, vá para o recurso no portal do Azure e selecione a guia Editor de consultas . Crie uma nova tabela chamada inventário que contém os dados que você gravará nela. Use o seguinte comando SQL para criar uma nova tabela com dois campos:

    • ItemName lista o nome de cada item.
    • Price armazena o preço do item.
    CREATE TABLE inventory (
        ItemName varchar(255),
        Price decimal(18,2)
        );
    

    Captura de ecrã a mostrar a criação de uma tabela no Editor de Consultas de um recurso SQL do Azure.

  6. Depois que o comando terminar a execução, expanda a pasta Tabelas e verifique se a nova tabela foi criada.

Configurar o gatilho Redis

Primeiro, faça uma cópia do mesmo projeto VS Code que você usou no tutorial anterior. Copie a pasta do tutorial anterior com um novo nome, como RedisWriteBehindTrigger, e abra-a no VS Code.

Em segundo lugar, exclua os arquivos RedisBindings.cs e RedisTriggers.cs .

Neste exemplo, você usa o gatilho pub/sub para acionar notificaçõeskeyevent. Os objetivos do exemplo são:

  • Acione sempre que ocorrer um SET evento. Um SET evento acontece quando novas chaves são gravadas na instância de cache ou o valor de uma chave é alterado.
  • Depois que um SET evento for acionado, acesse a instância de cache para localizar o valor da nova chave.
  • Determine se a chave já existe na tabela de inventário no banco de dados SQL.
    • Em caso afirmativo, atualize o valor dessa chave.
    • Caso contrário, escreva uma nova linha com a chave e seu valor.

Para configurar o gatilho:

  1. Importe o pacote NuGet para habilitar a System.Data.SqlClient comunicação com o banco de dados SQL. Vá para o terminal VS Code e use o seguinte comando:

      dotnet add package System.Data.SqlClient
    
  2. Crie um novo arquivo chamado RedisFunction.cs. Certifique-se de que eliminou os ficheiros RedisBindings.cs e RedisTriggers.cs .

  3. Copie e cole o seguinte código em RedisFunction.cs para substituir o código existente:

using Microsoft.Extensions.Logging;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Extensions.Redis;
using System.Data.SqlClient;

public class WriteBehindDemo
{
    private readonly ILogger<WriteBehindDemo> logger;

    public WriteBehindDemo(ILogger<WriteBehindDemo> logger)
    {
        this.logger = logger;
    }
    
    public string SQLAddress = System.Environment.GetEnvironmentVariable("SQLConnectionString");

    //This example uses the PubSub trigger to listen to key events on the 'set' operation. A Redis Input binding is used to get the value of the key being set.
    [Function("WriteBehind")]
    public void WriteBehind(
        [RedisPubSubTrigger(Common.connectionString, "__keyevent@0__:set")] Common.ChannelMessage channelMessage,
        [RedisInput(Common.connectionString, "GET {Message}")] string setValue)
    {
        var key = channelMessage.Message; //The name of the key that was set
        var value = 0.0;

        //Check if the value is a number. If not, log an error and return.
        if (double.TryParse(setValue, out double result))
        {
            value = result; //The value that was set. (i.e. the price.)
            logger.LogInformation($"Key '{channelMessage.Message}' was set to value '{value}'");
        }
        else
        {
            logger.LogInformation($"Invalid input for key '{key}'. A number is expected.");
            return;
        }        

        // Define the name of the table you created and the column names.
        String tableName = "dbo.inventory";
        String column1Value = "ItemName";
        String column2Value = "Price";        
        
        logger.LogInformation($" '{SQLAddress}'");
        using (SqlConnection connection = new SqlConnection(SQLAddress))
            {
                connection.Open();
                using (SqlCommand command = new SqlCommand())
                {
                    command.Connection = connection;

                    //Form the SQL query to update the database. In practice, you would want to use a parameterized query to prevent SQL injection attacks.
                    //An example query would be something like "UPDATE dbo.inventory SET Price = 1.75 WHERE ItemName = 'Apple'".
                    command.CommandText = "UPDATE " + tableName + " SET " + column2Value + " = " + value + " WHERE " + column1Value + " = '" + key + "'";
                    int rowsAffected = command.ExecuteNonQuery(); //The query execution returns the number of rows affected by the query. If the key doesn't exist, it will return 0.

                    if (rowsAffected == 0) //If key doesn't exist, add it to the database
                 {
                         //Form the SQL query to update the database. In practice, you would want to use a parameterized query to prevent SQL injection attacks.
                         //An example query would be something like "INSERT INTO dbo.inventory (ItemName, Price) VALUES ('Bread', '2.55')".
                        command.CommandText = "INSERT INTO " + tableName + " (" + column1Value + ", " + column2Value + ") VALUES ('" + key + "', '" + value + "')";
                        command.ExecuteNonQuery();

                        logger.LogInformation($"Item " + key + " has been added to the database with price " + value + "");
                    }

                    else {
                        logger.LogInformation($"Item " + key + " has been updated to price " + value + "");
                    }
                }
                connection.Close();
            }

            //Log the time that the function was executed.
            logger.LogInformation($"C# Redis trigger function executed at: {DateTime.Now}");
    }
}

Importante

Este exemplo é simplificado para o tutorial. Para uso em produção, recomendamos que você use consultas SQL parametrizadas para evitar ataques de injeção de SQL.

Configurar cadeias de ligação

Você precisa atualizar o arquivo local.settings.json para incluir a cadeia de conexão para seu banco de dados SQL. Adicione uma entrada na Values seção para SQLConnectionString. O ficheiro deverá ter um aspeto semelhante ao seguinte:

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
    "redisConnectionString": "<redis-connection-string>",
    "SQLConnectionString": "<sql-connection-string>"
  }
}

Para localizar a cadeia de conexão Redis, vá para o menu de recursos no recurso Cache do Azure para Redis. Localize a cadeia de caracteres na área Chaves de acesso no menu Recurso.

Para localizar a cadeia de conexão do banco de dados SQL, vá para o menu de recursos no recurso do banco de dados SQL. Em Definições, selecione Cadeias de ligação e, em seguida, selecione o separador ADO.NET . A cadeia de caracteres está na área ADO.NET (autenticação SQL).

Você precisa inserir manualmente a senha para sua cadeia de conexão do banco de dados SQL, porque a senha não é colada automaticamente.

Importante

Este exemplo é simplificado para o tutorial. Para uso em produção, recomendamos que você use o Azure Key Vault para armazenar informações de cadeia de conexão ou use o Azure EntraID para autenticação SQL.

Compilar e executar o projeto

  1. No VS Code, vá para a guia Executar e depurar e execute o projeto.

  2. Volte para sua instância do Cache do Azure para Redis no portal do Azure e selecione o botão Console para entrar no console Redis. Tente usar alguns SET comandos:

    • SET apple 5.25
    • SET bread 2.25
    • SET apple 4.50
  3. De volta ao VS Code, os gatilhos estão sendo registrados. Para validar se os gatilhos estão funcionando:

    1. Vá para o banco de dados SQL no portal do Azure.

    2. No menu de recursos, selecione Editor de consultas.

    3. Para Nova Consulta, crie uma consulta com o seguinte comando SQL para exibir os 100 principais itens na tabela de inventário:

      SELECT TOP (100) * FROM [dbo].[inventory]
      

      Confirme se os itens gravados em sua instância do Cache Redis do Azure aparecem aqui.

    Captura de tela mostrando que as informações foram copiadas para SQL da instância de cache.

Implantar o código em seu aplicativo de função

Este tutorial baseia-se no tutorial anterior. Para obter mais informações, consulte Implantar código em uma função do Azure.

  1. No VS Code, vá para a guia Azure .

  2. Encontre a sua subscrição e expanda-a. Em seguida, localize a seção Aplicativo de função e expanda-a.

  3. Selecione e segure (ou clique com o botão direito do mouse) seu aplicativo de função e, em seguida, selecione Implantar no aplicativo de função.

Adicionar informações da cadeia de conexão

Este tutorial baseia-se no tutorial anterior. Para obter mais informações sobre o , consulte Adicionar informações de cadeia de redisConnectionStringconexão.

  1. Vá para seu aplicativo de função no portal do Azure. No menu de recursos, selecione Variáveis de ambiente.

  2. No painel Configurações do aplicativo, insira SQLConnectionString como um novo campo. Em Valor, insira sua cadeia de conexão.

  3. Selecione Aplicar.

  4. Vá para a folha Visão geral e selecione Reiniciar para reiniciar o aplicativo com as novas informações da cadeia de conexão.

Verificar a implementação

Após a conclusão da implantação, volte para sua instância do Cache Redis do Azure e use SET comandos para gravar mais valores. Confirme se eles também aparecem em seu banco de dados SQL.

Se você quiser confirmar se seu aplicativo de função está funcionando corretamente, vá para o aplicativo no portal e selecione Registrar fluxo no menu de recursos. Você deve ver os gatilhos em execução e as atualizações correspondentes sendo feitas no seu banco de dados SQL.

Se você quiser limpar a tabela do banco de dados SQL sem excluí-la, poderá usar a seguinte consulta SQL:

TRUNCATE TABLE [dbo].[inventory]

Clean up resources (Limpar recursos)

Se quiser continuar a usar os recursos criados neste artigo, mantenha o grupo de recursos.

Caso contrário, se tiver terminado os recursos, pode eliminar o grupo de recursos do Azure que criou para evitar cobranças.

Importante

A eliminação de um grupo de recursos é irreversível. Quando elimina um grupo de recursos, todos os recursos nele contidos são eliminados permanentemente. Confirme que não elimina acidentalmente o grupo de recursos ou recursos errados. Se você criou os recursos dentro de um grupo de recursos existente que contém recursos que deseja manter, poderá excluir cada recurso individualmente em vez de excluir o grupo de recursos.

Para eliminar um grupo de recursos

  1. Inicie sessão no Portal do Azure e selecione Grupos de recursos.

  2. Selecione o grupo de recursos que pretende eliminar.

    Se houver muitos grupos de recursos, use a caixa Filtrar para qualquer campo... , digite o nome do grupo de recursos criado para este artigo. Selecione o grupo de recursos na lista de resultados.

    Captura de ecrã a mostrar uma lista de grupos de recursos a eliminar no painel de trabalho.

  3. Selecione Eliminar grupo de recursos.

  4. É-lhe pedido que confirme a eliminação do grupo de recursos. Escreva o nome do grupo de recursos para confirmar e, em seguida, selecione Eliminar.

    Captura de tela mostrando um formulário que requer o nome do recurso para confirmar a exclusão.

Após alguns instantes, o grupo de recursos e todos os respetivos recursos são eliminados.

Resumo

Este tutorial e Introdução aos gatilhos do Azure Functions no Cache Redis do Azure mostram como usar o Cache do Azure para Redis para acionar aplicativos de função do Azure. Eles também mostram como usar o Cache Redis do Azure como um cache write-behind com o Banco de Dados SQL do Azure. Usar o Cache Redis do Azure com o Azure Functions é uma combinação poderosa que pode resolver muitos problemas de integração e desempenho.