Distribuera och ta bort program med Hjälp av FabricClient
När en programtyp har paketerats är den redo för distribution till ett Azure Service Fabric-kluster. Distributionen omfattar följande tre steg:
- Ladda upp programpaketet till avbildningsarkivet
- Registrera programtypen
- Ta bort programpaketet från avbildningsarkivet
- Skapa programinstansen
När du har distribuerat ett program och kört en instans i klustret kan du ta bort programinstansen och dess programtyp. Ta bort ett program helt från klustret genom att följa dessa steg:
- Ta bort den programinstans som körs
- Avregistrera programtypen om du inte längre behöver den
Om du använder Visual Studio för att distribuera och felsöka program i ditt lokala utvecklingskluster hanteras alla föregående steg automatiskt via ett PowerShell-skript. Det här skriptet finns i mappen Skript i programprojektet. Den här artikeln innehåller bakgrund om vad skriptet gör så att du kan utföra samma åtgärder utanför Visual Studio.
Anslut till klustret
Anslut till klustret genom att skapa en FabricClient-instans innan du kör något av kodexemplen i den här artikeln. Exempel på hur du ansluter till ett lokalt utvecklingskluster eller ett fjärrkluster eller kluster som skyddas med Microsoft Entra-ID, X509-certifikat eller Windows Active Directory finns i Ansluta till ett säkert kluster. Om du vill ansluta till det lokala utvecklingsklustret kör du följande exempel:
// Connect to the local cluster.
FabricClient fabricClient = new FabricClient();
Ladda upp programpaketet
Anta att du skapar och paketar ett program med namnet MyApplication i Visual Studio. Som standard är namnet på programtypen i ApplicationManifest.xml "MyApplicationType". Programpaketet, som innehåller det nödvändiga programmanifestet, tjänstmanifest och kod-/konfigurations-/datapaket, finns i C:\Användare< username>\Documents\Visual Studio 2019\Projects\MyApplication\MyApplication\pkg\Debug.
När du laddar upp programpaketet placeras det på en plats som är tillgänglig för de interna Service Fabric-komponenterna. Service Fabric verifierar programpaketet under registreringen av programpaketet. Men om du vill verifiera programpaketet lokalt (dvs. innan du laddar upp) använder du cmdleten Test-ServiceFabricApplicationPackage .
API:et CopyApplicationPackage laddar upp programpaketet till klusteravbildningsarkivet.
Om programpaketet är stort och/eller har många filer kan du komprimera det och kopiera det till avbildningslagret med hjälp av PowerShell. Komprimering minskar storleken och antalet filer.
Mer information om avbildningsarkivet och avbildningsarkivet niska veze finns i Förstå niska veze för avbildningsarkivet.
Registrera programpaketet
Programtypen och versionen som deklareras i programmanifestet blir tillgängliga för användning när programpaketet registreras. Systemet läser paketet som laddades upp i föregående steg, verifierar paketet, bearbetar paketinnehållet och kopierar det bearbetade paketet till en intern systemplats.
API:et ProvisionApplicationAsync registrerar programtypen i klustret och gör den tillgänglig för distribution.
API:et GetApplicationTypeListAsync innehåller information om alla programtyper som har registrerats. Du kan använda det här API:et för att avgöra när registreringen är klar.
Ta bort ett programpaket från avbildningsarkivet
Vi rekommenderar att du tar bort programpaketet när programmet har registrerats. Om du tar bort programpaket från avbildningsarkivet frigörs systemresurser. Att behålla oanvända programpaket förbrukar disklagring och leder till problem med programprestanda. Ta bort programpaketet från avbildningsarkivet med api:et RemoveApplicationPackage .
Skapa en programinstans
Du kan instansiera ett program från alla programtyper som har registrerats med hjälp av API:et CreateApplicationAsync . Namnet på varje program måste börja med schemat "fabric:" och måste vara unikt för varje programinstans (i ett kluster). Alla standardtjänster som definieras i programmanifestet för målprogramtypen skapas också.
Flera programinstanser kan skapas för en viss version av en registrerad programtyp. Varje programinstans körs isolerat med en egen arbetskatalog och uppsättning processer.
Om du vill se vilka namngivna program och tjänster som körs i klustret kör du API:erna GetApplicationListAsync och GetServiceListAsync .
Skapa en tjänstinstans
Du kan instansiera en tjänst från en tjänsttyp med hjälp av API:et CreateServiceAsync . Om tjänsten deklareras som en standardtjänst i programmanifestet instansieras tjänsten när programmet instansieras. Om du anropar CreateServiceAsync-API:et för en tjänst som redan är instansierad returneras ett undantag av typen FabricException. Undantaget innehåller en felkod med värdet FabricErrorCode.ServiceAlreadyExists.
Ta bort en tjänstinstans
När en tjänstinstans inte längre behövs kan du ta bort den från programinstansen som körs genom att anropa API:et DeleteServiceAsync .
Varning
Det går inte att ångra den här åtgärden och det går inte att återställa tjänsttillståndet.
Ta bort en programinstans
När en programinstans inte längre behövs kan du permanent ta bort den med hjälp av API:et DeleteApplicationAsync . DeleteApplicationAsync tar automatiskt bort alla tjänster som tillhör programmet och tar permanent bort alla tjänsttillstånd.
Varning
Den här åtgärden kan inte ångras och programtillståndet kan inte återställas.
Avregistrera en programtyp
När en viss version av en programtyp inte längre behövs bör du avregistrera den specifika versionen av programtypen med api:et Unregister-ServiceFabricApplicationType . Om du avregistrerar oanvända versioner av programtyper frigörs lagringsutrymme som används av avbildningsarkivet. En version av en programtyp kan avregistreras så länge inga program instansieras mot den versionen av programtypen. Dessutom kan programtypen inte ha några väntande programuppgraderingar som refererar till den versionen av programtypen.
Felsökning
Copy-ServiceFabricApplicationPackage ber om en ImageStoreConnectionString
Service Fabric SDK-miljön bör redan ha rätt standardinställningar konfigurerade. Men om det behövs ska ImageStoreConnectionString för alla kommandon matcha det värde som Service Fabric-klustret använder. Du hittar ImageStoreConnectionString i klustermanifestet som hämtas med hjälp av kommandona Get-ServiceFabricClusterManifest och Get-ImageStoreConnectionStringFromClusterManifest:
PS C:\> Get-ImageStoreConnectionStringFromClusterManifest(Get-ServiceFabricClusterManifest)
Cmdleten Get-ImageStoreConnectionStringFromClusterManifest, som är en del av Service Fabric SDK PowerShell-modulen, används för att hämta avbildningsarkivet niska veze. Om du vill importera SDK-modulen kör du:
Import-Module "$ENV:ProgramFiles\Microsoft SDKs\Service Fabric\Tools\PSModule\ServiceFabricSDK\ServiceFabricSDK.psm1"
ImageStoreConnectionString finns i klustermanifestet:
<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>
[...]
Mer information om avbildningsarkivet och avbildningsarkivet niska veze finns i Förstå niska veze för avbildningsarkivet.
Distribuera ett stort programpaket
Problem: CopyApplicationPackage API överskrider tidsgränsen för ett stort programpaket (gb i ordning). Prova:
- Ange en större timeout för metoden CopyApplicationPackage med
timeout
parametern . Som standard är tidsgränsen 30 minuter. - Kontrollera nätverksanslutningen mellan källdatorn och klustret. Om anslutningen är långsam kan du överväga att använda en dator med en bättre nätverksanslutning. Om klientdatorn finns i en annan region än klustret kan du överväga att använda en klientdator i en närmare eller samma region som klustret.
- Kontrollera om du stöter på extern begränsning. När avbildningsarkivet till exempel har konfigurerats för att använda Azure Storage kan uppladdningen begränsas.
Problem: Uppladdningspaketet har slutförts, men Tidsgränsen uppnås för API:et ProvisionApplicationAsync . Försöka:
- Komprimera paketet innan du kopierar till avbildningsarkivet. Komprimering minskar storleken och antalet filer, vilket i sin tur minskar mängden trafik och arbete som Service Fabric måste utföra. Uppladdningsåtgärden kan vara långsammare (särskilt om du inkluderar komprimeringstiden), men registrera och avregistrera programtypen går snabbare.
- Ange en större timeout för ProvisionApplicationAsync API med
timeout
parameter.
Distribuera programpaket med många filer
Problem: ProvisionApplicationAsync överskrider tidsgränsen för ett programpaket med många filer (i storleksordningen tusentals). Prova:
- Komprimera paketet innan du kopierar till avbildningsarkivet. Komprimering minskar antalet filer.
- Ange en större tidsgräns för ProvisionApplicationAsync med
timeout
parametern .
Kodexempel
I följande exempel kopieras ett programpaket till avbildningsarkivet och etablerar programtypen. Sedan skapar exemplet en programinstans och skapar en tjänstinstans. Slutligen tar exemplet bort programinstansen, avetablerar programtypen och tar bort programpaketet från avbildningsarkivet.
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ästa steg
Uppgradering av Service Fabric-program
Introduktion till Service Fabric-hälsa