Bereitstellen und Entfernen von Anwendungen mithilfe von FabricClient


Sobald der Anwendungstyp gepackt wurde, ist die Anwendung für die Bereitstellung in einem Azure Service Fabric-Cluster bereit. Die Bereitstellung umfasst die folgenden drei Schritte:

  1. Hochladen des Anwendungspakets in den Imagespeicher
  2. Registrierung des Anwendungstyps
  3. Entfernen des Anwendungspakets aus dem Image-Speicher
  4. Erstellen der Anwendungsinstanz

Nachdem Sie eine Anwendung bereitgestellt und eine Instanz im Cluster ausgeführt haben, können Sie die Anwendungsinstanz und den zugehörigen Anwendungstyp löschen. Führen Sie diese Schritte aus, um eine Anwendung vollständig aus dem Cluster zu entfernen:

  1. Entfernen (oder Löschen) der ausgeführten Anwendungsinstanz
  2. Aufheben der Registrierung des Anwendungstyps, wenn er nicht mehr benötigt wird

Wenn Sie Visual Studio zum Bereitstellen und Debuggen von Anwendungen in Ihrem lokalen Entwicklungscluster verwenden, werden alle vorherigen Schritte automatisch über ein PowerShell-Skript ausgeführt. Dieses Skript befindet sich im Ordner Skripts des Anwendungsprojekts. In diesem Artikel wird die grundlegende Funktionsweise dieses Skripts erläutert, damit Sie die gleichen Vorgänge außerhalb von Visual Studio durchführen können.

Herstellen einer Verbindung mit dem Cluster

Stellen Sie durch Erstellen einer FabricClient-Instanz eine Verbindung mit dem Cluster her, bevor Sie die Codebeispiele in diesem Artikel ausführen. Beispiele für das Herstellen einer Verbindung mit einem lokalen Entwicklungscluster oder einem Remotecluster bzw. einem mit Microsoft Entra, X509-Zertifikaten oder Windows Active Directory gesicherten Cluster finden Sie unter Herstellen einer Verbindung mit einem sicheren Cluster. Führen Sie zum Herstellen der Verbindung mit dem lokalen Entwicklungscluster das folgende Beispiel aus:

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

Hochladen des Anwendungspakets

Angenommen, Sie erstellen und verpacken eine Anwendung namens MyApplication in Visual Studio. Der Name des Anwendungstyps ist in der Datei „ApplicationManifest.xml“ standardmäßig als „MyApplicationType“ aufgeführt. Das Anwendungspaket mit den erforderlichen Anwendungs- und Dienstmanifesten sowie Code-/Konfigurations-/Datenpaketen befindet sich unter C:\Benutzer<Benutzername>\Dokumente\Visual Studio 2019\Projects\MyApplication\MyApplication\pkg\Debug.

Beim Hochladen des Anwendungspakets wird das Paket an einem Speicherort gespeichert, an dem die internen Service Fabric-Komponenten auf das Paket zugreifen können. Service Fabric überprüft das Anwendungspaket während der Registrierung des Pakets. Wenn Sie das Anwendungspaket aber lokal überprüfen möchten (also vor dem Hochladen), müssen Sie das Cmdlet Test-ServiceFabricApplicationPackage verwenden.

Mit der CopyApplicationPackage-API wird das Anwendungspaket in den Clusterimagespeicher hochgeladen.

Wenn das Anwendungspaket groß ist und/oder viele Dateien enthält, können Sie es komprimieren und unter Verwendung von PowerShell in den Imagespeicher kopieren. Durch eine Komprimierung werden Größe und Anzahl der Dateien verringert.

Weitere Informationen zum Imagespeicher und zur Imagespeicher-Verbindungszeichenfolge finden Sie unter Grundlegendes zur Imagespeicher-Verbindungszeichenfolge.

Registrieren des Anwendungspakets

Der Anwendungstyp und die Version, der bzw. die im Anwendungsmanifest deklariert sind, werden beim Registrieren des Anwendungspakets verfügbar. Das System liest das im vorherigen Schritt hochgeladene Paket, überprüft es, verarbeitet den Inhalt des Pakets und kopiert das verarbeitete Paket an einen internen Systemspeicherort.

Mit der ProvisionApplicationAsync-API wird der Anwendungstyp im Cluster registriert und für die Bereitstellung verfügbar gemacht.

Die GetApplicationTypeListAsync-API enthält Informationen über alle erfolgreich registrierten Anwendungstypen. Sie können mithilfe dieser API ermitteln, wann die Registrierung abgeschlossen ist.

Entfernen eines Anwendungspakets aus dem Imagespeicher

Es wird empfohlen, nach erfolgreicher Registrierung der Anwendung das Anwendungspaket zu entfernen. Sie können Systemressourcen freigeben, indem Sie Anwendungspakete aus dem Imagespeicher löschen. Die Speicherung nicht verwendeter Anwendungspakete nimmt Speicherplatz in Anspruch und führt zu Leistungsproblemen der Anwendung. Löschen Sie das Anwendungspaket aus dem Imagespeicher mithilfe der API RemoveApplicationPackage.

Erstellen einer Anwendungsinstanz

Sie können eine Anwendung mit einem beliebigen Anwendungstyp instanziieren, der mit der CreateApplicationAsync-API erfolgreich registriert wurde. Der Name jeder Anwendung muss mit dem „fabric:“ -Schema beginnen und für jede Anwendungsinstanz (innerhalb eines Clusters) eindeutig sein. Wenn im Anwendungsmanifest des Zielanwendungstyps Standarddienste festgelegt wurden, werden diese ebenfalls erstellt.

Für jede Version des registrierten Anwendungstyps können mehrere Anwendungsinstanzen erstellt werden. Jede Anwendungsinstanz wird isoliert mit einem eigenen Arbeitsverzeichnis und einer Reihe von Prozessen ausgeführt.

Um anzuzeigen, welche benannten Anwendungen und Dienste im Cluster ausgeführt werden, führen Sie die APIs GetApplicationListAsync und GetServiceListAsync aus.

Erstellen einer Dienstinstanz

Mit der CreateServiceAsync-API können Sie einen Dienst über einen Diensttyp instanziieren. Wenn der Dienst im Anwendungsmanifest als Standarddienst deklariert ist, wird er beim Instanziieren der Anwendung instanziiert. Wenn die CreateServiceAsync-API für einen Dienst aufgerufen wird, der bereits instanziiert ist, wird eine Ausnahme vom Typ „FabricException“ zurückgegeben. Die Ausnahme enthält einen Fehlercode mit dem Wert „FabricErrorCode.ServiceAlreadyExists“.

Entfernen einer Dienstinstanz

Wenn eine Dienstinstanz nicht mehr benötigt wird, können Sie sie durch Aufrufen der DeleteServiceAsync-API aus der ausgeführten Anwendungsinstanz entfernen.

Warnung

Dieser Vorgang kann nicht rückgängig gemacht werden, und der Dienststatus kann nicht wiederhergestellt werden.

Entfernen einer Anwendungsinstanz

Wenn eine Anwendungsinstanz nicht mehr benötigt wird, können Sie sie anhand des Namens mit der DeleteApplicationAsync-API endgültig entfernen. Mit DeleteApplicationAsync werden auch alle Dienste automatisch entfernt, die mit der Anwendung verknüpft sind, d.h., der Dienststatus wird vollständig und dauerhaft entfernt.

Warnung

Dieser Vorgang kann nicht rückgängig gemacht werden, und der Anwendungsstatus kann nicht wiederhergestellt werden.

Aufheben der Registrierung eines Anwendungstyps

Wird eine bestimmte Version eines Anwendungstyps nicht mehr benötigt, sollten Sie die Registrierung dieser bestimmten Version des Anwendungstyps mit der Unregister-ServiceFabricApplicationType-API aufheben. Durch das Aufheben der Registrierung nicht verwendeter Versionen der Anwendungstypen wird Speicherplatz freigegeben, der vom Imagespeicher verwendet wird. Für eine Version eines Anwendungstyps kann die Registrierung aufgehoben werden, sofern für diese Version keine Anwendungen instanziiert werden. Für den Anwendungstyp dürfen auch keine ausstehenden Anwendungsupgrades auf diese Version des Anwendungstyps verweisen.

Problembehandlung

Copy-ServiceFabricApplicationPackage fordert einen ImageStoreConnectionString an

Die Service Fabric-SDK-Umgebung sollte bereits mit den richtigen Standardeinstellungen eingerichtet sein. Wichtig ist, dass der ImageStoreConnectionString für alle Befehle mit dem vom Service Fabric-Cluster verwendeten Wert übereinstimmt. Sie finden „ImageStoreConnectionString“ im Clustermanifest, das über die Befehle Get-ServiceFabricClusterManifest und „Get-ImageStoreConnectionStringFromClusterManifest“ abgerufen wird:

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

Das Cmdlet Get-ImageStoreConnectionStringFromClusterManifest ist Teil des Service Fabric-SDK-PowerShell-Moduls und wird verwendet, um die Imagespeicher-Verbindungszeichenfolge abzurufen. Um das SDK-Modul zu importieren, führen Sie Folgendes aus:

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

ImageStoreConnectionString ist im Clustermanifest zu finden:

<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>

    [...]

Weitere Informationen zum Imagespeicher und zur Imagespeicher-Verbindungszeichenfolge finden Sie unter Grundlegendes zur Imagespeicher-Verbindungszeichenfolge.

Bereitstellen eines großen Anwendungspakets

Problem: Bei einem großen Anwendungspaket (im GB-Bereich) tritt bei Verwendung der CopyApplicationPackage-API ein Timeout auf. Versuchen Sie Folgendes:

  • Geben Sie für die CopyApplicationPackage-Methode mit dem Parameter timeout einen höheren Timeoutwert an. Das Timeout beträgt standardmäßig 30 Minuten.
  • Überprüfen Sie die Netzwerkverbindung zwischen Ihrem Quellcomputer und dem Cluster. Ziehen Sie bei einer langsamen Verbindung die Verwendung eines Computers mit einer besseren Netzwerkverbindung in Betracht. Wenn sich der Clientcomputer in einem anderen Bereich als der Cluster befindet, sollten Sie einen Clientcomputer in einem näher gelegenen oder im selben Bereich wie den des Clusters verwenden.
  • Überprüfen Sie, ob Sie von einer externen Drosselung betroffen sind. Wenn der Abbildspeicher beispielsweise für die Verwendung des Azure-Speichers konfiguriert ist, wird der Upload eventuell gedrosselt.

Problem: Das Paket wurde erfolgreich hochgeladen, allerdings tritt bei Verwendung der ProvisionApplicationAsync-API ein Timeout auf. Versuchen Sie Folgendes:

  • Komprimieren Sie das Paket, bevor Sie es in den Abbildspeicher kopieren. Durch eine Komprimierung werden Größe und Anzahl der Dateien verringert, wodurch wiederum die Menge des Datenverkehrs und der Aufgaben, die das Service Fabric durchführen muss, reduziert wird. Der Upload kann sich eventuell verlangsamen (insbesondere, wenn Sie die Komprimierungszeit berücksichtigen), aber die Registrierung und die Aufhebung der Registrierung des Anwendungstyps werden schneller durchgeführt.
  • Geben Sie für die ProvisionApplicationAsync-API mit dem Parameter timeout einen höheren Timeoutwert an.

Bereitstellen eines Anwendungspakets mit vielen Dateien

Problem: Bei einem Anwendungspaket mit vielen Dateien (im Tausenderbereich) tritt bei Verwendung der ProvisionApplicationAsync-Methode ein Timeout auf. Versuchen Sie Folgendes:

Codebeispiel

Im folgenden Beispiel wird ein Anwendungspaket in den Imagespeicher kopiert und der Anwendungstyp bereitgestellt. Anschließend werden im Beispiel eine Anwendungsinstanz und eine Dienstinstanz erstellt. Abschließend wird im Beispiel die Anwendungsinstanz entfernt, die Bereitstellung des Anwendungstyps aufgehoben und das Anwendungspaket aus dem Imagespeicher gelöscht.

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();
}        
}
}

Nächste Schritte

Service Fabric-Anwendungsupgrade

Einführung in Service Fabric-Integrität

Diagnose und Problembehandlung von Service Fabric-Diensten

Modellieren einer Anwendung in Service Fabric