Implantar e remover aplicativos usando o FabricClient


Depois que um tipo de aplicativo for empacotado, ele estará pronto para implantação em um cluster do Azure Service Fabric. A implantação envolve as três etapas a seguir:

  1. Carregue o pacote do aplicativo para o armazenamento de imagens
  2. Registar o tipo de aplicação
  3. Remover o pacote do aplicativo do armazenamento de imagens
  4. Criar a instância do aplicativo

Depois de implantar um aplicativo e executar uma instância no cluster, você pode excluir a instância do aplicativo e seu tipo de aplicativo. Remova completamente um aplicativo do cluster seguindo estas etapas:

  1. Remover (ou excluir) a instância do aplicativo em execução
  2. Cancele o registro do tipo de aplicativo se não precisar mais dele

Se você usar o Visual Studio para implantar e depurar aplicativos em seu cluster de desenvolvimento local, todas as etapas anteriores serão tratadas automaticamente por meio de um script do PowerShell. Esse script é encontrado na pasta Scripts do projeto de aplicativo. Este artigo fornece informações básicas sobre o que esse script está fazendo para que você possa fazer as mesmas operações fora do Visual Studio.

Ligar ao cluster

Conecte-se ao cluster criando uma instância FabricClient antes de executar qualquer um dos exemplos de código neste artigo. Para obter exemplos de conexão a um cluster de desenvolvimento local ou a um cluster remoto ou cluster protegido usando o Microsoft Entra ID, certificados X509 ou Windows Ative Directory, consulte Conectar-se a um cluster seguro. Para se conectar ao cluster de desenvolvimento local, execute o seguinte exemplo:

// Connect to the local cluster.
FabricClient fabricClient = new FabricClient();

Carregue o pacote de candidatura

Suponha que você crie e empacote um aplicativo chamado MyApplication no Visual Studio. Por padrão, o nome do tipo de aplicativo listado no ApplicationManifest.xml é "MyApplicationType". O pacote do aplicativo, que contém o manifesto do aplicativo necessário, manifestos de serviço e pacotes de código/configuração/dados, está localizado em C:\Users< nome> de usuário\Documents\Visual Studio 2019\Projects\MyApplication\MyApplication\pkg\Debug.

O carregamento do pacote de aplicativos o coloca em um local acessível pelos componentes internos do Service Fabric. O Service Fabric verifica o pacote do aplicativo durante o registro do pacote do aplicativo. No entanto, se você quiser verificar o pacote do aplicativo localmente (ou seja, antes de carregar), use o cmdlet Test-ServiceFabricApplicationPackage .

A API CopyApplicationPackage carrega o pacote do aplicativo para o armazenamento de imagens do cluster.

Se o pacote do aplicativo for grande e/ou tiver muitos arquivos, você poderá compactá-lo e copiá-lo para o armazenamento de imagens usando o PowerShell. A compactação reduz o tamanho e o número de arquivos.

Consulte Compreender a cadeia de conexão do armazenamento de imagens para obter informações complementares sobre o armazenamento de imagens e a cadeia de conexão do armazenamento de imagens.

Registar o pacote de candidaturas

O tipo e a versão do aplicativo declarados no manifesto do aplicativo ficam disponíveis para uso quando o pacote do aplicativo é registrado. O sistema lê o pacote carregado na etapa anterior, verifica o pacote, processa o conteúdo do pacote e copia o pacote processado para um local interno do sistema.

A API ProvisionApplicationAsync registra o tipo de aplicativo no cluster e o disponibiliza para implantação.

A API GetApplicationTypeListAsync fornece informações sobre todos os tipos de aplicativos registrados com êxito. Você pode usar essa API para determinar quando o registro é concluído.

Remover um pacote de aplicativo do armazenamento de imagens

É recomendável remover o pacote do aplicativo depois que o aplicativo for registrado com êxito. A exclusão de pacotes de aplicativos do armazenamento de imagens libera recursos do sistema. Manter pacotes de aplicativos não utilizados consome armazenamento em disco e leva a problemas de desempenho do aplicativo. Exclua o pacote do aplicativo do armazenamento de imagens usando a API RemoveApplicationPackage .

Criar uma instância de aplicativo

Você pode instanciar um aplicativo de qualquer tipo de aplicativo que tenha sido registrado com êxito usando a API CreateApplicationAsync . O nome de cada aplicativo deve começar com o esquema "fabric:" e deve ser exclusivo para cada instância do aplicativo (dentro de um cluster). Todos os serviços padrão definidos no manifesto do aplicativo do tipo de aplicativo de destino também são criados.

Várias instâncias de aplicativo podem ser criadas para qualquer versão de um tipo de aplicativo registrado. Cada instância do aplicativo é executada isoladamente, com seu próprio diretório de trabalho e conjunto de processos.

Para ver quais aplicativos e serviços nomeados estão em execução no cluster, execute as APIs GetApplicationListAsync e GetServiceListAsync .

Criar uma instância de serviço

Você pode instanciar um serviço de um tipo de serviço usando a API CreateServiceAsync . Se o serviço for declarado como um serviço padrão no manifesto do aplicativo, o serviço será instanciado quando o aplicativo for instanciado. Chamar a API CreateServiceAsync para um serviço que já está instanciado retornará uma exceção do tipo FabricException. A exceção conterá um código de erro com um valor de FabricErrorCode.ServiceAlreadyExists.

Remover uma instância de serviço

Quando uma instância de serviço não é mais necessária, você pode removê-la da instância do aplicativo em execução chamando a API DeleteServiceAsync .

Aviso

Essa operação não pode ser revertida e o estado do serviço não pode ser recuperado.

Remover uma instância de aplicativo

Quando uma instância de aplicativo não é mais necessária, você pode removê-la permanentemente pelo nome usando a API DeleteApplicationAsync . DeleteApplicationAsync remove automaticamente todos os serviços que pertencem ao aplicativo também, removendo permanentemente todo o estado do serviço.

Aviso

Essa operação não pode ser revertida e o estado do aplicativo não pode ser recuperado.

Cancelar o registro de um tipo de aplicativo

Quando uma versão específica de um tipo de aplicativo não é mais necessária, você deve cancelar o registro dessa versão específica do tipo de aplicativo usando a API Unregister-ServiceFabricApplicationType . Cancelar o registro de versões não utilizadas de tipos de aplicativos libera espaço de armazenamento usado pelo armazenamento de imagens. Uma versão de um tipo de aplicativo pode ser cancelada, desde que nenhum aplicativo seja instanciado em relação a essa versão do tipo de aplicativo. Além disso, o tipo de aplicativo não pode ter atualizações de aplicativo pendentes estão fazendo referência a essa versão do tipo de aplicativo.

Resolução de Problemas

Copy-ServiceFabricApplicationPackage solicita um ImageStoreConnectionString

O ambiente do SDK do Service Fabric já deve ter os padrões corretos configurados. Mas, se necessário, o ImageStoreConnectionString para todos os comandos deve corresponder ao valor que o cluster do Service Fabric está usando. Você pode encontrar o ImageStoreConnectionString no manifesto do cluster, recuperado usando os comandos Get-ServiceFabricClusterManifest e Get-ImageStoreConnectionStringFromClusterManifest:

PS C:\> Get-ImageStoreConnectionStringFromClusterManifest(Get-ServiceFabricClusterManifest)

O cmdlet Get-ImageStoreConnectionStringFromClusterManifest , que faz parte do módulo PowerShell do SDK do Service Fabric, é usado para obter a cadeia de conexão do armazenamento de imagens. Para importar o módulo SDK, execute:

Import-Module "$ENV:ProgramFiles\Microsoft SDKs\Service Fabric\Tools\PSModule\ServiceFabricSDK\ServiceFabricSDK.psm1"

O ImageStoreConnectionString é encontrado no manifesto do cluster:

<ClusterManifest xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" Name="Server-Default-SingleNode" Version="1.0" xmlns="http://schemas.microsoft.com/2011/01/fabric">

    [...]

    <Section Name="Management">
      <Parameter Name="ImageStoreConnectionString" Value="file:D:\ServiceFabric\Data\ImageStore" />
    </Section>

    [...]

Consulte Compreender a cadeia de conexão do armazenamento de imagens para obter informações complementares sobre o armazenamento de imagens e a cadeia de conexão do armazenamento de imagens.

Implantar pacote de aplicativos grande

Problema: a API CopyApplicationPackage expira para um pacote de aplicativo grande (ordem de GB). Experimente:

  • Especifique um tempo limite maior para o método CopyApplicationPackage , com timeout parâmetro. Por padrão, o tempo limite é de 30 minutos.
  • Verifique a conexão de rede entre a máquina de origem e o cluster. Se a conexão for lenta, considere usar uma máquina com uma conexão de rede melhor. Se a máquina cliente estiver em outra região que não o cluster, considere usar uma máquina cliente em uma região mais próxima ou igual à do cluster.
  • Verifique se você está atingindo a limitação externa. Por exemplo, quando o armazenamento de imagens está configurado para usar o armazenamento azure, o carregamento pode ser limitado.

Problema: o pacote de carregamento foi concluído com êxito, mas a API ProvisionApplicationAsync expira. Experimente:

  • Comprima o pacote antes de copiar para o armazenamento de imagens. A compactação reduz o tamanho e o número de arquivos, o que, por sua vez, reduz a quantidade de tráfego e trabalho que o Service Fabric deve executar. A operação de upload pode ser mais lenta (especialmente se você incluir o tempo de compactação), mas registrar e cancelar o registro do tipo de aplicativo são mais rápidos.
  • Especifique um tempo limite maior para a API ProvisionApplicationAsync com timeout parâmetro.

Implante o pacote de aplicativos com muitos arquivos

Problema: ProvisionApplicationAsync expira para um pacote de aplicativo com muitos arquivos (ordem de milhares). Experimente:

Exemplo de código

O exemplo a seguir copia um pacote de aplicativo para o armazenamento de imagens e provisiona o tipo de aplicativo. Em seguida, o exemplo cria uma instância de aplicativo e cria uma instância de serviço. Finalmente, o exemplo remove a instância do aplicativo, desprovisiona o tipo de aplicativo e exclui o pacote do aplicativo do armazenamento de imagens.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Threading.Tasks;

using System.Fabric;
using System.Fabric.Description;
using System.Threading;

namespace ServiceFabricAppLifecycle
{
class Program
{
static void Main(string[] args)
{

    string clusterConnection = "localhost:19000";
    string appName = "fabric:/MyApplication";
    string appType = "MyApplicationType";
    string appVersion = "1.0.0";
    string serviceName = "fabric:/MyApplication/Stateless1";
    string imageStoreConnectionString = "file:C:\\SfDevCluster\\Data\\ImageStoreShare";
    string packagePathInImageStore = "MyApplication";
    string packagePath = "C:\\Users\\username\\Documents\\Visual Studio 2019\\Projects\\MyApplication\\MyApplication\\pkg\\Debug";
    string serviceType = "Stateless1Type";

    // Connect to the cluster.
    FabricClient fabricClient = new FabricClient(clusterConnection);

    // Copy the application package to a location in the image store
    try
    {
        fabricClient.ApplicationManager.CopyApplicationPackage(imageStoreConnectionString, packagePath, packagePathInImageStore);
        Console.WriteLine("Application package copied to {0}", packagePathInImageStore);
    }
    catch (AggregateException ae)
    {
        Console.WriteLine("Application package copy to Image Store failed: ");
        foreach (Exception ex in ae.InnerExceptions)
        {
            Console.WriteLine("HResult: {0} Message: {1}", ex.HResult, ex.Message);
        }
    }

    // Provision the application.  "MyApplicationV1" is the folder in the image store where the application package is located. 
    // The application type with name "MyApplicationType" and version "1.0.0" (both are found in the application manifest) 
    // is now registered in the cluster.            
    try
    {
        fabricClient.ApplicationManager.ProvisionApplicationAsync(packagePathInImageStore).Wait();

        Console.WriteLine("Provisioned application type {0}", packagePathInImageStore);
    }
    catch (AggregateException ae)
    {
        Console.WriteLine("Provision Application Type failed:");

        foreach (Exception ex in ae.InnerExceptions)
        {
            Console.WriteLine("HResult: {0} Message: {1}", ex.HResult, ex.Message);
        }
    }

    // Delete the application package from a location in the image store.
    try
    {
        fabricClient.ApplicationManager.RemoveApplicationPackage(imageStoreConnectionString, packagePathInImageStore);
        Console.WriteLine("Application package removed from {0}", packagePathInImageStore);
    }
    catch (AggregateException ae)
    {
        Console.WriteLine("Application package removal from Image Store failed: ");
        foreach (Exception ex in ae.InnerExceptions)
        {
            Console.WriteLine("HResult: {0} Message: {1}", ex.HResult, ex.Message);
        }
    }

    //  Create the application instance.
    try
    {
        ApplicationDescription appDesc = new ApplicationDescription(new Uri(appName), appType, appVersion);
        fabricClient.ApplicationManager.CreateApplicationAsync(appDesc).Wait();
        Console.WriteLine("Created application instance of type {0}, version {1}", appType, appVersion);
    }
    catch (AggregateException ae)
    {
        Console.WriteLine("CreateApplication failed.");
        foreach (Exception ex in ae.InnerExceptions)
        {
            Console.WriteLine("HResult: {0} Message: {1}", ex.HResult, ex.Message);
        }
    }

    // Create the stateless service description.  For stateful services, use a StatefulServiceDescription object.
    StatelessServiceDescription serviceDescription = new StatelessServiceDescription();
    serviceDescription.ApplicationName = new Uri(appName);
    serviceDescription.InstanceCount = 1;
    serviceDescription.PartitionSchemeDescription = new SingletonPartitionSchemeDescription();
    serviceDescription.ServiceName = new Uri(serviceName);
    serviceDescription.ServiceTypeName = serviceType;

    // Create the service instance.  If the service is declared as a default service in the ApplicationManifest.xml,
    // the service instance is already running and this call will fail.
    try
    {
        fabricClient.ServiceManager.CreateServiceAsync(serviceDescription).Wait();
        Console.WriteLine("Created service instance {0}", serviceName);
    }
    catch (AggregateException ae)
    {
        Console.WriteLine("CreateService failed.");
        foreach (Exception ex in ae.InnerExceptions)
        {
            Console.WriteLine("HResult: {0} Message: {1}", ex.HResult, ex.Message);
        }
    }

    // Delete a service instance.
    try
    {
        DeleteServiceDescription deleteServiceDescription = new DeleteServiceDescription(new Uri(serviceName));

        fabricClient.ServiceManager.DeleteServiceAsync(deleteServiceDescription);
        Console.WriteLine("Deleted service instance {0}", serviceName);
    }
    catch (AggregateException ae)
    {
        Console.WriteLine("DeleteService failed.");
        foreach (Exception ex in ae.InnerExceptions)
        {
            Console.WriteLine("HResult: {0} Message: {1}", ex.HResult, ex.Message);
        }
    }

    // Delete an application instance from the application type.
    try
    {
        DeleteApplicationDescription deleteApplicationDescription = new DeleteApplicationDescription(new Uri(appName));

        fabricClient.ApplicationManager.DeleteApplicationAsync(deleteApplicationDescription).Wait();
        Console.WriteLine("Deleted application instance {0}", appName);
    }
    catch (AggregateException ae)
    {
        Console.WriteLine("DeleteApplication failed.");
        foreach (Exception ex in ae.InnerExceptions)
        {
            Console.WriteLine("HResult: {0} Message: {1}", ex.HResult, ex.Message);
        }
    }

    // Un-provision the application type.
    try
    {
        fabricClient.ApplicationManager.UnprovisionApplicationAsync(appType, appVersion).Wait();
        Console.WriteLine("Un-provisioned application type {0}, version {1}", appType, appVersion);
    }
    catch (AggregateException ae)
    {
        Console.WriteLine("Un-provision application type failed: ");
        foreach (Exception ex in ae.InnerExceptions)
        {
            Console.WriteLine("HResult: {0} Message: {1}", ex.HResult, ex.Message);
        }
    }

    Console.WriteLine("Hit enter...");
    Console.Read();
}        
}
}

Próximos passos

Atualização do aplicativo Service Fabric

Introdução à integridade do Service Fabric

Diagnosticar e solucionar problemas de um serviço do Service Fabric

Modelar um aplicativo no Service Fabric