Bewerken

Delen via


Gridwich-bewerkingen voor Azure Storage

Azure Storage

Gridwich Azure Storage Service, Gridwich.SagaParticipants.Storage.AzureStorage, biedt blob- en containerbewerkingen voor Azure Storage-accounts die zijn geconfigureerd voor Gridwich. Voorbeelden van opslagbewerkingen zijn Blob maken, Container verwijderen, Blob kopiëren of Opslaglaag wijzigen.

Gridwich vereist dat de opslagmechanismen werken voor zowel Azure Storage-blok-blobs als containers. Met afzonderlijke klassen en opslagservicebewerkingen voor blobs en containers is er geen dubbelzinnigheid over of een bepaalde opslagbewerking betrekking heeft op een blob of een container. Dit artikel is van toepassing op zowel blobs als containers, behalve waar vermeld.

Gridwich maakt de meeste opslagbewerkingen beschikbaar voor externe systemen binnen de Storage.AzureStorage saga-deelnemer. Andere saga-deelnemers gebruiken de opslagservice voor taken zoals het kopiëren van blobs tussen verschillende containers of accounts wanneer ze coderingswerkstromen instellen.

In dit artikel wordt beschreven hoe de Gridwich Azure Storage-service voldoet aan de oplossingsvereisten en kan worden geïntegreerd met mechanismen zoals gebeurtenis-handlers. Koppelingen verwijzen naar de bijbehorende broncode, die uitgebreider commentaar bevat over de containers, klassen en mechanismen.

Azure Storage SDK

Gridwich maakt gebruik van klassen van de Azure Storage SDK om te communiceren met Azure Storage, in plaats van HAND-aanvragen te maken. Binnen de opslagprovider beheren de klassen SDK BlobBaseClient en BlobContainerClient opslagaanvragen.

Deze SDK-clientklassen bieden momenteel alleen indirecte toegang tot de twee HTTP-headers Gridwich die moet worden bewerkt, x-ms-client-request-id voor de bewerkingscontext en ETag voor objectversie.

In Gridwich dispenses een paar providerklassen BlobBaseClientProvider en BlobContainerClientProvider functionaliteit in eenheden genaamd sleeves. Zie Opslagmouwen voor meer informatie over mouwen.

In het volgende diagram ziet u de structuur van de SDK- en Gridwich-klassen en hoe exemplaren zich met elkaar verhouden. De pijlen geven aan 'heeft een verwijzing naar'.

Diagram met relaties tussen de Storage SDK-klassen van het clientobjectexemplaren.

Pijplijnbeleid

U stelt de hook in om de HTTP-headers te bewerken als een exemplaar van een pijplijnbeleid wanneer u het clientexemplaren maakt. U kunt dit beleid alleen instellen tijdens het maken van het clientexemplaren en u kunt het beleid niet wijzigen. De code van de opslagprovider met behulp van de client moet de headerwaarden kunnen bewerken tijdens de uitvoering. De uitdaging is om de opslagprovider en pijplijn schoon te laten werken.

Zie de klasse BlobClientPipelinePolicy voor het gridwich-pijplijnbeleid.

Opslagservice opslaan in cache

De instelling en verificatie van TCP-verbindingen maken overhead wanneer een EXEMPLAAR van een SDK-clientobject de eerste aanvraag naar Azure Storage verzendt. Meerdere aanroepen naar dezelfde blob in een externe systeemaanvraag, bijvoorbeeld Metagegevens ophalen, vervolgens Blob verwijderen, de overhead optellen.

Om overhead te beperken, onderhoudt Gridwich een cache van één clientexemplaren voor elke opslagblob of container, afhankelijk van de SDK-klassen die door de context van de bewerking worden gebruikt. Gridwich behoudt dit clientexemplaren en kan het exemplaar gebruiken voor meerdere Azure Storage-bewerkingen op dezelfde blob of container voor de duur van een externe systeemaanvraag.

Voor de door Azure SDK geleverde clientklassen moeten SDK-clientobjectexemplaren specifiek zijn voor één blob of container tijdens het maken. De exemplaren zijn ook niet gegarandeerd veilig voor gelijktijdig gebruik op verschillende threads. Aangezien een bewerkingscontext één aanvraag vertegenwoordigt, baseert Gridwich caching op de combinatie van blob- of containernaam met bewerkingscontext.

Voor dit exemplaar is in combinatie met de Clientstructuur van de Azure Storage SDK aanvullende ondersteuningscode vereist om de efficiëntie en de duidelijkheid van code te verdelen.

Contextargument

Bijna alle Gridwich Storage Service-bewerkingen vereisen een speciaal contextargument van het type StorageClientProviderContext. Dit contextargument voldoet aan de volgende vereisten:

  • Biedt het externe systeem antwoorden, waaronder de unieke JSON-bewerkingscontextwaarde per aanvraag die door het externe systeem is opgegeven in de Gridwich-aanvraag. Zie De context van de bewerking voor meer informatie.

  • Hiermee kunnen bellers van de Storage-service, zoals Gridwich-gebeurtenishandlers, bepalen welke antwoorden zichtbaar zijn voor het externe systeem. Met dit besturingselement voorkomt u dat de service het externe systeem overspoelt met irrelevante meldingsevenementen. Zie Context dempen voor meer informatie.

  • Voldoet aan Azure Storage-conventies om coherente aanvragen en antwoorden in een omgeving te garanderen die een combinatie van parallelle lezers en schrijvers mogelijk maakt. Ondersteunt bijvoorbeeld ETag-tracering. Zie ETags voor meer informatie.

Opslagcontext

De context voor zowel de blob- als containeropslagtypen is de StorageClientProviderContext, die er als volgt uitziet:

    string  ClientRequestID { get; }
    JObject ClientRequestIdAsJObject { get; }
    bool    IsMuted { get; set; }
    string  ETag { get; set; }
    bool    TrackingETag { get; set; }

De eerste twee eigenschappen zijn verschillende weergaven van de bewerkingscontext die is gebruikt voor het initialiseren van het StorageClientProviderContext-exemplaar . De klasse heeft verschillende constructors, waaronder een kopieerconstructor. Aanvullende methoden zijn onder andere ResetTohet toestaan van in-place statusduplicatie en een statische CreateSafe methode om ervoor te zorgen dat problematische initialisaties geen uitzonderingen genereren.

De klasse bevat ook speciale verwerking voor het maken van contexten op basis van GUID's en lege tekenreeksen. Voor de Azure Storage-meldingshandlers voor blob gemaakt en verwijderd, die ook meldingen verwerken die afkomstig zijn van externe agents, is het GUID-formulier vereist.

Context dempen

De IsMuted eigenschap bepaalt of de toepassing verwacht dat de service resulterende meldingen weer naar de aanroeper publiceert, bijvoorbeeld naar het externe systeem. In een gedempte bewerking publiceert de service geen resulterende gebeurtenissen.

Een voorbeeld hiervan zijn blobkopieën die door een encoder worden uitgevoerd om blobs in Azure Storage als invoer voor een coderingstaak te rangschikken. Het externe systeem maakt zich geen zorgen over deze details, maar alleen over de status van de coderingstaak en waar de gecodeerde uitvoer kan worden opgehaald. Om deze problemen weer te geven, gebruikt u de encoder:

  1. Hiermee maakt u bijvoorbeeld een niet-gedempte opslagcontext op basis van de aanvraagbewerkingscontext ctxNotMuted.

  2. Hiermee maakt u een gedempte opslagcontext, bijvoorbeeld ctxMutedmet behulp van de constructor voor het kopiëren van contextklassen of het maken van een nieuw exemplaar. Beide opties hebben dezelfde waarde voor de bewerkingscontext.

  3. Hiermee geeft u ctxMuted op voor opslagbewerkingen die betrokken zijn bij de installatie voor codering. Het externe systeem ziet geen indicatie van deze bewerkingen.

  4. Hiermee geeft u de ctxNotMuted context op voor opslagbewerkingen die de voltooiing van de codering weerspiegelen, bijvoorbeeld het kopiëren van een uitvoerbestand naar een doelcontainer. Gridwich-handlers publiceren de resulterende Azure Storage-meldings gebeurtenissen naar het externe systeem.

De beller bepaalt de ultieme zichtbaarheid van bewerkingen. Zowel gedempte als niet-gedempte bewerkingen zijn gebaseerd op een equivalente operationContext waarde. Het doel van het dempen van contexten is om het gemakkelijker te maken om een diagnose van problemen uit te voeren vanuit logboeken voor gebeurtenistracering, omdat het mogelijk is om de opslagbewerkingen te zien die betrekking hebben op een aanvraag, ongeacht de status van het dempen van bewerkingen.

De ResponseBaseDTO heeft een booleaanse eigenschap DoNotPublish, die gebeurtenisverzending gebruikt om de definitieve beslissing te bepalen over het publiceren. Gebeurtenisverzending stelt DoNotPublish de eigenschap op zijn beurt in op basis van de IsMuted eigenschap van de context.

De service verzendt de dempingsinstelling naar Azure Storage, waarmee de clientRequestId gebeurtenissen voor opslagmeldingen worden ingesteld die worden gepresenteerd aan de twee Gridwich-handlers, Gemaakt en Verwijderd. Deze twee handlers zijn ingesteld DoNotPublish om de door de aanroeper aangevraagde demping weer te geven.

ETags voor doelconsistentie

Azure Storage maakt gebruik van de HTTP-header ETag voor aanvraagreeksen die de doelconsistentie moeten hebben. Een voorbeeld is om ervoor te zorgen dat een blob niet is gewijzigd tussen het ophalen van metagegevens en het bijwerken van metagegevensopslagbewerkingen .

Deze header heeft een ondoorzichtige waarde waarvan de interpretatie is dat als de headerwaarde verandert, het onderliggende object ook is gewijzigd om het te laten overeenkomen met het standaard HTTP-gebruik. Als een aanvraag de huidige ETag waarde voor het object verzendt en deze niet overeenkomt met de huidige opslagservicewaarde ETag , mislukt de aanvraag onmiddellijk. Als de aanvraag geen waarde bevat ETag , slaat Azure Storage die controle over en blokkeert de aanvraag niet.

ETags in de opslagservice

Voor Gridwich is het ETag een interne details tussen de Gridwich Storage-service en Azure Storage. Er hoeft geen andere code op de hoogte te zijn van de ETag. De Opslagservice gebruikt de ETag for-reeksen, zoals de metagegevens van de blob ophalen, blobbewerkingen verwijderen voor het verwerken van een BlobDelete Event aanvraag. Als u de ETag bewerking Blob verwijderen gebruikt, is deze exact dezelfde versie van de blob als de bewerking Metagegevens ophalen.

Ga als volgt te werk om het ETag voor het voorgaande voorbeeld te gebruiken:

  1. Verzend de aanvraag Metagegevens ophalen met een lege ETagaanvraag.
  2. Sla de ETag waarde op uit het antwoord.
  3. Voeg de opgeslagen ETag waarde toe aan de aanvraag Blob verwijderen.

Als de twee ETag waarden verschillen, mislukt de verwijderbewerking. De fout impliceert dat een andere bewerking de blob tussen stap 2 en 3 heeft gewijzigd. Herhaal het proces uit stap 1.

ETag is een parameter van constructors en een tekenreekseigenschap van de klasse StorageClientProviderContext. Alleen de Gridwich-specifieke BlobClientPipelinePolicy bewerkt de ETag waarde.

ETag-gebruik beheren

De TrackingETag eigenschap bepaalt of de ETag waarde voor de volgende aanvraag moet worden verzonden. De waarde true betekent dat de service een ETag if-waarde verzendt als deze beschikbaar is.

Een Azure Storage-aanvraag met een ETag waarde die niet overeenkomt met de onderwerp-blob of container, resulteert in een mislukte bewerking. Deze fout is standaard, omdat ETag dit de standaard HTTP-manier is om 'de exacte versie van de aanvraag die op de aanvraag is gericht' uit te drukken. Aanvragen kunnen de TrackingETag eigenschap bevatten om aan te geven dat de ETags eigenschap moet overeenkomen of niet de TrackingETag eigenschap bevatten om aan te geven dat de ETag waarden niet van belang zijn.

De pijplijn haalt altijd een ETag waarde op uit een Azure Storage-bewerking als deze aanwezig is in dat REST-antwoord. De pijplijn werkt altijd de contexteigenschap ETag bij, indien mogelijk, vanaf de laatste bewerking. De TrackingETag vlag bepaalt alleen of de volgende aanvraag van hetzelfde clientexemplaren de waarde van de ETag eigenschap verzendt. Als de ETag waarde null of leeg is, wordt met de huidige aanvraag geen HTTP-waarde ETag ingesteld, ongeacht de waarde van TrackingETag.

Opbergmouwen

Gridwich vereist dat de opslagmechanismen werken voor zowel Azure Storage-blok-blobs als containers. Er zijn verschillende klassen en opslagservicebewerkingen voor blobs en containers, dus er is geen dubbelzinnigheid over of een bepaalde opslagbewerking betrekking heeft op een blob of een container.

Een paar providerklassen, één voor blobs en één voor containers, dispenseer de twee sets functionaliteit in eenheden die mouwen worden genoemd. Sleeves bevatten exemplaren van opslaghulpklassen die deel uitmaken van de Azure SDK. Als u de opslagservice initialiseert, worden de providers gemaakt en worden deze rechtstreeks beschikbaar gemaakt voor opslagservicemethoden.

Mouwstructuur

De hoes is een container voor het SDK Client-objectexemplaren en een opslagcontext. De functies van de opslagprovider verwijzen via de twee eigenschappen Client en Context. Er is een mouwtype voor blobs en een andere voor containers, die eigenschappen van het type BlobBaseClienten BlobContainerClient, respectievelijk, hebben.Client

De algemene mouwstructuur voor blobs ziet er als volgt uit:

BlobBaseClient Client { get; }
BlobServiceClient Service { get; }
StorageClientProviderContext Context { get; }

Het Service pand op de hoes is een gemak. Voor sommige van de laatste coderingsprogrammabewerkingen die gebruikmaken van de SDK BlobServiceClient-klasse zijn opslagaccountreferenties vereist. Deze vereiste heeft geleid tot het toevoegen van een serviceclientexemplaren aan de twee bestaande mouwtypen in plaats van een afzonderlijke provider te produceren.

Gebruik van mouwen

De clientopslagproviders dispense sleeve-exemplaren. De code van de opslagservice ziet er ongeveer uit als de volgende geannoteerde codereeks, met typen die voor de duidelijkheid zijn gespeld:

public bool DeleteBlob(Uri sourceUri, StorageClientProviderContext context)
{
    . . .
    StorageBlobClientSleeve sleeve = _blobBaseClientProvider.GetBlobBaseClientForUri(sourceUri, context); // Line A
    BlobProperties propsIncludingMetadata = sleeve.Client.GetProperties(); // Line B
    sleeve.Context.TrackingETag = true;   // Send ETag from GetProperties()
    var wasDeleted = sleeve.Client.DeleteBlob(); // Line C
    sleeve.Context.TrackingETag = false;
    var someResult = sleeve.Client.AnotherOperation(); // Line D
    . . .
}
  1. Gridwich vult de bewerkingscontext automatisch in de mouwcontext op regel A. TrackingETag is standaard ingesteld op false.
  2. Na regel B bevat sleeve.Context u de ETag van regel A en behoudt u dezelfde ClientRequestID waarde.
  3. Regel C verzendt zowel de ETag waarde van regel B als de ClientRequestId.
  4. Na regel C heeft de context een nieuwe ETag waarde, zoals wordt geretourneerd in het Delete() antwoord.
  5. Regel D verzendt ETag geen waarde in de aanvraag voor AnotherOperation().
  6. Na regel D heeft de context een nieuwe ETag waarde, zoals wordt geretourneerd in het AnotherOperation() antwoord.

De opslagservice is momenteel ingesteld als Transient in de configuratie van afhankelijkheidsinjectie, wat impliceert dat de cache op basis van de mouwen per aanvraag is. Zie Opslagservice en afhankelijkheidsinjectie voor meer informatie.

Alternatieven voor Storage Service

In de volgende secties worden alternatieve benaderingen beschreven die geen deel uitmaken van de huidige Gridwich-opslagoplossing.

Het pijplijnbeleid verbergen via subklassen

Met subklassen van de SDK-clienttypen worden twee eenvoudige eigenschappen toegevoegd aan de client, één voor elke HTTP-headerwaarde, om de interactie met het pijplijnbeleid volledig te verbergen. Maar vanwege een diepe Moq-fout is het niet mogelijk om eenheidstests te maken via mock deze afgeleide typen. Gridwich gebruikt Moq, dus deze methode voor subklassen is niet gebruikt.

De Moq-fout heeft betrekking op het verkeerdhanden van subklassen voor meerdere assembly's in aanwezigheid van virtuele functies binnen het bereik. De SDK-clientklassen maken gebruik van virtuele functies binnen het bereik met interne bereiktypen die onzichtbaar zijn voor normale externe gebruikers. Wanneer Moq probeert een mock van de subklassen te maken, die zich in een van de Gridwich-assembly's bevindt, mislukt deze tijdens de testuitvoering omdat de interne bereik-virtuals niet kunnen worden gevonden in de SDK-clientklassen waaruit de Gridwich-klassen worden afgeleid. Er is geen tijdelijke oplossing zonder wijzigingen in de proxygeneratie van Moq Castle.

Opslagservice en afhankelijkheidsinjectie

Gridwich registreert de Opslagservice momenteel als een Transient afhankelijkheidsinjectieservice. Dat wil gezegd, telkens wanneer afhankelijkheidsinjectie wordt gevraagd voor de service, wordt er een nieuw exemplaar gemaakt. De huidige code moet ook correct werken als de registratie wordt gewijzigd Scoped, wat betekent dat er één exemplaar per aanvraag wordt gebruikt, bijvoorbeeld de aanvraag van het externe systeem.

Er zijn echter problemen als de registratie wordt gewijzigd Singletonin, één exemplaar in de Gridwich Function-app. Het Gridwich-cachingmechanisme voor mouwen en gegevens bytebereiken maakt vervolgens geen onderscheid tussen verschillende aanvragen. Het cachemodel is ook geen uitcheckmodel, dus Gridwich verwijdert het exemplaar niet uit de cache terwijl het in gebruik is. Omdat de SDK-clientklassen niet gegarandeerd thread-veilig zijn, zou coördinatie veel wijzigingen vereisen.

Wijzig om deze redenen de Gridwich Storage-service niet in Singleton registratie van afhankelijkheidsinjectie. Gridwich volgt deze regel in registratie van afhankelijkheidsinjectie en bevat een eenheidstest, CheckThatStorageServiceIsNotASingleton, om deze af te dwingen.

Volgende stappen

Productdocumentatie:

Microsoft Learn-modules: