Usługa Gridwich Azure Storage, Gridwich.SagaParticipants.Storage.AzureStorage udostępnia operacje obiektów blob i kontenerów dla kont usługi Azure Storage skonfigurowanych dla usługi Gridwich. Przykładowe operacje magazynowania to Tworzenie obiektów blob, Usuwanie kontenera, Kopiowanie obiektu blob lub Zmiana warstwy magazynowania.
Usługa Gridwich wymaga, aby mechanizmy magazynowania działały zarówno dla blokowych obiektów blob, jak i kontenerów usługi Azure Storage. W przypadku odrębnych klas i operacji usługi Storage dla obiektów blob i kontenerów nie ma wątpliwości, czy dana operacja magazynu odnosi się do obiektu blob, czy kontenera. Ten artykuł dotyczy zarówno obiektów blob, jak i kontenerów, z wyjątkiem przypadków, w których jest to zaznaczone.
Gridwich uwidacznia większość operacji magazynowania w systemach zewnętrznych w ramach Storage.AzureStorage
uczestnika sagi. Inni uczestnicy sagi używają usługi magazynu do zadań, takich jak kopiowanie obiektów blob między różnymi kontenerami lub kontami podczas konfigurowania przepływów pracy kodowania.
W tym artykule opisano sposób, w jaki usługa Gridwich Azure Storage spełnia wymagania dotyczące rozwiązania i integruje się z mechanizmami, takimi jak programy obsługi zdarzeń. Linki wskazują odpowiedni kod źródłowy, który zawiera bardziej obszerny komentarz do kontenerów, klas i mechanizmów.
Azure Storage SDK
Usługa Gridwich używa klas z zestawu SDK usługi Azure Storage do interakcji z usługą Azure Storage, a nie ręcznie tworzenia żądań REST. W ramach dostawcy magazynu klasy BlobBaseClient i BlobContainerClient zestawu SDK zarządzają żądaniami magazynu.
Te klasy klienta zestawu SDK umożliwiają obecnie tylko pośredni dostęp do dwóch nagłówków HTTP Gridwich musi manipulować, x-ms-client-request-id
na potrzeby kontekstu operacji i ETag
wersji obiektu.
W usłudze Gridwich para klas dostawców zwalnia funkcje BlobBaseClientProvider i BlobContainerClientProvider w jednostkach nazywanych rękawami. Aby uzyskać szczegółowe informacje na temat rękawów, zobacz Rękawy magazynu.
Na poniższym diagramie przedstawiono strukturę klas SDK i Gridwich oraz sposób, w jaki wystąpienia są ze sobą powiązane. Strzałki wskazują "ma odwołanie do".
Zasady potoku
Punkt zaczepienia umożliwia manipulowanie nagłówkami HTTP jako wystąpienie zasad potoku podczas tworzenia wystąpienia klienta. Te zasady można ustawić tylko w czasie tworzenia wystąpienia klienta i nie można zmienić zasad. Kod dostawcy magazynu korzystający z klienta musi mieć możliwość manipulowania wartościami nagłówka podczas wykonywania. Wyzwaniem jest, aby dostawca magazynu i potok wchodziły w interakcję w sposób czysty.
Zasady potoku Gridwich można znaleźć w klasie BlobClientPipelinePolicy .
Buforowanie usługi Storage
Ustanowienie połączenia TCP i uwierzytelnianie tworzą obciążenie, gdy wystąpienie obiektu klienta zestawu SDK wysyła swoje pierwsze żądanie do usługi Azure Storage. Wiele wywołań tego samego obiektu blob w żądaniu systemu zewnętrznego, na przykład Pobierz metadane, a następnie Usuń obiekt blob, narzuć obciążenie.
Aby zmniejszyć obciążenie, usługa Gridwich utrzymuje pamięć podręczną jednego wystąpienia klienta dla każdego obiektu blob magazynu lub kontenera, w zależności od klas zestawu SDK używanych przez kontekst operacji. Usługa Gridwich zachowuje to wystąpienie klienta i może używać wystąpienia dla wielu operacji usługi Azure Storage względem tego samego obiektu blob lub kontenera przez czas trwania żądania systemu zewnętrznego.
Klasy klienta udostępniane przez zestaw Azure SDK wymagają, aby wystąpienia obiektów klienta zestawu SDK było specyficzne dla pojedynczego obiektu blob lub kontenera w czasie tworzenia. Wystąpienia nie są również gwarantowane bezpiecznie w przypadku jednoczesnego użycia w różnych wątkach. Ponieważ kontekst operacji reprezentuje pojedyncze żądanie, buforowanie bazy Gridwich na kombinacji nazwy obiektu blob lub kontenera z kontekstem operacji.
To wystąpienie jest używane ponownie w połączeniu ze strukturą klienta zestawu SDK usługi Azure Storage, wymaga dodatkowego kodu pomocy technicznej w celu zrównoważenia wydajności i przejrzystości kodu.
Argument kontekstu
Prawie wszystkie operacje usługi Storage Gridwich wymagają specjalnego argumentu kontekstu typu StorageClientProviderContext. Ten argument kontekstu spełnia następujące wymagania:
Udostępnia system zewnętrzny odpowiedzi, które obejmują unikatową wartość kontekstu operacji opartej na formacie JSON dla poszczególnych żądań, którą system zewnętrzny określony w żądaniu Gridwich. Aby uzyskać więcej informacji, zobacz Kontekst operacji.
Umożliwia obiektom wywołującym usługę Storage, na przykład programom obsługi zdarzeń Gridwich kontrolowanie, które odpowiedzi są widoczne dla systemu zewnętrznego. Ta kontrolka uniemożliwia usłudze zalanie systemu zewnętrznego z nieistotnymi zdarzeniami powiadomień. Aby uzyskać więcej informacji, zobacz Wyciszenie kontekstu.
Jest zgodna z konwencjami usługi Azure Storage, aby zapewnić spójne żądania i odpowiedzi w środowisku, które umożliwia łączenie równoległych czytników i składników zapisywania. Na przykład obsługuje śledzenie elementu ETag. Aby uzyskać więcej informacji, zobacz ETags.
Kontekst magazynu
Kontekstem dla typów magazynu obiektów blob i kontenerów jest StorageClientProviderContext, który wygląda następująco:
string ClientRequestID { get; }
JObject ClientRequestIdAsJObject { get; }
bool IsMuted { get; set; }
string ETag { get; set; }
bool TrackingETag { get; set; }
Dwie pierwsze właściwości to różne reprezentacje kontekstu operacji, który został użyty do zainicjowania wystąpienia StorageClientProviderContext . Klasa ma różne konstruktory, w tym konstruktor kopiujący. Dodatkowe metody obejmują ResetTo
metodę , aby umożliwić duplikowanie stanu w miejscu i metodę statyczną CreateSafe
w celu zapewnienia, że problematyczne inicjacje nie zgłaszają wyjątków.
Klasa zawiera również specjalną obsługę tworzenia kontekstów na podstawie identyfikatorów GUID i pustych ciągów. Programy obsługi powiadomień usługi Azure Storage dla obiektów blob Created i Deleted, które również przetwarzają powiadomienia wynikające z agentów zewnętrznych, wymagają formularza identyfikatora GUID.
Wyciszenie kontekstu
Właściwość IsMuted
określa, czy aplikacja oczekuje, że usługa opublikuje powiadomienia wynikowe z powrotem do obiektu wywołującego, na przykład w systemie zewnętrznym. W operacji wyciszonej usługa nie publikuje wynikowych zdarzeń.
Przykładem jest kopiowanie obiektów blob wykonywanych przez koder w celu rozmieszczania obiektów blob w usłudze Azure Storage jako danych wejściowych zadania kodowania. System zewnętrzny nie jest zaniepokojony tymi szczegółami, ale tylko o stanie zadania kodowania i miejscu, w którym może pobrać zakodowane dane wyjściowe. Aby uwzględnić te obawy, koder:
Tworzy kontekst magazynu bez wyciszenia na podstawie kontekstu operacji żądania, na przykład
ctxNotMuted
.Tworzy wyciszony kontekst magazynu, na przykład
ctxMuted
, przy użyciu konstruktora kopiowania klasy kontekstu lub tworzenia nowego wystąpienia. Każda opcja będzie mieć tę samą wartość kontekstu operacji.Określa operacje
ctxMuted
magazynowania związane z konfiguracją kodowania. System zewnętrzny nie widzi żadnych wskazówek dotyczących tych operacji.Określa
ctxNotMuted
kontekst operacji magazynu, które odzwierciedlają uzupełnianie kodowania, na przykład kopiowanie pliku wyjściowego do kontenera docelowego. Programy obsługi gridwich publikują wynikowe zdarzenia powiadomień usługi Azure Storage w systemie zewnętrznym.
Obiekt wywołujący kontroluje ostateczną widoczność operacji. Zarówno wyciszone, jak i nie wyciszone operacje są oparte na równoważnej operationContext
wartości. Celem wyciszenia kontekstu jest ułatwienie diagnozowania problemów z dzienników śledzenia zdarzeń, ponieważ istnieje możliwość wyświetlenia operacji magazynowania związanych z żądaniem, niezależnie od stanu wyciszenia operacji operacji.
Obiekt ResponseBaseDTO ma właściwość DoNotPublish
logiczną , której wysyłanie zdarzeń używa w celu dyktowania ostatecznej decyzji dotyczącej tego, czy opublikować. Wysyłanie zdarzeń ustawia DoNotPublish
z kolei właściwość na IsMuted
podstawie właściwości kontekstu.
Usługa przesyła ustawienie wyciszania do usługi Azure Storage, która następnie ustawia clientRequestId
wartość w zdarzeniach powiadomień magazynu, które przedstawia dwóm procedurom obsługi Gridwich, Utworzonym i Usuniętym. Te dwa programy obsługi są ustawione DoNotPublish
tak, aby odzwierciedlały wyciszenie żądane przez obiekt wywołujący.
Tagi ETag dla spójności docelowej
Usługa Azure Storage używa nagłówka HTTP ETag
dla sekwencji żądań, które powinny mieć spójność docelową. Przykładem jest upewnienie się, że obiekt blob nie został zmieniony między operacjami pobierania metadanych i aktualizowania magazynu metadanych .
Aby dopasować się do standardowego użycia protokołu HTTP, ten nagłówek ma nieprzezroczystą wartość, której interpretacja polega na tym, że jeśli wartość nagłówka ulegnie zmianie, obiekt bazowy również uległ zmianie. Jeśli żądanie wysyła bieżącą ETag
wartość obiektu i nie jest zgodne z bieżącą wartością usługi ETag
magazynu, żądanie natychmiast kończy się niepowodzeniem. Jeśli żądanie nie zawiera ETag
wartości, usługa Azure Storage pomija sprawdzanie i nie blokuje żądania.
Tagi ETag w usłudze magazynu
W przypadku usługi Gridwich ETag
element jest wewnętrznym szczegółem między usługą Gridwich Storage i usługą Azure Storage. Żaden inny kod nie musi być świadomy .ETag
Usługa Storage używa elementu ETag
dla sekwencji, takich jak Pobieranie metadanych obiektu blob, usuwanie operacji obiektów blob do przetwarzania BlobDelete Event
żądania. ETag
Użycie metody zapewnia, że operacja Usuń obiekt blob jest przeznaczona dokładnie dla tej samej wersji obiektu blob co operacja Pobierania metadanych.
Aby użyć elementu ETag
dla poprzedniego przykładu:
- Wyślij żądanie Get Metadata (Pobierz metadane) z pustym
ETag
elementem . ETag
Zapisz wartość z odpowiedzi.- Dodaj zapisaną
ETag
wartość do żądania Usuń obiekt blob .
Jeśli te dwie ETag
wartości są różne, operacja usuwania zakończy się niepowodzeniem. Niepowodzenie oznacza, że niektóre inne operacje zmieniły obiekt blob między krokami 2 i 3. Powtórz proces z kroku 1.
ETag
to parametr konstruktorów i właściwość string klasy StorageClientProviderContext. Tylko obiekt BlobClientPipelinePolicy specyficzny dla gridwich manipuluje wartościąETag
.
Używanie kontrolki ETag
Właściwość TrackingETag
określa, czy wysłać ETag
wartość w następnym żądaniu. Wartość true
oznacza, że usługa wysyła ETag
element , jeśli jest dostępny.
Żądanie usługi Azure Storage z wartością ETag
, która nie jest zgodna z obiektem blob lub kontenerem, powoduje niepowodzenie operacji. Ten błąd jest zgodnie z projektem, ponieważ ETag
jest to standardowy sposób wyrażania "dokładnej wersji, którą dotyczy żądanie". Żądania mogą zawierać TrackingETag
właściwość , aby określić, że ETags
właściwość musi być zgodna lub nie zawiera TrackingETag
właściwości, aby wskazać, że ETag
wartości nie mają znaczenia.
Potok zawsze pobiera ETag
wartość z operacji usługi Azure Storage, jeśli istnieje ona w tej odpowiedzi REST. Potok zawsze aktualizuje właściwość kontekstu ETag
, jeśli to możliwe, od ostatniej operacji. Flaga TrackingETag
steruje tylko tym, czy następne żądanie z tego samego wystąpienia klienta wysyła wartość ETag
właściwości. ETag
Jeśli wartość ma wartość null lub jest pusta, bieżące żądanie nie ustawia żadnej wartości HTTPETag
, niezależnie od wartości TrackingETag
.
Rękawy magazynu
Usługa Gridwich wymaga, aby jej mechanizmy magazynowania działały zarówno dla blokowych obiektów blob, jak i kontenerów usługi Azure Storage. Istnieją różne klasy i operacje usługi Storage dla obiektów blob i kontenerów, więc nie ma wątpliwości, czy dana operacja magazynu odnosi się do obiektu blob, czy kontenera.
Para klas dostawców, jedna dla obiektów blob i jedna dla kontenerów, dozuje dwa zestawy funkcji w jednostkach nazywanych rękawami. Rękawy zawierają wystąpienia klas pomocników magazynu, które są częścią zestawu Azure SDK. Inicjowanie usługi storage tworzy dostawców i udostępnia je bezpośrednio metodom usługi Storage.
Struktura rękawów
Rękaw jest kontenerem dla wystąpienia obiektu klienta zestawu SDK i kontekstu magazynu. Funkcje dostawcy magazynu odwołują się do rękawa za pośrednictwem dwóch właściwości Client
i Context
. Istnieje typ rękawa dla obiektów blob i inny dla kontenerów, które mają Client
właściwości typuBlobBaseClient
iBlobContainerClient
, odpowiednio.
Ogólna struktura rękawów obiektów blob wygląda następująco:
BlobBaseClient Client { get; }
BlobServiceClient Service { get; }
StorageClientProviderContext Context { get; }
Obiekt Service
na rękawie jest wygodą. Niektóre końcowe operacje związane z koderem korzystające z klasy BlobServiceClient zestawu SDK wymagają kluczy konta magazynu. To wymaganie doprowadziło do dodania wystąpienia klienta usługi do dwóch istniejących typów rękawów, a nie utworzenia oddzielnego dostawcy.
Użycie rękawów
Dostawcy magazynu klienta rozdają wystąpienia rękawów. Kod usługi magazynu wygląda podobnie do następującej sekwencji kodu z adnotacjami, a typy zostały zapisane w celu uzyskania jasności:
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
. . .
}
- Gridwich automatycznie wypełnia kontekst operacji w kontekście rękawa w wierszu A.
TrackingETag
wartość domyślna to false. - Po wierszu B
sleeve.Context
zawiera wartośćETag
z wiersza A i zachowuje tę samąClientRequestID
wartość. - Wiersz C wysyła zarówno
ETag
wartość z wiersza B, jak i .ClientRequestId
- Po wierszu C kontekst ma nową
ETag
wartość, która jest zwracana wDelete()
odpowiedzi. - Wiersz D nie wysyła
ETag
wartości dla żądania .AnotherOperation()
- Po wierszu D kontekst ma nową
ETag
wartość, która jest zwracana wAnotherOperation()
odpowiedzi.
Usługa storage jest obecnie ustawiona tak jak Transient
w konfiguracji wstrzykiwania zależności, co oznacza, że buforowanie oparte na rękawach jest na podstawie poszczególnych żądań. Aby uzyskać więcej informacji, zobacz Iniekcja usługi Storage i zależności.
Alternatywy usługi Storage
W poniższych sekcjach opisano alternatywne podejścia, które nie są częścią bieżącego rozwiązania magazynu Gridwich.
Gridwich AzureStorageManagement, klasa
W połączeniu z elementem członkowskim rękawaService
, który jest wystąpieniem klasy Azure SDK BlobServiceClient, Gridwich ma również klasę AzureStorageManagement. Metoda usługi GetConnectionStringForAccount
Storage i metoda kodowania GetStoreByNameAsync
Telerek używają tej klasy do pobierania kluczy konta magazynu. Klasa jest obecnie oparta na strukturze Fluent. Dodatki do klasy SDK BlobServiceClient
powinny ostatecznie zastąpić tę klasę, umożliwiając bardziej ukierunkowane pobieranie informacji niż szeroką gamę w interfejsie Fluent IAzure.
Ukrywanie zasad potoku za pomocą podklasy
Podklasy typów klientów zestawu SDK dodaje do klienta dwie proste właściwości, po jednym dla każdej wartości nagłówka HTTP, aby całkowicie ukryć interakcję z zasadami potoku. Jednak ze względu na głęboką usterkę Moq nie można utworzyć testów jednostkowych za pośrednictwem mock
dla tych typów pochodnych. Usługa Gridwich używa narzędzia Moq, więc nie używa tej metody podklasowania.
Usterka Moq odnosi się do błędnej obsługi podklas między zestawami w obecności funkcji wirtualnych w zakresie wewnętrznym. Klasy klienta zestawu SDK korzystają z funkcji wirtualnych w zakresie wewnętrznym obejmujących typy zakresu wewnętrznego, które są niewidoczne dla zwykłych użytkowników zewnętrznych. Gdy moq próbuje utworzyć podklasę mock
, która znajduje się w jednym z zestawów Gridwich, kończy się niepowodzeniem w czasie wykonywania testu, ponieważ nie może znaleźć maszyn wirtualnych zakresu wewnętrznego w klasach klienta zestawu SDK, z których pochodzą klasy gridwich. Nie ma obejścia bez zmian w generowaniu serwera proxy zamku Moq.
Iniekcja usługi Storage i zależności
Gridwich obecnie rejestruje usługę storage jako usługę Transient
iniekcji zależności. Oznacza to, że za każdym razem, gdy iniekcja zależności jest proszona o usługę, tworzy nowe wystąpienie. Bieżący kod powinien również działać poprawnie, jeśli rejestracja zmieni się na Scoped
, co oznacza jedno wystąpienie na żądanie, na przykład żądanie systemu zewnętrznego.
Jednak wystąpią problemy, jeśli rejestracja zmieni się na Singleton
, jedno wystąpienie w aplikacji funkcji Gridwich. Mechanizm buforowania Gridwich dla rękawów i zakresów bajtów danych nie będzie rozróżniać między różnymi żądaniami. Ponadto model pamięci podręcznej nie jest wyewidencjonowywaniem, więc usługa Gridwich nie usuwa wystąpienia z pamięci podręcznej, gdy jest używana. Ponieważ klasy klienta zestawu SDK nie mają gwarancji bezpieczeństwa wątkowego, koordynacja wymagałaby wielu zmian.
Z tych powodów nie należy zmieniać usługi Gridwich Storage, tak jak to jest, na rejestrację wstrzykiwania Singleton
zależności. Funkcja Gridwich jest zgodna z tą regułą w rejestracji wstrzykiwania zależności i zawiera test jednostkowy CheckThatStorageServiceIsNotASingleton, aby go wymusić.
Następne kroki
Dokumentacja produktu:
- System multimediów w chmurze Gridwich
- Co to jest usługa Azure Blob Storage?
- Co to jest usługa Azure Pipelines?
Moduły microsoft Learn: