Partilhar via


Guia de início rápido: criar um aplicativo de funções duráveis que usa o provedor de armazenamento MSSQL

Use Durable Functions, um recurso do Azure Functions, para escrever funções com monitoração de estado em um ambiente sem servidor. O Durable Functions gerencia o estado, os pontos de verificação e as reinicializações em seu aplicativo.

O Durable Functions suporta vários provedores de armazenamento, também conhecidos como back-ends, para armazenar orquestração e estado de tempo de execução da entidade. Neste início rápido, você cria um aplicativo Durable Functions para usar o provedor de armazenamento Microsoft SQL Server (MSSQL) usando o Visual Studio Code.

Este guia de início rápido cria um aplicativo .NET (modelo isolado) para fins de demonstração. O conteúdo fornecido neste artigo aplica-se a outros idiomas de maneiras semelhantes.

Nota

  • O back-end MSSQL foi projetado para maximizar a portabilidade do aplicativo e o controle sobre seus dados. Ele usa o Microsoft SQL Server para manter todos os dados do hub de tarefas para que os usuários obtenham os benefícios de uma infraestrutura moderna de sistema de gerenciamento de banco de dados (DBMS) de nível empresarial. Para saber mais sobre quando usar o provedor de armazenamento MSSQL, consulte a visão geral dos provedores de armazenamento.

  • Atualmente, não há suporte para a migração de dados do hub de tarefas entre provedores de armazenamento. Os aplicativos de função que têm dados de tempo de execução existentes começam com um hub de tarefas novo e vazio depois de alternarem para o back-end do MSSQL. Da mesma forma, o conteúdo do hub de tarefas criado usando o MSSQL não poderá ser preservado se você alternar para um provedor de armazenamento diferente.

Pré-requisitos

Para concluir este arranque rápido, necessita de:

Criar um projeto das Funções do Azure

No Visual Studio Code, crie um projeto local do Azure Functions.

  1. No menu Exibir, selecione Paleta de comandos (ou selecione Ctrl+Shift+P).

  2. No prompt (>), insira e selecione Azure Functions: Create New Project.

    Captura de tela que mostra o comando para criar um projeto Functions.

  3. Selecione Procurar. Na caixa de diálogo Selecionar pasta, vá para uma pasta a ser usada para seu projeto e escolha Selecionar.

  4. Nos prompts, selecione ou insira os seguintes valores:

    Pronta Ação Descrição
    Selecione um idioma para seu projeto de aplicativo de função Selecione .NET Cria um projeto local do C# Functions
    Selecione um tempo de execução do .NET Selecione .NET 8.0 isolado. Cria um projeto do Functions que dá suporte ao .NET 8 em execução em um processo de trabalho isolado e ao Azure Functions Runtime 4.0.
    Selecione um modelo para a primeira função do seu projeto Selecione Orquestração de funções duráveis. Cria uma orquestração de funções duráveis.
    Escolha um tipo de armazenamento durável Selecione MSSQL. Seleciona o provedor de armazenamento MSSQL.
    Fornecer um nome de função Digite HelloOrchestration. Um nome para a função de orquestração.
    Fornecer um namespace Digite Company.Function. Um namespace para a classe gerada.
    Selecione como gostaria de abrir o seu projeto Selecione Abrir na janela atual. Abre o Visual Studio Code na pasta selecionada.

O Visual Studio Code instala as Ferramentas Principais do Azure Functions se for necessário para criar o projeto. Ele também cria um projeto de aplicativo de função em uma pasta. Este projeto contém os arquivos de configuração host.json e local.settings.json .

Outro arquivo, HelloOrchestration.cs, contém os blocos de construção básicos de um aplicativo Durable Functions:

Método Descrição
HelloOrchestration Define a orquestração do aplicativo Durable Functions. Nesse caso, a orquestração é iniciada, cria uma lista e, em seguida, adiciona o resultado de três chamadas de funções à lista. Quando as três chamadas de função terminam, ele retorna a lista.
SayHello Um aplicativo de função simples que retorna olá. Esta função contém a lógica de negócios que é orquestrada.
HelloOrchestration_HttpStart Uma função acionada por HTTP que inicia uma instância da orquestração e retorna uma resposta de status de verificação.

Para obter mais informações sobre essas funções, consulte Tipos e recursos de funções duráveis.

Configurar a sua base de dados

Nota

Se você já tiver um banco de dados compatível com MSSQL, poderá ignorar esta seção e a próxima seção sobre como configurar um banco de dados local baseado no Docker.

Como o back-end MSSQL foi projetado para portabilidade, você tem várias opções para configurar seu banco de dados de suporte. Por exemplo, você pode configurar uma instância local do SQL Server, usar uma instância totalmente gerenciada do Banco de Dados SQL do Azure ou usar qualquer outra opção de hospedagem compatível com o SQL Server.

Você também pode fazer desenvolvimento local offline usando o SQL Server Express em seu computador Windows local ou usando uma imagem do SQL Server Docker em execução em um contêiner do Docker.

Este guia de início rápido se concentra no uso de uma imagem do SQL Server Docker.

Configurar sua instância local do SQL Server baseada no Docker

Use os seguintes comandos do PowerShell para configurar um banco de dados SQL Server local no Docker. Você pode instalar o PowerShell no Windows, macOS ou Linux.

# primary parameters
$pw        = "yourStrong(!)Password"
$edition   = "Developer"
$port      = 1433
$tag       = "2019-latest"
$dbname    = "DurableDB"
$collation = "Latin1_General_100_BIN2_UTF8"

# pull the image from the Microsoft container registry
docker pull mcr.microsoft.com/mssql/server:$tag

# run the image and provide some basic setup parameters
docker run --name mssql-server -e 'ACCEPT_EULA=Y' -e "MSSQL_SA_PASSWORD=$pw" -e "MSSQL_PID=$edition" -p ${port}:1433 -d mcr.microsoft.com/mssql/server:$tag

# wait a few seconds for the container to start...

# create the database with strict binary collation
docker exec -it mssql-server /opt/mssql-tools/bin/sqlcmd -S . -U sa -P "$pw" -Q "CREATE DATABASE [$dbname] COLLATE $collation"

# if sqlcmd is in the mssql-tools18 folder
# docker exec -it mssql-server /opt/mssql-tools18/bin/sqlcmd -C -S . -U sa -P "$pw" -Q "CREATE DATABASE [$dbname] COLLATE $collation"

Agora você deve ter um SQL Server local em execução no Docker e escutando na porta 1443. Se a porta 1443 entrar em conflito com outro serviço, execute novamente esses comandos depois de alterar a variável $port para um valor diferente.

Para validar a instalação do banco de dados, consulte o novo banco de dados SQL:

docker exec -it mssql-server /opt/mssql-tools/bin/sqlcmd -S . -U sa -P "$pw" -Q "SELECT name FROM sys.databases"

Se a configuração do banco de dados for concluída com êxito, o nome do seu banco de dados (por exemplo, DurableDB) aparecerá na saída da linha de comando:

name

--------------------------------------------------------------
master

tempdb

model

msdb

DurableDB

Nota

Para parar e excluir um contêiner em execução, você pode usar docker stop <containerName> e docker rm <containerName> respectivamente. Você pode usar esses comandos para recriar seu contêiner e parar o contêiner quando terminar este início rápido. Para obter mais assistência, execute docker --help.

Solução de problemas

Se você se deparar com "Error response from daemon: OCI runtime exec failed" ao executar docker exec para criar o banco de dados, é provável que a pasta /opt/mssql-tools/bin/sqlcmd não exista. Abra o Docker Desktop, selecione seu contêiner do SQL Server Docker, selecione Arquivos e procure a pasta mssql-tools. Verifique se esta pasta tem um nome diferente, como /opt/mssql-tools18/bin/sqlcmd. Atualize o comando em conformidade.

No ODBC Driver 18 para SQL Server, a opção Criptografar conexão é definida como true por padrão. Se te deparares com "error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed:self signed certificate" ao executares docker exec para realizar operações de base de dados, adiciona -C, que é equivalente à opção TRUSTSERVERCERTIFICATE = true ADO.net.

Adicionar cadeia de conexão SQL ao local.settings.json

O back-end MSSQL precisa de uma cadeia de conexão para acessar seu banco de dados. Como obter uma cadeia de conexão depende principalmente do seu provedor de servidor MSSQL específico.

Se você usar os comandos anteriores do Docker sem alterar nenhum parâmetro, sua cadeia de conexão será:

Server=localhost,1433;Database=DurableDB;User Id=sa;Password=yourStrong(!)Password;

No local.settings.json, atribua a cadeia de conexão da instância do SQL Server baseada no Docker a SQLDB_Connection. Essa variável foi adicionada pelo Visual Studio Code quando você escolheu MSSQL como back-end para seu aplicativo Durable Functions:

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true", 
    "SQLDB_Connection": "Server=localhost,1433;Database=DurableDB;User Id=sa;Password=yourStrong(!)Password;",
    "FUNCTIONS_WORKER_RUNTIME": "<dependent on your programming language>"
  }
}

Teste localmente

Abra uma janela de terminal na pasta raiz do aplicativo e execute azurite start. Azurite é o emulador de Armazenamento do Azure, que é necessário para executar qualquer aplicativo Function.

Abra outra janela de terminal na pasta raiz do seu aplicativo e inicie o aplicativo Função executando func host start.

  1. Na janela do terminal, copie o endereço de URL da função acionada por HTTP.

    Captura de ecrã da janela de saída local do Azure.

  2. Use uma ferramenta de teste HTTP para enviar uma solicitação HTTP POST para o ponto de extremidade URL.

    A resposta é o resultado inicial da função HTTP. Ele permite que você saiba que a orquestração de funções duráveis foi iniciada com êxito. Ainda não exibe o resultado final da orquestração. A resposta inclui alguns URLs úteis.

  3. Copie o valor do URL para statusQueryGetUri, cole-o na barra de endereço do navegador e execute a solicitação. Como alternativa, você também pode continuar a usar a ferramenta de teste HTTP para emitir a solicitação GET.

    A solicitação consulta a instância de orquestração para obter o status. Você deve ver que a instância terminou e que inclui as saídas ou resultados do aplicativo Durable Functions, como neste exemplo:

    {
        "name":"HelloCities",
        "instanceId":"7f99f9474a6641438e5c7169b7ecb3f2",
        "runtimeStatus":"Completed",
        "input":null,
        "customStatus":null,
        "output":"Hello, Tokyo! Hello, London! Hello, Seattle!",
        "createdTime":"2023-01-31T18:48:49Z",
        "lastUpdatedTime":"2023-01-31T18:48:56Z"
    }
    

Executar seu aplicativo no Azure

Para executar seu aplicativo no Azure, você precisa criar vários recursos. Para uma limpeza conveniente mais tarde, crie todos os recursos no mesmo grupo de recursos.

Criar uma Base de Dados SQL do Azure

Nota

Se você já tiver um banco de dados SQL do Azure ou outra instância do SQL Server acessível publicamente que gostaria de usar, vá para a próxima seção.

Abster-se de habilitar a configuração Permitir que os serviços e recursos do Azure acessem este servidor [SQL] para cenários de produção. Aplicativos reais devem implementar abordagens mais seguras, como restrições de firewall mais fortes ou configurações de rede virtual.

No portal do Azure, você pode criar um banco de dados SQL do Azure. Durante a criação:

  • Habilitar os serviços e recursos do Azure para acessar este servidor (em Rede)
  • Defina o valor para Agrupamento de banco de dados (em Configurações adicionais) como Latin1_General_100_BIN2_UTF8.

Criar um aplicativo do Azure Functions e recursos de suporte

  1. Abra uma janela de terminal e entre no Azure:

    az login
    
  2. Crie os seguintes recursos no mesmo grupo de recursos e região que o banco de dados SQL:

    • Uma conta de armazenamento de uso geral, que é usada para armazenar dados importantes do aplicativo, como o próprio código do aplicativo. Os nomes das contas de armazenamento devem conter de três a 24 caracteres, números e letras minúsculas apenas.
    • Plano premium de aplicação funcional
    • Um aplicativo de função
    # Variables
    location=<REGION>
    resourceGroup=<RESOURCE_GROUP_NAME>
    storage=<STORAGE_NAME>
    planName=<PREMIUM_PLAN_NAME>
    functionApp=<APP_NAME>
    skuStorage="Standard_LRS"
    skuPlan="EP1"
    functionsVersion="4"
    
    # Create an Azure storage account
    echo "Creating $storage"
    az storage account create --name $storage --location "$location" --resource-group $resourceGroup --sku $skuStorage --allow-blob-public-access false
    
    # Create a premium plan
    echo "Creating $premiumPlan"
    az functionapp plan create --name $planName --resource-group $resourceGroup --location "$location" --sku $skuPlan
    
    # Create a function app hosted in the premium plan
    echo "Creating $functionApp"
    az functionapp create --name $functionApp --storage-account $storage --plan $planName --resource-group $resourceGroup --functions-version $functionsVersion
    

Criar uma identidade gerenciada do Azure

As identidades gerenciadas tornam seu aplicativo mais seguro, eliminando segredos de seu aplicativo, como credenciais nas cadeias de conexão. Você pode escolher entre identidade gerenciada atribuída pelo sistema e atribuída pelo usuário. Este início rápido demonstra a configuração da identidade gerenciada atribuída pelo usuário, que é a opção recomendada, pois não está vinculada ao ciclo de vida do aplicativo.

Os comandos a seguir criam o recurso de identidade e o atribuem ao aplicativo:

# Variables
subscription=<SUBSCRIPTION_ID>
identity=<IDENTITY_NAME>

# Create a managed identity resource
echo "Creating $identity"
az identity create -g $resourceGroup -n $identity --location "$location"

# Construct the identity resource ID 
resourceId="/subscriptions/$subscription/resourceGroups/$resourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/$identity"

# Assign the identity to the Azure Functions app
echo "Assigning $identity to app"
az functionapp identity assign -g $resourceGroup -n $functionApp --identities "$resourceId"

# Get the identity's ClientId and PrincipalId (also called ObjectId) for a later step. 
clientId=$(az identity show --name $identity --resource-group $resourceGroup --query 'clientId' --output tsv)

principalId=$(az identity show --name $identity --resource-group $resourceGroup --query 'principalId' --output tsv)

Conceder acesso ao Armazenamento do Azure e ao Banco de Dados SQL do Azure

Armazenamento do Azure

Atribua a função Proprietário de Dados de Blob de Armazenamento para acessar a conta de armazenamento.

# Set the scope of the access
scope="/subscriptions/$subscription/resourceGroups/$resourceGroup/providers/Microsoft.Storage/storageAccounts/$storage"

# Assign the role
echo "Assign Storage Blob Data Owner role to identity"
az role assignment create --assignee "$clientId" --role "Storage Blob Data Owner" --scope "$scope"

Base de Dados SQL do Azure

Nota

Não há suporte para autenticação no banco de dados SQL do Azure usando identidade gerenciada ao hospedar um aplicativo Durable Functions no plano Flex Consumption. Se a sua aplicação estiver alojada no plano Flex Consumption, avance para a secção definir definições da aplicação .

  1. Comece definindo sua identidade de desenvolvedor como administrador do banco de dados.

    O cessionário é a sua identidade, por isso mude para o seu e-mail:

    assignee=$(az ad user show --id "someone@example.com" --query "id" --output tsv)
    

    Defina o cessionário como administrador da base de dados SQL do Azure:

    az sql server ad-admin create --resource-group $resourceGroup --server-name <SQL_SERVER_NAME> --display-name ADMIN --object-id "$assignee"
    
  2. Conecte-se ao banco de dados SQL criado anteriormente usando ferramentas como o Azure Data Studio ou o SQL Management Server Studio. Ou você pode executar o seguinte comando SQLCMD para se conectar:

    sqlcmd -S <SQL_SERVER_NAME>.database.windows.net -d <DATABASE_NAME> -U <someone@example.com> -P "ACCOUNT_PASSWORD" -G -l 30
    

    Conceda acesso à sua identidade db_owner executando a seguinte consulta no banco de dados. O IDENTITY_OBJECT_ID é o PrincipalId da etapa de criação de identidade.

    CREATE USER "<IDENTITY_NAME>" FROM EXTERNAL PROVIDER With OBJECT_ID='<IDENTITY_OBJECT_ID>'
    ALTER ROLE db_owner ADD MEMBER "<IDENTITY_NAME>";
    GO
    
  3. Conecte-se ao master banco de dados e conceda à sua identidade dbmanager acesso:

    CREATE USER "<IDENTITY_NAME>" FROM EXTERNAL PROVIDER With OBJECT_ID='<IDENTITY_OBJECT_ID>'
    ALTER ROLE dbmanager ADD MEMBER "<IDENTITY_NAME>";
    GO
    

Definir as configurações necessárias do aplicativo

Você precisa adicionar as seguintes configurações do aplicativo ao seu aplicativo:

  • AzureWebJobsStorage__accountName: Nome da conta de Armazenamento do Azure
  • AzureWebJobsStorage__clientId: ClientId da identidade gerenciada
  • AzureWebJobsStorage__credential: Tipo de credencial, que é managedidentity
  • SQLDB_Connection: Cadeia de conexão do banco de dados SQL

Se você estiver usando a identidade gerenciada atribuída pelo usuário para autenticar no banco de dados SQL, a cadeia de conexão deverá ter a seguinte aparência:

dbserver=<SQL_SERVER_NAME>
sqlDB=<SQL_DB_NAME>
clientId=<IDENTITY_CLIENT_ID>

sqlconnstr="Server=tcp:$dbserver.database.windows.net,1433;Initial Catalog=$sqlDB;Persist Security Info=False;User ID=$clientId;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Authentication='Active Directory Managed Identity';"

Para aplicativos Flex Consumption, use uma cadeia de conexão para autenticar por enquanto. Você pode encontrá-lo acessando o recurso do banco de dados SQL no portal do Azure, navegando até a guia Configurações e clicando em Cadeias de conexão:

Captura de tela mostrando a cadeia de conexão do banco de dados.

A cadeia de conexão deve ter este formato:

dbserver=<SQL_SERVER_NAME>
sqlDB=<SQL_DB_NAME>
username=<DB_USER_LOGIN>
password=<DB_USER_PASSWORD>

sqlconnstr="Server=tcp:$dbserver.database.windows.net,1433;Initial Catalog=$sqlDB;Persist Security Info=False;User ID=$username;Password=$password;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"

Execute o seguinte comando para definir as configurações:

az functionapp config appsettings set --name $functionApp --resource-group $resourceGroup --settings AzureWebJobsStorage__accountName="$storage" AzureWebJobsStorage__clientId="$clientId" AzureWebJobsStorage__credential="managedidentity" SQLDB_Connection=$sqlconnstr

Exclua a configuração existente AzureWebJobsStorage :

az functionapp config appsettings delete --name $functionApp --resource-group $resourceGroup --setting-names "AzureWebJobsStorage"

Implantar o projeto local no Azure e testar

Finalmente, em sua pasta de projeto raiz, implante seu aplicativo no Azure executando:

func azure functionapp publish $functionApp

Após a conclusão da implantação, execute o seguinte para obter a URL de gatilho HTTP:

az functionapp function list --resource-group $resourceGroup --name $functionApp  --query '[].{Function:name, URL:invokeUrlTemplate}' --output json

Teste exatamente como fez durante o desenvolvimento local com uma ferramenta de teste HTTP.

Você também pode validar se o back-end MSSQL está configurado corretamente consultando o banco de dados para obter dados do hub de tarefas.

Por exemplo, você pode consultar suas instâncias de orquestração no painel de visão geral do banco de dados SQL. Selecione Editor de Consultas, autentique e execute a seguinte consulta:

SELECT TOP 5 InstanceID, RuntimeStatus, CreatedTime, CompletedTime FROM dt.Instances

Depois de executar um orquestrador simples, você verá pelo menos um resultado, conforme mostrado neste exemplo:

Captura de tela que mostra os resultados do Editor de Consultas SQL do Azure para a consulta SQL.

Próximos passos