A Gridwich Azure Storage szolgáltatás, a Gridwich.SagaParticipants.Storage.AzureStorage blob- és tárolóműveleteket biztosít a Gridwichhez konfigurált Azure Storage-fiókokhoz. Ilyenek például a blobok létrehozása, a tároló törlése, a blob másolása vagy a tárolási szint módosítása.
A Gridwich megköveteli, hogy a tárolási mechanizmusai mind az Azure Storage blokkblobok, mind a tárolók esetében működjenek. A blobok és tárolók eltérő osztályai és tárolási szolgáltatásműveletei miatt nincs kétértelműség abban, hogy egy adott tárolási művelet egy blobhoz vagy egy tárolóhoz kapcsolódik-e. Ez a cikk a blobokra és a tárolókra is vonatkozik, kivéve, ha fel van jegyezve.
A Gridwich a legtöbb tárolási műveletet külső rendszerek számára teszi elérhetővé a Storage.AzureStorage
saga résztvevőn belül. Más saga-résztvevők a tárolási szolgáltatást olyan feladatokhoz használják, mint a blobok másolása különböző tárolók vagy fiókok között kódolási munkafolyamatok beállításakor.
Ez a cikk azt ismerteti, hogy a Gridwich Azure Storage szolgáltatás hogyan felel meg a megoldási követelményeknek, és hogyan integrálható olyan mechanizmusokkal, mint az eseménykezelők. A hivatkozások a megfelelő forráskódra mutatnak, amely részletesebb megjegyzéseket tartalmaz a tárolókról, osztályokról és mechanizmusokról.
Azure Storage SDK
A Gridwich az Azure Storage SDK osztályait használja az Azure Storage-ral való interakcióhoz, ahelyett, hogy REST-kéréseket hoznál össze. A tárolószolgáltatón belül az SDK BlobBaseClient és a BlobContainerClient osztály kezeli a tárolási kérelmeket.
Ezek az SDK-ügyfélosztályok jelenleg csak közvetett hozzáférést biztosítanak a Gridwich által módosítani kívánt két HTTP-fejléchez a x-ms-client-request-id
műveleti környezethez és ETag
az objektumverzióhoz.
A Gridwichben egy szolgáltatóosztálypár biztosítja a BlobBaseClientProvider és a BlobContainerClientProvider funkciót a hüvelyek nevű egységekben. Az ujjal kapcsolatos részletekért tekintse meg a Tárolóujjak című témakört.
Az alábbi ábra az SDK- és Gridwich-osztályok szerkezetét, valamint a példányok egymáshoz való viszonyát mutatja be. A nyilak azt jelzik, hogy "van egy hivatkozás".
Folyamatházirend
Az ügyfélpéldány létrehozásakor a horogot úgy állítja be, hogy a HTTP-fejléceket folyamatszabályzat-példányként módosítsa. Ezt a szabályzatot csak az ügyfélpéldány létrehozásakor állíthatja be, és nem módosíthatja a szabályzatot. Az ügyfelet használó tárolószolgáltató kódjának képesnek kell lennie a fejlécértékek módosítására a végrehajtás során. A kihívás az, hogy a tárolószolgáltató és a folyamat megfelelően működjön együtt.
A Gridwich-folyamat házirendje a BlobClientPipelinePolicy osztályban található.
Storage-szolgáltatás gyorsítótárazása
A TCP-kapcsolat létrehozása és hitelesítése többletterhelést okoz, amikor egy SDK-ügyfélobjektum-példány elküldi az első kérését az Azure Storage-nak. Egy külső rendszerkérésben több hívás is ugyanarra a blobra, például metaadatok lekérése, majd blob törlése, ami a többletterhelést is súlyosbítja.
A többletterhelés csökkentése érdekében a Gridwich minden tárolóblobhoz vagy tárolóhoz egy ügyfélpéldány gyorsítótárát tárolja a műveleti környezet által használt SDK-osztályoktól függően. A Gridwich megtartja ezt az ügyfélpéldányt, és több Azure Storage-művelethez is használhatja ugyanazt a blobot vagy tárolót egy külső rendszerkérés időtartamára.
Az Azure SDK által biztosított ügyfélosztályokhoz az SDK-ügyfélobjektum-példányoknak egyetlen blobra vagy tárolóra kell vonatkoznia a létrehozáskor. A példányok a különböző szálakon való egyidejű használatra sem garantáltak biztonságosan. Mivel a műveleti környezet egyetlen kérést jelöl, a Gridwich a blob- vagy tárolónév és a műveleti környezet kombinációján alapul.
Ez a példány az Azure Storage SDK-ügyfélstruktúrával kombinálva további támogatási kódot igényel a hatékonyság és a kód egyértelműségének egyensúlya érdekében.
Környezeti argumentum
Szinte az összes Gridwich Storage-szolgáltatásművelethez szükség van egy StorageClientProviderContext típusú speciális környezeti argumentumra. Ez a környezeti argumentum a következő követelményeknek felel meg:
Választ ad a külső rendszernek, amely tartalmazza a gridwichi kérelemben megadott egyedi JSON-alapú műveleti környezeti értéket. További információ: Műveleti környezet.
A Storage Service-hívók, például a Gridwich eseménykezelői szabályozni tudják, hogy mely válaszok láthatók a külső rendszer számára. Ez a vezérlő megakadályozza, hogy a szolgáltatás irreleváns értesítési eseményekkel elárasztsa a külső rendszert. További információ: Környezet némítás.
Megfelel az Azure Storage-konvencióknak, hogy egységes kéréseket és válaszokat biztosítsanak egy olyan környezetben, amely lehetővé teszi a párhuzamos olvasók és írók kombinációját. Támogatja például az ETag-nyomkövetést. További információ: ETags.
Tárolási környezet
A blob- és tárolótároló-típusok környezete a StorageClientProviderContext, amely a következőképpen néz ki:
string ClientRequestID { get; }
JObject ClientRequestIdAsJObject { get; }
bool IsMuted { get; set; }
string ETag { get; set; }
bool TrackingETag { get; set; }
Az első két tulajdonság a StorageClientProviderContext példány inicializálásához használt műveleti környezet különböző ábrázolása. Az osztály különböző konstruktorokkal rendelkezik, köztük másolatkonstruktorokkal. A további módszerek közé tartozik a ResetTo
helyi állapot duplikációjának engedélyezése, valamint egy statikus CreateSafe
módszer, amely biztosítja, hogy a problémás inicializációk ne okozhassanak kivételeket.
Az osztály speciális kezeléseket is tartalmaz a környezetek guid azonosítók és üres sztringek alapján történő létrehozásához. A létrehozott és törölt Blob Azure Storage-értesítéskezelőinek, amelyek a külső ügynököktől származó értesítéseket is feldolgozzák, a GUID-űrlapot kell megadniuk.
Környezeti némítás
A IsMuted
tulajdonság azt szabályozza, hogy az alkalmazás elvárja-e, hogy a szolgáltatás tegye közzé az eredményként kapott értesítéseket a hívónak, például a külső rendszernek. Elnémított művelet esetén a szolgáltatás nem teszi közzé az eredményként kapott eseményeket.
Ilyen például a blobmásolatok, amelyeket egy kódoló hajt végre, hogy a blobokat az Azure Storage-ban rendezze egy kódolási feladat bemeneteként. A külső rendszer nem foglalkozik ezekkel a részletekkel, csak a kódolási feladat állapotával és a kódolt kimenetek lekérésének helyével. A kódoló a következő szempontokat szeretné tükrözni:
Nem némított tárolási környezetet hoz létre például a kérelemműveleti környezet
ctxNotMuted
alapján.Elnémított tárolási környezetet hoz létre például
ctxMuted
a környezetosztály másolási konstruktorával vagy egy új példány létrehozásával. Mindkét beállítás ugyanazt a műveleti környezeti értéket fogja megadni.ctxMuted
Meghatározza a kódolás beállításában részt vevő tárolási műveleteket. A külső rendszer nem látja ezeknek a műveleteknek a előfordulását.Megadja a
ctxNotMuted
kódolás befejezését tükröző tárolási műveletek környezetét, például egy kimeneti fájl céltárolóba való másolását. A Gridwich-kezelők közzéteszik az eredményként kapott Azure Storage-értesítési eseményeket a külső rendszerben.
A hívó szabályozza a műveletek végső láthatóságát. A némított és a nem némított műveletek is egyenértékű operationContext
értéken alapulnak. A környezet némításának célja, hogy megkönnyítse a probléma diagnosztizálását az eseménykövetési naplókból, mivel a kérelemhez kapcsolódó tárolási műveletek a művelet elnémítási állapotától függetlenül megtekinthetők.
A ResponseBaseDTO logikai tulajdonságot DoNotPublish
használ, amelyet az eseményküldés a közzététel végleges eldöntéséhez használ. Az eseményküldés viszont a DoNotPublish
környezet tulajdonsága alapján állítja be a IsMuted
tulajdonságot.
A szolgáltatás továbbítja a némítási beállítást az Azure Storage-nak, amely ezután beállítja az clientRequestId
általa a két Gridwich-kezelőnek beszúrt tárolási értesítési eseményeket, létrehozva és törölve. Ez a két kezelő úgy van beállítva DoNotPublish
, hogy tükrözze a hívó által kért némítást.
ETags a célkonzisztenciához
Az Azure Storage a HTTP-fejlécet ETag
olyan kérésütemezésekhez használja, amelyeknek célkonzisztenciával kell rendelkezniük. Ilyen például annak biztosítása, hogy a blobok ne változtak a Metaadatok lekérése és a Metaadattár frissítése műveletek között.
A szokásos HTTP-használathoz igazodva ez az élőfej átlátszatlan értékkel rendelkezik, amelynek értelmezése szerint ha a fejléc értéke megváltozik, akkor a mögöttes objektum is módosult. Ha egy kérés elküldi az objektum aktuális ETag
értékét, és nem egyezik meg a Storage Service ETag
aktuális értékével, a kérés azonnal meghiúsul. Ha a kérés nem tartalmaz ETag
értéket, az Azure Storage kihagyja az ellenőrzést, és nem blokkolja a kérést.
ETags a Storage Service-ben
A Gridwich esetében ez ETag
egy belső részlet a Gridwich Storage szolgáltatás és az Azure Storage között. Nincs más kód, amelyről tudnia kell a ETag
. A Tárolási szolgáltatás olyan szekvenciákhoz használja, ETag
mint a Blob metaadatok lekérése, a Blob-műveletek törlése a BlobDelete Event
kérések feldolgozásához. ETag
Ezzel biztosítja, hogy a Blob törlése művelet pontosan ugyanazt a blobverziót célozza meg, mint a Metaadatok lekérése műveletet.
Az előző példa használata ETag
:
- Küldje el a Metaadatok lekérése kérést üresen
ETag
. - Mentse az
ETag
értéket a válaszból. - Adja hozzá a mentett
ETag
értéket a Blob törlése kérelemhez.
Ha a két ETag
érték eltér, a törlési művelet meghiúsul. A hiba azt jelenti, hogy egy másik művelet módosította a blobot a 2. és a 3. lépés között. Ismételje meg a folyamatot az 1. lépésben.
ETag
a konstruktorok paramétere és a StorageClientProviderContext osztály sztringtulajdonsága. Csak a Gridwich-specifikus BlobClientPipelinePolicy módosítja az ETag
értéket.
Az ETag használatának szabályozása
A TrackingETag
tulajdonság azt határozza meg, hogy a ETag
következő kérelemben elküldje-e az értéket. Az érték true
azt jelenti, hogy a szolgáltatás küld egy ETag
ha van elérhető.
A tárgy blobnak vagy tárolónak nem megfelelő értékkel rendelkező ETag
Azure Storage-kérések a művelet sikertelenségéhez vezetnek. Ez a hiba terv szerint történik, mert ETag
a szabványos HTTP-módszer a "pontos verzió, amelyet a kérés megcélzott". A kérelmek tartalmazhatják azt a TrackingETag
tulajdonságot, amely azt jelzi, hogy a ETags
tulajdonságnak egyeznie kell, vagy nem tartalmazza a TrackingETag
tulajdonságot annak jelzésére, hogy az ETag
értékek nem számítanak.
A folyamat mindig lekéri az ETag
értéket egy Azure Storage-műveletből, ha van ilyen a REST-válaszban. A folyamat mindig frissíti a környezeti ETag
tulajdonságot, ha lehetséges, az utolsó művelettel. A TrackingETag
jelölő csak azt szabályozza, hogy az ugyanabból az ügyfélpéldányból érkező következő kérés elküldi-e a ETag
tulajdonság értékét. Ha az ETag
érték null vagy üres, akkor az aktuális kérés nem állít be HTTP-értéketETag
, függetlenül attól, hogy az érték.TrackingETag
Tárolóhüvelyek
A Gridwich megköveteli, hogy a tárolási mechanizmusai mind az Azure Storage-blokkblobok, mind a tárolók esetében működjön. A blobokhoz és tárolókhoz különböző osztályok és Storage Service-műveletek tartoznak, így nem egyértelmű, hogy egy adott tárolási művelet egy blobhoz vagy egy tárolóhoz kapcsolódik-e.
Egy szolgáltatóosztálypár, egy blobhoz és egy tárolóhoz, kiadja a két funkciókészletet az ujjaknak nevezett egységekben. A hüvelyek olyan tárolási segédosztályokat tartalmaznak, amelyek az Azure SDK részét képezik. A Tárolási szolgáltatás inicializálása létrehozza a szolgáltatókat, és közvetlenül elérhetővé teszi őket a Storage Service metódusai számára.
Hüvelyszerkezet
A hüvely az SDK-ügyfélobjektum-példány és a tárolási környezet tárolója. A storage provider függvények a két tulajdonságon Client
keresztül hivatkoznak a hüvelyre és Context
a . Van egy hüvelytípus a blobokhoz, egy másik a tárolókhoz, amelyek típusBlobBaseClient
- ésBlobContainerClient
típustulajdonságokkal rendelkeznek.Client
A blobok általános hüvelyszerkezete a következőképpen néz ki:
BlobBaseClient Client { get; }
BlobServiceClient Service { get; }
StorageClientProviderContext Context { get; }
A Service
ingujjas ingatlan kényelmes. Az SDK BlobServiceClient osztályt használó utolsó kódolóval kapcsolatos műveletek némelyikéhez tárfiókkulcsok szükségesek. Ez a követelmény azt eredményezte, hogy egy szolgáltatásügyfél-példányt ad hozzá a két meglévő hüvelytípushoz, ahelyett, hogy külön szolgáltatót hoz létre.
Hüvely használata
Az ügyféltároló-szolgáltatók a hüvelypéldányokat osztják ki. A tárolási szolgáltatás kódja a következő jegyzetekkel ellátott kódsorozathoz hasonlóan néz ki, és a típusok az egyértelműség kedvéért ki van írva:
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
. . .
}
- A Gridwich automatikusan kitölti a műveleti környezetet az A sorban lévő hüvelykörnyezetbe.
TrackingETag
alapértelmezés szerint hamis. - A B sor után az A sor tartalmazza az
ETag
értéket,sleeve.Context
és ugyanaztClientRequestID
az értéket őrzi meg. - A C sor a B sorból és a
ETag
ClientRequestId
. - A C sor után a környezet új
ETag
értékkel rendelkezik a válaszbanDelete()
visszaadott módon. - A D sor nem küld
ETag
értéket a kérelembenAnotherOperation()
. - A D sor után a környezet új
ETag
értékkel rendelkezik a válaszbanAnotherOperation()
visszaadott módon.
A Storage szolgáltatás jelenleg a függőséginjektálási konfigurációban van beállítvaTransient
, ami azt jelenti, hogy a hüvelyalapú gyorsítótárazás kérésenként történik. További információt a Storage Service és a függőséginjektálás című témakörben talál.
Tárolási szolgáltatás alternatívái
A következő szakaszok olyan alternatív megközelítéseket ismertetnek, amelyek nem részei az aktuális Gridwich Storage-megoldásnak.
Gridwich AzureStorageManagement osztály
A tarsolytaggal Service
együtt, amely az Azure SDK BlobServiceClient osztály egy példánya, a Gridwich is rendelkezik az AzureStorageManagement osztálysal. A Storage Service GetConnectionStringForAccount
metódus és a Telerek kódolási metódusa GetStoreByNameAsync
ezt az osztályt használja a tárfiókkulcsok lekéréséhez. Az osztály jelenleg a Fluent-keretrendszeren alapul. Az SDK-osztály BlobServiceClient
kiegészítései végül felülírják ezt az osztályt, így a Fluent IAzure felületén a széles választéknál jobban koncentráltabb információ-lekérést tesz lehetővé.
A folyamatszabályzat elrejtése alosztályozással
Az SDK-ügyféltípusok alosztályozása két egyszerű tulajdonságot ad hozzá az ügyfélhez, egyet minden HTTP-fejlécértékhez, hogy teljesen elrejtse a folyamatszabályzattal való interakciót. Egy mély Moq-hiba miatt azonban nem lehet egységteszteket mock
létrehozni ezekhez a származtatott típusokhoz. A Gridwich a Moq-t használja, ezért nem használta ezt az alosztályozási módszert.
A Moq-hiba a belső hatókörű virtuális függvények jelenlétében történő keresztszerelvény-alosztályozás helytelen kezelésével kapcsolatos. Az SDK-ügyfélosztályok olyan belső hatókörű virtuális függvényeket használnak, amelyek belső hatókörű típusok, amelyek a normál külső felhasználók számára láthatatlanok. Amikor a Moq megpróbál létrehozni egy mock
alosztályt, amely a Gridwich-szerelvények egyikében található, a tesztelési végrehajtási időpontban meghiúsul, mivel nem találja a belső hatókörű virtuális elemet abban az SDK-ügyfélosztályban, amelyből a Gridwich-osztályok származtatva vannak. Nincs megkerülő megoldás a Moq Castle proxygenerációjának módosítása nélkül.
Storage-szolgáltatás és függőséginjektálás
A Gridwich jelenleg függőséginjektálási szolgáltatásként Transient
regisztrálja a Storage szolgáltatást. Vagyis minden alkalommal, amikor a függőséginjektálást kéri a szolgáltatás, létrehoz egy új példányt. Az aktuális kódnak akkor is megfelelően kell működnie, ha a regisztráció módosul Scoped
, ami kérésenként egy példányt jelent, például a külső rendszer kérését.
Ha azonban a regisztráció egy példányra Singleton
változik a Gridwich-függvényalkalmazásban, problémák lépnek fel. A Rácswich gyorsítótárazási mechanizmusa a hüvelyek és az adat bájttartományok esetében nem tesz különbséget a különböző kérések között. Emellett a gyorsítótármodell nem kivétel, így a Gridwich nem távolítja el a példányt a gyorsítótárból használat közben. Mivel az SDK-ügyfélosztályok nem garantáltan szálbiztosak, a koordináció sok változást igényelne.
Ezen okok miatt ne módosítsa a Gridwich Storage szolgáltatást a függőséginjektálási regisztrációra Singleton
. A Gridwich ezt a szabályt követi a függőséginjektálási regisztrációban, és egy checkThatStorageServiceIsNotASingleton nevű egységtesztet is tartalmaz a kényszerítéséhez.
Következő lépések
Termékdokumentáció:
Microsoft Learn-modulok: