In dit artikel wordt beschreven hoe u het patroon moderne web-apps implementeert. Het patroon Moderne web-app definieert hoe u web-apps in de cloud moet moderniseren en een servicegerichte architectuur moet introduceren. Het patroon Moderne web-app biedt prescriptieve architectuur, code en configuratierichtlijnen die zijn afgestemd op de principes van het Goed ontworpen Framework van Azure en bouwt voort op het patroon Reliable Web App.
Waarom het patroon Moderne web-app gebruiken?
Het patroon Moderne web-app helpt bij het optimaliseren van gebieden met hoge vraag van een web-app. Het biedt gedetailleerde richtlijnen voor het loskoppelen van deze gebieden, waardoor onafhankelijk schalen voor kostenoptimalisatie mogelijk is. Met deze aanpak kunt u toegewezen resources toewijzen aan kritieke onderdelen, waardoor de algehele prestaties worden verbeterd. Het loskoppelen van afzonderlijke services kan de betrouwbaarheid verbeteren door vertragingen in één deel van de app te voorkomen. Door het loskoppelen kunt u ook afzonderlijke app-onderdelen afzonderlijk versiebeheer inschakelen.
Het patroon Moderne web-app implementeren
Dit artikel bevat richtlijnen voor architectuur, code en configuratie voor het implementeren van het patroon Moderne web-app. Gebruik de volgende koppelingen om naar de richtlijnen te navigeren die u nodig hebt:
- Architectuurrichtlijnen: Leer hoe u onderdelen van web-apps modulariseert en de juiste PaaS-oplossingen (Platform as a Service) selecteert.
- Coderichtlijnen: Implementeer vier ontwerppatronen om de losgekoppelde onderdelen te optimaliseren: Strangler Fig, load leveling op basis van wachtrij, concurrerende consumenten en statuseindpuntbewakingspatronen.
- Configuratierichtlijnen: Verificatie, autorisatie, automatisch schalen en containerisatie configureren voor de losgekoppelde onderdelen.
Tip
Er is een referentie-implementatie (voorbeeld-app) van het patroon Moderne web-app. Het vertegenwoordigt de eindstatus van de implementatie van de moderne web-app. Het is een web-app op productieniveau die alle code, architectuur en configuratie-updates bevat die in dit artikel worden besproken. Implementeer en gebruik de referentie-implementatie om uw implementatie van het moderne web-app-patroon te begeleiden.
Uitleg bij architectuur
Het patroon Moderne web-app is gebaseerd op het patroon Reliable Web App. Er zijn enkele extra architectuuronderdelen nodig om te implementeren. U hebt een berichtenwachtrij, containerplatform, losgekoppeld servicegegevensarchief en een containerregister nodig (zie afbeelding 1).
Afbeelding 1. Essentiële architecturale elementen van het patroon Moderne web-app.
Voor een hogere serviceniveaudoelstelling (SLO) kunt u een tweede regio toevoegen aan uw web-app-architectuur. Voor een tweede regio moet u uw load balancer configureren om verkeer naar de tweede regio te routeren om een actief-actief- of actief-passieve configuratie te ondersteunen. Gebruik een hub-and-spoke-netwerktopologie om resources, zoals een netwerkfirewall, te centraliseren en te delen. Open de containeropslagplaats via het virtuele hubnetwerk. Als u virtuele machines hebt, voegt u een bastionhost toe aan het virtuele hubnetwerk om deze veilig te beheren (zie afbeelding 2).
Afbeelding 2. De architectuur van het moderne web-app-patroon met de tweede regio en hub-and-spoke-netwerktopologie.
Architectuur loskoppelen
Als u het patroon Moderne web-app wilt implementeren, moet u de bestaande web-app-architectuur loskoppelen. Het loskoppelen van de architectuur omvat het opsplitsen van een monolithische toepassing in kleinere, onafhankelijke services, die elk verantwoordelijk zijn voor een specifieke functie of functionaliteit. Dit proces omvat het evalueren van de huidige web-app, het wijzigen van de architectuur en ten slotte het extraheren van de code van de web-app naar een containerplatform. Het doel is om toepassingsservices die het meeste profiteren van ontkoppeld, systematisch te identificeren en te extraheren. Volg deze aanbevelingen om uw architectuur los te koppelen:
Servicegrenzen identificeren. Pas ontwerpprincipes op basis van een domein toe om gebonden contexten binnen uw monolithische toepassing te identificeren. Elke gebonden context vertegenwoordigt een logische grens en kan een kandidaat zijn voor een afzonderlijke service. Services die afzonderlijke bedrijfsfuncties vertegenwoordigen en minder afhankelijkheden hebben, zijn goede kandidaten voor ontkoppeling.
Evalueer servicevoordelen. Richt u op services die het meest profiteren van onafhankelijk schalen. Het loskoppelen van deze services en het converteren van verwerkingstaken van synchrone naar asynchrone bewerkingen maakt efficiënter resourcebeheer mogelijk, ondersteunt onafhankelijke implementaties en vermindert het risico dat andere onderdelen van de toepassing worden beïnvloed tijdens updates of wijzigingen. U kunt bijvoorbeeld het uitchecken van de bestelling scheiden van de orderverwerking.
Technische haalbaarheid beoordelen. Bekijk de huidige architectuur om technische beperkingen en afhankelijkheden te identificeren die van invloed kunnen zijn op het ontkoppelingsproces. Plan hoe gegevens worden beheerd en gedeeld tussen services. Losgekoppelde services moeten hun eigen gegevens beheren en directe databasetoegang over servicegrenzen minimaliseren.
Azure-services implementeren. Selecteer en implementeer de Azure-services die u nodig hebt om de web-app-service te ondersteunen die u wilt extraheren. Gebruik de volgende sectie Azure-services selecteren voor hulp.
Koppel web-app-services los. Definieer duidelijke interfaces en API's voor de zojuist geëxtraheerde web-app-services om te communiceren met andere onderdelen van het systeem. Ontwerp een strategie voor gegevensbeheer waarmee elke service zijn eigen gegevens kan beheren en tegelijkertijd consistentie en integriteit kan garanderen. Raadpleeg de sectie Code-richtlijnen voor specifieke implementatiestrategieën en ontwerppatronen die tijdens dit extractieproces moeten worden gebruikt.
Gebruik onafhankelijke opslag voor losgekoppelde services. Elke losgekoppelde service moet een eigen geïsoleerd gegevensarchief hebben om onafhankelijke versiebeheer, implementatie, schaalbaarheid en gegevensintegriteit te vergemakkelijken. De referentie-implementatie scheidt bijvoorbeeld de ticketrenderingsservice van de web-API en elimineert de noodzaak voor de service om toegang te krijgen tot de database van de API. In plaats daarvan communiceert de service de URL waarin ticketinstallatiekopieën zijn gegenereerd naar de web-API via een Azure Service Bus-bericht en blijft het pad naar de database behouden.
Implementeer afzonderlijke implementatiepijplijnen voor elke losgekoppelde service. Met afzonderlijke implementatiepijplijnen kan elke service in zijn eigen tempo worden bijgewerkt. Als verschillende teams of organisaties binnen uw bedrijf eigenaar zijn van verschillende services, heeft u afzonderlijke implementatiepijplijnen die elk team controle geven over hun eigen implementaties. Gebruik hulpprogramma's voor continue integratie en continue levering (CI/CD), zoals Jenkins, GitHub Actions of Azure Pipelines om deze pijplijnen in te stellen.
Besturingselementen voor beveiliging herzien. Zorg ervoor dat uw beveiligingscontroles worden bijgewerkt om rekening te houden met de nieuwe architectuur, waaronder firewallregels en toegangsbeheer.
De juiste Azure-services selecteren
Raadpleeg voor elke Azure-service in uw architectuur de relevante Azure-servicehandleiding in het Well-Architected Framework. Voor het patroon Moderne web-app hebt u een berichtensysteem nodig om asynchrone berichten te ondersteunen, een toepassingsplatform dat ondersteuning biedt voor containerisatie en een opslagplaats voor containerinstallatiekopieën.
Kies een berichtenwachtrij. Een berichtenwachtrij is een belangrijk onderdeel van servicegerichte architecturen. Hiermee worden afzenders en ontvangers van berichten ontkoppeld om asynchrone berichten in te schakelen. Gebruik de richtlijnen voor het kiezen van een Azure Messaging-service om een Azure Messaging-systeem te kiezen dat uw ontwerpbehoeften ondersteunt. Azure heeft drie berichtenservices: Azure Event Grid, Azure Event Hubs en Service Bus. Begin met Service Bus als de standaardoptie en gebruik de andere twee opties als Service Bus niet aan uw behoeften voldoet.
Service Gebruiksscenario Service Bus Kies Service Bus voor betrouwbare, geordende en mogelijk transactionele levering van hoogwaardige berichten in bedrijfstoepassingen. Event Grid Kies Event Grid wanneer u een groot aantal discrete gebeurtenissen efficiënt moet afhandelen. Event Grid is schaalbaar voor gebeurtenisgestuurde toepassingen waarbij veel kleine, onafhankelijke gebeurtenissen (zoals wijzigingen in de resourcestatus) moeten worden gerouteerd naar abonnees in een model met lage latentie en publiceren-abonneren. Event Hubs Kies Event Hubs voor enorme gegevensopname met hoge doorvoer, zoals telemetrie, logboeken of realtime analyse. Event Hubs is geoptimaliseerd voor streamingscenario's waarbij bulkgegevens continu moeten worden opgenomen en verwerkt. Een containerservice implementeren. Voor de onderdelen van uw toepassing die u in een container wilt plaatsen, hebt u een toepassingsplatform nodig dat containers ondersteunt. Gebruik de richtlijnen voor een Azure-containerservice kiezen om uw beslissing te nemen. Azure heeft drie principal-containerservices: Azure Container Apps, Azure Kubernetes Service (AKS) en Azure-app Service. Begin met Container Apps als de standaardoptie en gebruik de andere twee opties als Container Apps niet aan uw behoeften voldoet.
Service Gebruiksscenario Container Apps Kies Container Apps als u een serverloos platform nodig hebt dat containers automatisch schaalt en beheert in gebeurtenisgestuurde toepassingen. AKS Kies AKS als u gedetailleerde controle nodig hebt over Kubernetes-configuraties en geavanceerde functies voor schalen, netwerken en beveiliging. Web Apps voor container Kies Web App for Containers in App Service voor de eenvoudigste PaaS-ervaring. Implementeer een containeropslagplaats. Wanneer u een rekenservice op basis van containers gebruikt, moet u een opslagplaats hebben om de containerinstallatiekopieën op te slaan. U kunt een openbaar containerregister gebruiken, zoals Docker Hub of een beheerd register, zoals Azure Container Registry. Gebruik de inleiding tot containerregisters in Azure-richtlijnen om uw beslissing te nemen.
Richtlijnen voor code
Als u een onafhankelijke service wilt loskoppelen en extraheren, moet u de code van uw web-app bijwerken met de volgende ontwerppatronen: het patroon Strangler Fig, het patroon Load Leveling op basis van wachtrij, het patroon Concurrerende consumenten, het patroon Statuseindpuntbewaking en het patroon Opnieuw proberen.
Afbeelding 3. Rol van de ontwerppatronen.
Strangler Fig-patroon: Het Strangler Fig-patroon migreert incrementeel functionaliteit van een monolithische toepassing naar de losgekoppelde service. Implementeer dit patroon in de hoofdweb-app om functionaliteit geleidelijk te migreren naar onafhankelijke services door verkeer te leiden op basis van eindpunten.
Patroon load leveling op basis van wachtrij: het patroon Load Leveling op basis van wachtrij beheert de stroom van berichten tussen de producent en de consument door een wachtrij als buffer te gebruiken. Implementeer dit patroon op het producentgedeelte van de ontkoppelde service om de berichtstroom asynchroon te beheren met behulp van een wachtrij.
Patroon concurrerende consumenten: Met het patroon Concurrerende consumenten kunnen meerdere exemplaren van de losgekoppelde service onafhankelijk van dezelfde berichtenwachtrij lezen en concurreren om berichten te verwerken. Implementeer dit patroon in de losgekoppelde service om taken over meerdere exemplaren te distribueren.
Patroon Statuseindpuntbewaking: Het patroon Statuseindpuntbewaking toont eindpunten voor het bewaken van de status en status van verschillende onderdelen van de web-app. (4a) Implementeer dit patroon in de hoofdweb-app. (4b) Implementeer deze ook in de losgekoppelde service om de status van eindpunten bij te houden.
Patroon voor opnieuw proberen: het patroon Opnieuw proberen verwerkt tijdelijke fouten door bewerkingen opnieuw uit te voeren die af en toe kunnen mislukken. (5a) Implementeer dit patroon voor alle uitgaande aanroepen naar andere Azure-services in de hoofdweb-app, zoals aanroepen naar berichtenwachtrij en privé-eindpunten. (5b) Implementeer dit patroon ook in de ontkoppelde service om tijdelijke fouten in aanroepen naar de privé-eindpunten af te handelen.
Elk ontwerppatroon biedt voordelen die zijn afgestemd op een of meer pijlers van het Well-Architected Framework (zie de volgende tabel).
Ontwerppatroon | Implementatielocatie | Betrouwbaarheid (RE) | Beveiliging (SE) | Kostenoptimalisatie (CO) | Operational Excellence (OE) | Prestatie-efficiëntie (PE) | Goed ontworpen frameworkprincipes ondersteunen |
---|---|---|---|---|---|---|---|
Strangler Fig-patroon | Hoofdweb-app | ✔ | ✔ | ✔ | RE:08 CO:07 CO:08 OE:06 OE:11 |
||
Patroon Load Leveling op basis van wachtrij | Producent van losgekoppelde service | ✔ | ✔ | ✔ | RE:06 RE:07 CO:12 PE:05 |
||
Patroon concurrerende consumenten | Losgekoppelde service | ✔ | ✔ | ✔ | RE:05 RE:07 CO:05 CO:07 PE:05 PE:07 |
||
Patroon Statuseindpuntbewaking | Hoofdweb-app en losgekoppelde service | ✔ | ✔ | ✔ | RE:07 RE:10 OE:07 PE:05 |
||
Patroon opnieuw proberen | Hoofdweb-app en losgekoppelde service | ✔ | RE:07 |
Het strangler Fig-patroon implementeren
Gebruik het strangler Fig-patroon om de functionaliteit geleidelijk te migreren van de monolithische codebasis naar nieuwe onafhankelijke services. Extraheer nieuwe services uit de bestaande monolithische codebasis en moderniseer langzaam kritieke onderdelen van de web-app. Volg deze aanbevelingen om het strangler Fig-patroon te implementeren:
Stel een routeringslaag in. Implementeer in de codebasis van de monolithische web-app een routeringslaag die verkeer omleidt op basis van eindpunten. Gebruik zo nodig aangepaste routeringslogica voor het afhandelen van specifieke bedrijfsregels voor het omleiden van verkeer. Als u bijvoorbeeld een
/users
eindpunt in uw monolithische app hebt en deze functionaliteit hebt verplaatst naar de losgekoppelde service, stuurt de routeringslaag alle aanvragen naar/users
de nieuwe service.Implementatie van functies beheren. Gebruik .NET-functiebeheerbibliotheken om functievlagmen en gefaseerde implementatie te implementeren om de losgekoppelde services geleidelijk uit te rollen. De bestaande monolithische app-routering moet bepalen hoeveel aanvragen de losgekoppelde services ontvangen. Begin met een klein percentage aanvragen en verhoog het gebruik in de loop van de tijd naarmate u vertrouwen krijgt in de stabiliteit en prestaties. Met de referentie-implementatie wordt bijvoorbeeld de functionaliteit voor ticketrendering geëxtraheerd in een zelfstandige service, die geleidelijk kan worden geïntroduceerd om een groter deel van de ticketrenderingsaanvragen af te handelen. Omdat de nieuwe service de betrouwbaarheid en prestaties bewijst, kan deze uiteindelijk de volledige functionaliteit voor het renderen van tickets overnemen vanuit de monolithie, waardoor de overgang wordt voltooid.
Gebruik een gevelservice (indien nodig). Een gevelservice is handig wanneer één aanvraag moet communiceren met meerdere services of wanneer u de complexiteit van het onderliggende systeem van de client wilt verbergen. Als de ontkoppelde service echter geen openbare API's heeft, is een façadeservice mogelijk niet nodig. Implementeer in de codebasis van de monolithische web-app een façadeservice om aanvragen naar de juiste back-end (monolith of microservice) te routeren. Zorg ervoor dat de nieuwe service in de nieuwe ontkoppelde service aanvragen onafhankelijk kan verwerken wanneer deze toegankelijk is via de gevel.
Het patroon Load Leveling op basis van wachtrij implementeren
Implementeer het patroon load leveling op basis van wachtrijen op het producentgedeelte van de losgekoppelde service om taken die niet direct hoeven te worden beantwoord, asynchroon af te handelen. Dit patroon verbetert de algehele reactiesnelheid en schaalbaarheid van het systeem met behulp van een wachtrij voor het beheren van de workloaddistributie. Hiermee kan de ontkoppelde service aanvragen met een consistente snelheid verwerken. Volg deze aanbevelingen om dit patroon effectief te implementeren:
Gebruik niet-blokkerende berichtenwachtrijen. Zorg ervoor dat het proces waarmee berichten naar de wachtrij worden verzonden, andere processen niet blokkeert terwijl wordt gewacht tot de losgekoppelde service berichten in de wachtrij verwerkt. Als voor het proces het resultaat van de losgekoppelde servicebewerking is vereist, kunt u de situatie ook afhandelen terwijl u wacht tot de bewerking in de wachtrij is voltooid. De referentie-implementatie maakt bijvoorbeeld gebruik van Service Bus en het
await
trefwoord waarmeemessageSender.PublishAsync()
berichten asynchroon naar de wachtrij worden gepubliceerd zonder dat de thread die deze code uitvoert, wordt geblokkeerd:// Asynchronously publish a message without blocking the calling thread await messageSender.PublishAsync(new TicketRenderRequestMessage(Guid.NewGuid(), ticket, null, DateTime.Now), CancellationToken.None);
Deze aanpak zorgt ervoor dat de hoofdtoepassing responsief blijft en andere taken gelijktijdig kan verwerken, terwijl de losgekoppelde service de aanvragen in de wachtrij met een beheersbaar tarief verwerkt.
Implementeer het opnieuw proberen en verwijderen van berichten. Implementeer een mechanisme voor het opnieuw verwerken van berichten in de wachtrij die niet kunnen worden verwerkt. Als er fouten optreden, moeten deze berichten uit de wachtrij worden verwijderd. Service Bus heeft bijvoorbeeld ingebouwde functies voor nieuwe pogingen en wachtrijen met dode letters.
Configureer idempotent berichtverwerking. De logica waarmee berichten uit de wachtrij worden verwerkt, moet idempotent zijn voor het afhandelen van gevallen waarin een bericht meerdere keren kan worden verwerkt. De referentie-implementatie gebruikt
ServiceBusClient.CreateProcessor
bijvoorbeeld metAutoCompleteMessages = true
enReceiveMode = ServiceBusReceiveMode.PeekLock
om ervoor te zorgen dat berichten slechts eenmaal worden verwerkt en opnieuw kunnen worden verwerkt bij fouten (zie de volgende code).// Create a processor for idempotent message processing var processor = serviceBusClient.CreateProcessor(path, new ServiceBusProcessorOptions { // Allow the messages to be auto-completed // if processing finishes without failure. AutoCompleteMessages = true, // PeekLock mode provides reliability in that unsettled messages // will be redelivered on failure. ReceiveMode = ServiceBusReceiveMode.PeekLock, // Containerized processors can scale at the container level // and need not scale via the processor options. MaxConcurrentCalls = 1, PrefetchCount = 0 });
Wijzigingen in de ervaring beheren. Asynchrone verwerking kan ertoe leiden dat taken niet onmiddellijk worden voltooid. Gebruikers moeten zich bewust worden gemaakt wanneer hun taak nog steeds wordt verwerkt om de juiste verwachtingen in te stellen en verwarring te voorkomen. Gebruik visuele aanwijzingen of berichten om aan te geven dat een taak wordt uitgevoerd. Geef gebruikers de mogelijkheid om meldingen te ontvangen wanneer hun taak is voltooid, zoals een e-mail of pushmelding.
Het patroon Concurrerende consumenten implementeren
Implementeer het patroon Concurrerende consumenten in de losgekoppelde services om binnenkomende taken uit de berichtenwachtrij te beheren. Dit patroon omvat het distribueren van taken over meerdere instanties van losgekoppelde services. Deze services verwerken berichten uit de wachtrij, verbeteren de taakverdeling en stimuleren de capaciteit van het systeem om gelijktijdige aanvragen te verwerken. Het patroon Concurrerende consumenten is effectief wanneer:
- De volgorde van berichtverwerking is niet van cruciaal belang.
- De wachtrij blijft niet beïnvloed door verkeerd gevormde berichten.
- De verwerkingsbewerking is idempotent, wat betekent dat deze meerdere keren kan worden toegepast zonder het resultaat te wijzigen buiten de eerste toepassing.
Volg deze aanbevelingen om het patroon Concurrerende consumenten te implementeren:
Gelijktijdige berichten verwerken. Wanneer u berichten van een wachtrij ontvangt, moet u ervoor zorgen dat uw systeem is ontworpen om meerdere berichten gelijktijdig te verwerken. Stel het maximum aantal gelijktijdige aanroepen in op 1, zodat een afzonderlijke consument elk bericht verwerkt.
Schakel prefetching uit. Schakel het vooraf afhalen van berichten uit, zodat gebruikers alleen berichten ophalen wanneer ze klaar zijn.
Gebruik betrouwbare berichtverwerkingsmodi. Gebruik een betrouwbare verwerkingsmodus, zoals PeekLock (of het equivalent daarvan), waarmee berichten die niet kunnen worden verwerkt, automatisch opnieuw worden uitgevoerd. Deze modus verbetert de betrouwbaarheid ten opzichte van verwijderings-eerste methoden. Als een werkrol een bericht niet kan verwerken, moet een andere werknemer het zonder fouten kunnen verwerken, zelfs als het bericht meerdere keren wordt verwerkt.
Foutafhandeling implementeren. Verkeerd gevormde of niet-verwerkte berichten doorsturen naar een afzonderlijke wachtrij met dode letters. Dit ontwerp voorkomt terugkerende verwerking. U kunt bijvoorbeeld uitzonderingen vangen tijdens het verwerken van berichten en het problematische bericht verplaatsen naar de afzonderlijke wachtrij.
Berichten buiten de volgorde verwerken. Ontwerp consumenten om berichten te verwerken die niet op volgorde aankomen. Meerdere parallelle consumenten betekent dat ze berichten mogelijk niet op volgorde verwerken.
Schalen op basis van de lengte van de wachtrij. Services die berichten uit een wachtrij gebruiken, moeten automatisch worden geschaald op basis van de lengte van de wachtrij. Automatische schaalaanpassing op basis van schaal zorgt voor een efficiënte verwerking van pieken in binnenkomende berichten.
Gebruik een berichtenwachtrij. Als voor het systeem meldingen zijn vereist voor het verwerken van berichten, stelt u een speciale antwoord- of antwoordwachtrij in. Deze installatie verdeelt operationele berichten van meldingsprocessen.
Gebruik stateless services. Overweeg om stateless services te gebruiken om aanvragen uit een wachtrij te verwerken. Het maakt eenvoudig schalen en efficiënt resourcegebruik mogelijk.
Logboekregistratie configureren. Integreer logboekregistratie en specifieke uitzonderingsafhandeling in de werkstroom voor berichtverwerking. Richt u op het vastleggen van serialisatiefouten en het doorsturen van deze problematische berichten naar een mechanisme voor dode letters. Deze logboeken bieden waardevolle inzichten voor probleemoplossing.
De referentie-implementatie maakt bijvoorbeeld gebruik van het patroon Concurrerende consumenten voor een staatloze service die wordt uitgevoerd in Container Apps om aanvragen voor ticketweergave uit een Service Bus-wachtrij te verwerken. Hiermee configureert u een wachtrijprocessor met:
- AutoCompleteMessages: hiermee worden berichten automatisch voltooid als ze zonder fouten worden verwerkt.
- ReceiveMode: gebruikt de PeekLock-modus en berichten opnieuw verzenden als ze niet zijn vereffend.
- MaxConcurrentCalls: stel in op 1 om één bericht tegelijk te verwerken.
- PrefetchCount: stel in op 0 om te voorkomen dat berichten vooraf worden gezet.
De processor registreert details voor berichtverwerking, die u helpen bij het oplossen en bewaken van problemen. Hiermee worden deserialisatiefouten vastgelegd en worden ongeldige berichten gerouteerd naar een wachtrij met dode letters, waardoor terugkerende verwerking van foutieve berichten wordt voorkomen. De service wordt geschaald op containerniveau, zodat berichtenpieken efficiënt kunnen worden verwerkt op basis van de lengte van de wachtrij.
// Create a processor for the given queue that will process
// incoming messages.
var processor = serviceBusClient.CreateProcessor(path, new ServiceBusProcessorOptions
{
// Allow the messages to be auto-completed
// if processing finishes without failure.
AutoCompleteMessages = true,
// PeekLock mode provides reliability in that unsettled messages
// are redelivered on failure.
ReceiveMode = ServiceBusReceiveMode.PeekLock,
// Containerized processors can scale at the container level
// and need not scale via the processor options.
MaxConcurrentCalls = 1,
PrefetchCount = 0
});
// Called for each message received by the processor.
processor.ProcessMessageAsync += async args =>
{
logger.LogInformation("Processing message {MessageId} from {ServiceBusNamespace}/{Path}", args.Message.MessageId, args.FullyQualifiedNamespace, args.EntityPath);
// Unhandled exceptions in the handler will be caught by
// the processor and result in abandoning and dead-lettering the message.
try
{
var message = args.Message.Body.ToObjectFromJson<T>();
await messageHandler(message, args.CancellationToken);
logger.LogInformation("Successfully processed message {MessageId} from {ServiceBusNamespace}/{Path}",args.Message.MessageId, args.FullyQualifiedNamespace, args.EntityPath);
}
catch (JsonException)
{
logger.LogError("Invalid message body; could not be deserialized to {Type}", typeof(T));
await args.DeadLetterMessageAsync(args.Message, $"Invalid message body; could not be deserialized to {typeof(T)}",cancellationToken: args.CancellationToken);
}
};
Het patroon Statuseindpuntbewaking implementeren
Implementeer het patroon Statuseindpuntbewaking in de hoofd-app-code en losgekoppelde servicecode om de status van toepassingseindpunten bij te houden. Orchestrators zoals AKS of Container Apps kunnen deze eindpunten peilen om de servicestatus te controleren en beschadigde exemplaren opnieuw op te starten. ASP.NET Core-apps kunnen speciale statuscontrole-middleware toevoegen om op efficiënte wijze eindpuntstatusgegevens en sleutelafhankelijkheden te verwerken. Volg deze aanbevelingen om het patroon Statuseindpuntbewaking te implementeren:
Statuscontroles implementeren. Gebruik ASP.NET Core health checks middleware om statuscontrole-eindpunten te bieden.
Afhankelijkheden valideren. Zorg ervoor dat uw statuscontroles de beschikbaarheid van belangrijke afhankelijkheden valideren, zoals de database, opslag en berichtensysteem. Het pakket dat niet van Microsoft is, AspNetCore.Diagnostics.HealthChecks, kan afhankelijkheidscontroles voor statuscontrole implementeren voor veel algemene app-afhankelijkheden.
De referentie-implementatie maakt bijvoorbeeld gebruik van ASP.NET Middleware voor kernstatuscontrole om eindpunten voor statuscontrole beschikbaar te maken met behulp van de
AddHealthChecks()
methode op hetbuilder.Services
object. De code valideert de beschikbaarheid van belangrijke afhankelijkheden, Azure Blob Storage en De Service Bus-wachtrij met deAddAzureBlobStorage()
enAddAzureServiceBusQueue()
methoden, die deel uitmaken van hetAspNetCore.Diagnostics.HealthChecks
pakket. Container Apps maakt configuratie mogelijk van statustests die worden bewaakt om te meten of apps in orde zijn of in behoefte zijn aan recycling.// Add health checks, including health checks for Azure services // that are used by this service. // The Blob Storage and Service Bus health checks are provided by // AspNetCore.Diagnostics.HealthChecks // (a popular open source project) rather than by Microsoft. // https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks builder.Services.AddHealthChecks() .AddAzureBlobStorage(options => { // AddAzureBlobStorage will use the BlobServiceClient registered in DI // We just need to specify the container name options.ContainerName = builder.Configuration.GetRequiredConfigurationValue("App:StorageAccount:Container"); }) .AddAzureServiceBusQueue( builder.Configuration.GetRequiredConfigurationValue("App:ServiceBus:Host"), builder.Configuration.GetRequiredConfigurationValue("App:ServiceBus:RenderRequestQueueName"), azureCredentials); // Further app configuration omitted for brevity app.MapHealthChecks("/health");
Azure-resources configureren. Configureer de Azure-resources om de URL's van de statuscontrole van de app te gebruiken om de liveness en gereedheid te bevestigen. De referentie-implementatie maakt bijvoorbeeld gebruik van Bicep om de STATUSCONTROLE-URL's te configureren om de liveness en gereedheid van de Azure-resource te bevestigen. Een livenesstest om het
/health
eindpunt elke 10 seconden na een initiële vertraging van 2 seconden te bereiken.probes: [ { type: 'liveness' httpGet: { path: '/health' port: 8080 } initialDelaySeconds: 2 periodSeconds: 10 } ]
Het patroon Opnieuw proberen implementeren
Met het patroon Opnieuw proberen kunnen toepassingen herstellen van tijdelijke fouten. Het patroon Opnieuw proberen is centraal in het patroon Betrouwbare web-app, dus uw web-app moet het patroon Opnieuw proberen al gebruiken. Pas het patroon Opnieuw proberen toe op aanvragen op de berichtensystemen en aanvragen die zijn uitgegeven door de losgekoppelde services die u uit de web-app haalt. Volg deze aanbevelingen om het patroon Opnieuw proberen te implementeren:
Configureer opties voor opnieuw proberen. Wanneer u integreert met een berichtenwachtrij, moet u ervoor zorgen dat u de client configureert die verantwoordelijk is voor interacties met de wachtrij met de juiste instellingen voor opnieuw proberen. Geef parameters op, zoals het maximum aantal nieuwe pogingen, vertraging tussen nieuwe pogingen en maximale vertraging.
Gebruik exponentieel uitstel. Implementeer een exponentiële uitstelstrategie voor nieuwe pogingen. Dit betekent dat de tijd tussen elke nieuwe poging exponentieel toeneemt, waardoor de belasting van het systeem tijdens perioden met hoge storingsfrequenties wordt verminderd.
Gebruik de sdk-functionaliteit voor opnieuw proberen. Gebruik de ingebouwde mechanismen voor opnieuw proberen voor services met gespecialiseerde SDK's, zoals Service Bus of Blob Storage. De ingebouwde mechanismen voor opnieuw proberen zijn geoptimaliseerd voor de typische gebruiksscenario's van de service en kunnen nieuwe pogingen effectiever verwerken met minder configuratie die voor u vereist is. De referentie-implementatie maakt bijvoorbeeld gebruik van de ingebouwde functionaliteit voor opnieuw proberen van de Service Bus SDK (
ServiceBusClient
enServiceBusRetryOptions
). HetServiceBusRetryOptions
object haalt instellingen op vanMessageBusOptions
waaruit u instellingen voor opnieuw proberen wilt configureren, zoals MaxRetries, Delay, MaxDelay en TryTimeout.// ServiceBusClient is thread-safe and can be reused for the lifetime // of the application. services.AddSingleton(sp => { var options = sp.GetRequiredService<IOptions<MessageBusOptions>>().Value; var clientOptions = new ServiceBusClientOptions { RetryOptions = new ServiceBusRetryOptions { Mode = ServiceBusRetryMode.Exponential, MaxRetries = options.MaxRetries, Delay = TimeSpan.FromSeconds(options.BaseDelaySecondsBetweenRetries), MaxDelay = TimeSpan.FromSeconds(options.MaxDelaySeconds), TryTimeout = TimeSpan.FromSeconds(options.TryTimeoutSeconds) } }; return new ServiceBusClient(options.Host, azureCredential ?? new DefaultAzureCredential(), clientOptions); });
Gebruik standaardtolerantiebibliotheken voor HTTP-clients. Integreer voor HTTP-communicatie een standaardbibliotheek voor tolerantie, zoals Polly of
Microsoft.Extensions.Http.Resilience
. Deze bibliotheken bieden uitgebreide mechanismen voor opnieuw proberen die essentieel zijn voor het beheren van communicatie met externe webservices.Afhandelen van berichtvergrendeling. Voor systemen op basis van berichten implementeert u strategieën voor het verwerken van berichten die ondersteuning bieden voor nieuwe pogingen zonder gegevensverlies, zoals het gebruik van 'peek-lock'-modi waar beschikbaar. Zorg ervoor dat mislukte berichten effectief opnieuw worden geprobeerd en worden verplaatst naar een wachtrij met onbestelbare berichten na herhaalde fouten.
Gedistribueerde tracering implementeren
Naarmate toepassingen meer servicegericht worden en hun onderdelen losgekoppeld zijn, is het bewaken van de uitvoeringsstroom tussen services cruciaal. Het patroon Moderne web-app maakt gebruik van Application Insights en Azure Monitor voor inzicht in de status en prestaties van toepassingen via OpenTelemetry-API's, die gedistribueerde tracering ondersteunen.
Met gedistribueerde tracering wordt een gebruikersaanvraag bijgehouden terwijl deze meerdere services doorkruist. Wanneer een aanvraag wordt ontvangen, wordt deze getagd met een tracerings-id, die wordt doorgegeven aan andere onderdelen via HTTP-headers en Service Bus-eigenschappen tijdens het aanroepen van afhankelijkheden. Traceringen en logboeken bevatten vervolgens zowel de tracerings-id als een activiteits-id (of span-id), die overeenkomt met het specifieke onderdeel en de bovenliggende activiteit. Bewakingshulpprogramma's zoals Application Insights gebruiken het om een structuur met activiteiten en logboeken weer te geven voor verschillende services, die cruciaal zijn voor het bewaken van gedistribueerde toepassingen.
Installeer OpenTelemetry-bibliotheken. Gebruik instrumentatiebibliotheken om tracering en metrische gegevens van algemene onderdelen in te schakelen. Voeg aangepaste instrumentatie toe met
System.Diagnostics.ActivitySource
enSystem.Diagnostics.Activity
indien nodig. Gebruik exporteursbibliotheken om te luisteren naar diagnostische gegevens van OpenTelemetry en deze vast te leggen in permanente winkels. Bestaande exporteurs gebruiken of uw eigen exporteurs maken metSystem.Diagnostics.ActivityListener
.OpenTelemetry instellen. Gebruik de Azure Monitor-distributie van OpenTelemetry (
Azure.Monitor.OpenTelemetry.AspNetCore
). Zorg ervoor dat diagnostische gegevens naar Application Insights worden geëxporteerd en ingebouwde instrumentatie bevat voor algemene metrische gegevens, traceringen, logboeken en uitzonderingen van de .NET-runtime en ASP.NET Core. Neem andere OpenTelemetry-instrumentatiepakketten op voor SQL-, Redis- en Azure SDK-clients.Bewaken en analyseren. Zorg er na de configuratie voor dat logboeken, traceringen, metrische gegevens en uitzonderingen worden vastgelegd en verzonden naar Application Insights. Controleer of tracerings-, activiteits- en bovenliggende activiteits-id's zijn opgenomen, zodat Application Insights end-to-end zichtbaarheid kan bieden voor HTTP- en Service Bus-grenzen. Gebruik deze installatie om de activiteiten van uw toepassing effectief in services te bewaken en te analyseren.
Het voorbeeld van de moderne web-app maakt gebruik van de Azure Monitor-distributie van OpenTelemetry (Azure.Monitor.OpenTelemetry.AspNetCore
). Er worden meer instrumentatiepakketten gebruikt voor SQL-, Redis- en Azure SDK-clients. OpenTelemetry is geconfigureerd in de voorbeeldservice voor ticketrendering van moderne web-apps, zoals deze:
builder.Logging.AddOpenTelemetry(o =>
{
o.IncludeFormattedMessage = true;
o.IncludeScopes = true;
});
builder.Services.AddOpenTelemetry()
.UseAzureMonitor(o => o.ConnectionString = appInsightsConnectionString)
.WithMetrics(metrics =>
{
metrics.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddRuntimeInstrumentation();
})
.WithTracing(tracing =>
{
tracing.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddSource("Azure.*");
});
De builder.Logging.AddOpenTelemetry
methode routeert alle logboekregistraties via OpenTelemetry, waardoor consistente tracering en logboekregistratie in de toepassing wordt gegarandeerd. Door OpenTelemetry-services te registreren bij builder.Services.AddOpenTelemetry
, wordt de toepassing ingesteld voor het verzamelen en exporteren van diagnostische gegevens, die vervolgens worden verzonden naar Application Insights via UseAzureMonitor
. Bovendien wordt client-instrumentatie voor onderdelen zoals Service Bus- en HTTP-clients geconfigureerd WithMetrics
en WithTracing
wordt automatische metrische gegevens en traceringsverzameling ingeschakeld zonder dat wijzigingen in het bestaande clientgebruik nodig zijn, alleen een update naar de configuratie.
Configuratierichtlijnen
De volgende secties bevatten richtlijnen voor het implementeren van de configuratie-updates. Elke sectie wordt uitgelijnd met een of meer pijlers van het Well-Architected Framework.
Configuratie | Betrouwbaarheid (RE) | Beveiliging (SE) | Kostenoptimalisatie (CO) | Operational Excellence (OE) | Prestatie-efficiëntie (PE) | Goed ontworpen frameworkprincipes ondersteunen |
---|---|---|---|---|---|---|
Verificatie en autorisatie configureren | ✔ | ✔ | SE:05 OE:10 |
|||
Onafhankelijke automatische schaalaanpassing implementeren | ✔ | ✔ | ✔ | RE:06 CO:12 PE:05 |
||
Service-implementatie containeriseren | ✔ | ✔ | CO:13 PE:09 PE:03 |
Verificatie en autorisatie configureren
Als u verificatie en autorisatie wilt configureren voor nieuwe Azure-services (workloadidentiteiten) die u aan de web-app toevoegt, volgt u deze aanbevelingen:
Gebruik beheerde identiteiten voor elke nieuwe service. Elke onafhankelijke service moet een eigen identiteit hebben en beheerde identiteiten gebruiken voor service-naar-service-verificatie. Beheerde identiteiten elimineren de noodzaak om referenties in uw code te beheren en het risico op het lekken van referenties te verminderen. Ze helpen u te voorkomen dat gevoelige informatie, zoals verbindingsreeks s, in uw code- of configuratiebestanden wordt gebruikt.
Ververleent minimale bevoegdheden aan elke nieuwe service. Wijs alleen de benodigde machtigingen toe aan elke nieuwe service-id. Als een identiteit bijvoorbeeld alleen naar een containerregister hoeft te pushen, geeft u deze geen pull-machtigingen. Controleer deze machtigingen regelmatig en pas deze indien nodig aan. Gebruik verschillende identiteiten voor verschillende rollen, zoals implementatie en de toepassing. Dit beperkt de mogelijke schade als één identiteit wordt aangetast.
Infrastructuur als code (IaC) gebruiken. Gebruik Bicep of vergelijkbare IaC-hulpprogramma's om uw cloudresources te definiëren en te beheren. IaC zorgt voor een consistente toepassing van beveiligingsconfiguraties in uw implementaties en stelt u in staat om de installatie van uw infrastructuur te beheren.
Volg deze aanbevelingen om verificatie en autorisatie voor gebruikers (gebruikersidentiteiten) te configureren:
Geef gebruikers minimale bevoegdheden. Net als bij services moet u ervoor zorgen dat gebruikers alleen de machtigingen krijgen die ze nodig hebben om hun taken uit te voeren. Controleer en pas deze machtigingen regelmatig aan.
Voer regelmatig beveiligingscontroles uit. Controleer uw beveiligingsconfiguratie regelmatig en controleer deze. Zoek naar onjuiste configuraties of onnodige machtigingen en corrigeer ze onmiddellijk.
De referentie-implementatie maakt gebruik van IaC om beheerde identiteiten toe te wijzen aan toegevoegde services en specifieke rollen aan elke identiteit. Hiermee definieert u rollen en machtigingen voor implementatie (containerRegistryPushRoleId
), toepassingseigenaar (containerRegistryPushRoleId
) en Container Apps-toepassing () (containerRegistryPullRoleId
zie de volgende code).
roleAssignments: \[
{
principalId: deploymentSettings.principalId
principalType: deploymentSettings.principalType
roleDefinitionIdOrName: containerRegistryPushRoleId
}
{
principalId: ownerManagedIdentity.outputs.principal_id
principalType: 'ServicePrincipal'
roleDefinitionIdOrName: containerRegistryPushRoleId
}
{
principalId: appManagedIdentity.outputs.principal_id
principalType: 'ServicePrincipal'
roleDefinitionIdOrName: containerRegistryPullRoleId
}
\]
De referentie-implementatie wijst de beheerde identiteit toe als de nieuwe Container Apps-identiteit bij de implementatie (zie de volgende code).
module renderingServiceContainerApp 'br/public:avm/res/app/container-app:0.1.0' = {
name: 'application-rendering-service-container-app'
scope: resourceGroup()
params: {
// Other parameters omitted for brevity
managedIdentities: {
userAssignedResourceIds: [
managedIdentity.id
]
}
}
}
Onafhankelijke automatische schaalaanpassing configureren
Het patroon Moderne web-app begint met het opsplitsen van de monolithische architectuur en introduceert serviceontdubbeling. Wanneer u een web-app-architectuur loskoppelt, kunt u losgekoppelde services onafhankelijk schalen. Door de Azure-services te schalen ter ondersteuning van een onafhankelijke web-app-service, in plaats van een volledige web-app, worden de schaalkosten geoptimaliseerd terwijl aan de eisen wordt tegemoet getreden. Volg deze aanbevelingen om containers automatisch te schalen:
Gebruik stateless services. Zorg ervoor dat uw services staatloos zijn. Als uw .NET-toepassing de sessiestatus van het proces bevat, moet u deze externaliseren naar een gedistribueerde cache zoals Redis of een database zoals SQL Server.
Configureer regels voor automatisch schalen. Gebruik de configuraties voor automatisch schalen die de meest rendabele controle over uw services bieden. Voor containerservices biedt schaalaanpassing op basis van gebeurtenissen, zoals Kubernetes Event Driven Autoscaler (KEDA), vaak gedetailleerde controle, zodat u kunt schalen op basis van metrische gegevens van gebeurtenissen. Container Apps en AKS ondersteunen KEDA. Voor services die KEDA niet ondersteunen, zoals App Service, gebruikt u de functies voor automatisch schalen die door het platform zelf worden geleverd. Deze functies omvatten vaak schalen op basis van regels op basis van metrische gegevens of HTTP-verkeer.
Configureer minimale replica's. Als u een koude start wilt voorkomen, configureert u instellingen voor automatisch schalen om minimaal één replica te behouden. Een koude start is wanneer u een service initialiseert vanuit een gestopte status, waardoor vaak een vertraagd antwoord ontstaat. Als het minimaliseren van de kosten een prioriteit is en u koude startvertragingen kunt tolereren, stelt u het minimumaantal replica's in op 0 bij het configureren van automatische schaalaanpassing.
Configureer een afkoelperiode. Pas een geschikte afkoelperiode toe om een vertraging tussen schaalgebeurtenissen te introduceren. Het doel is om overmatige schaalactiviteiten te voorkomen die worden geactiveerd door tijdelijke belastingpieken.
Schaalaanpassing op basis van wachtrijen configureren. Als uw toepassing gebruikmaakt van een berichtenwachtrij zoals Service Bus, configureert u de instellingen voor automatisch schalen om te schalen op basis van de lengte van de wachtrij met aanvraagberichten. De scaler is erop gericht om één replica van de service te onderhouden voor elke N-berichten in de wachtrij (naar boven afgerond).
De referentie-implementatie maakt bijvoorbeeld gebruik van de Service Bus KEDA-schaalfunctie om de container-app te schalen op basis van de lengte van de wachtrij. De service-bus-queue-length-rule
service wordt geschaald op basis van de lengte van een opgegeven Service Bus-wachtrij. De messageCount
parameter is ingesteld op 10, dus de schaalschaal heeft één servicereplica voor elke 10 berichten in de wachtrij. De scaleMaxReplicas
parameters scaleMinReplicas
stellen het maximum- en minimumaantal replica's voor de service in. Het queue-connection-string
geheim, dat de verbindingsreeks voor de Service Bus-wachtrij bevat, wordt opgehaald uit Azure Key Vault. Dit geheim wordt gebruikt om de scaler te verifiëren bij de Service Bus.
scaleRules: [
{
name: 'service-bus-queue-length-rule'
custom: {
type: 'azure-servicebus'
metadata: {
messageCount: '10'
namespace: renderRequestServiceBusNamespace
queueName: renderRequestServiceBusQueueName
}
auth: [
{
secretRef: 'render-request-queue-connection-string'
triggerParameter: 'connection'
}
]
}
}
]
scaleMaxReplicas: 5
scaleMinReplicas: 0
Service-implementatie containeriseren
Containerisatie betekent dat alle afhankelijkheden voor de te functioneren app worden ingekapseld in een lichtgewicht installatiekopie die betrouwbaar kan worden geïmplementeerd op een breed scala aan hosts. Volg deze aanbevelingen om de implementatie in containers te plaatsen:
Domeingrenzen identificeren. Begin met het identificeren van de domeingrenzen binnen uw monolithische toepassing. Hiermee kunt u bepalen welke onderdelen van de toepassing u in afzonderlijke services kunt extraheren.
Docker-installatiekopieën maken. Wanneer u Docker-installatiekopieën voor uw .NET-services maakt, gebruikt u beitelde basisinstallatiekopieën. Deze installatiekopieën bevatten alleen de minimale set pakketten die nodig zijn om .NET uit te voeren, waardoor zowel de pakketgrootte als het kwetsbaarheid voor aanvallen wordt geminimaliseerd.
Gebruik Dockerfiles met meerdere fasen. Implementeer Dockerfiles met meerdere fasen om buildtime-assets te scheiden van de runtimecontainerinstallatiekopieën. Het helpt om uw productie-installatiekopieën klein en veilig te houden.
Uitvoeren als een niet-basisgebruiker. Voer uw .NET-containers uit als een niet-basisgebruiker (via gebruikersnaam of UID, $APP_UID) om te voldoen aan het principe van minimale bevoegdheden. Hiermee worden de mogelijke effecten van een geïnfecteerde container beperkt.
Luister op poort 8080. Wanneer u als niet-basisgebruiker werkt, configureert u uw toepassing om te luisteren op poort 8080. Het is een algemene conventie voor niet-basisgebruikers.
Afhankelijkheden inkapselen. Zorg ervoor dat alle afhankelijkheden voor de te functioneren app zijn ingekapseld in de Docker-containerinstallatiekopieën. Dankzij inkapseling kan de app betrouwbaar worden geïmplementeerd op een breed scala aan hosts.
Kies de juiste basisafbeeldingen. De basisinstallatiekopieën die u kiest, zijn afhankelijk van uw implementatieomgeving. Als u bijvoorbeeld implementeert in Container Apps, moet u Linux Docker-installatiekopieën gebruiken.
De referentie-implementatie maakt bijvoorbeeld gebruik van een buildproces met meerdere fasen . In de eerste fasen wordt de toepassing gecompileerd en gebouwd met behulp van een volledige SDK-installatiekopieën (mcr.microsoft.com/dotnet/sdk:8.0-jammy
). De uiteindelijke runtime-installatiekopieën worden gemaakt op basis van de chiseled
basisinstallatiekopieën, die de SDK en buildartefacten uitsluiten. De service wordt uitgevoerd als een niet-basisgebruiker (USER $APP_UID
) en maakt poort 8080 beschikbaar. De afhankelijkheden die nodig zijn om de toepassing te laten werken, worden opgenomen in de Docker-installatiekopie, zoals wordt aangetoond door de opdrachten voor het kopiëren van projectbestanden en het herstellen van pakketten. Het gebruik van installatiekopieën op basis van Linux (mcr.microsoft.com/dotnet/aspnet:8.0-jammy-chiseled
) zorgt voor compatibiliteit met Container Apps, waarvoor Linux-containers zijn vereist voor implementatie.
# Build in a separate stage to avoid copying the SDK into the final image
FROM mcr.microsoft.com/dotnet/sdk:8.0-jammy AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
# Restore packages
COPY ["Relecloud.TicketRenderer/Relecloud.TicketRenderer.csproj", "Relecloud.TicketRenderer/"]
COPY ["Relecloud.Messaging/Relecloud.Messaging.csproj", "Relecloud.Messaging/"]
COPY ["Relecloud.Models/Relecloud.Models.csproj", "Relecloud.Models/"]
RUN dotnet restore "./Relecloud.TicketRenderer/Relecloud.TicketRenderer.csproj"
# Build and publish
COPY . .
WORKDIR "/src/Relecloud.TicketRenderer"
RUN dotnet publish "./Relecloud.TicketRenderer.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
# Chiseled images contain only the minimal set of packages needed for .NET 8.0
FROM mcr.microsoft.com/dotnet/aspnet:8.0-jammy-chiseled AS final
WORKDIR /app
EXPOSE 8080
# Copy the published app from the build stage
COPY --from=build /app/publish .
# Run as non-root user
USER $APP_UID
ENTRYPOINT ["dotnet", "./Relecloud.TicketRenderer.dll"]
De referentie-implementatie implementeren
Implementeer de referentie-implementatie van het moderne web-app-patroon voor .NET. Er zijn instructies voor zowel de ontwikkeling als de productie-implementatie in de opslagplaats. Nadat u de implementatie hebt uitgevoerd, kunt u ontwerppatronen simuleren en observeren.
Afbeelding 3. Architectuur van de referentie-implementatie. Download een Visio-bestand van deze architectuur.