Operacje usługi Gridwich dla usługi Azure Storage

Azure Storage

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.AzureStorageuczestnika 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".

Diagram showing client object instance relationships between the Storage SDK classes.

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ą ResetTometodę , 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:

  1. Tworzy kontekst magazynu bez wyciszenia na podstawie kontekstu operacji żądania, na przykład ctxNotMuted.

  2. 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.

  3. Określa operacje ctxMuted magazynowania związane z konfiguracją kodowania. System zewnętrzny nie widzi żadnych wskazówek dotyczących tych operacji.

  4. 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ść DoNotPublishlogiczną , 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:

  1. Wyślij żądanie Get Metadata (Pobierz metadane) z pustym ETagelementem .
  2. ETag Zapisz wartość z odpowiedzi.
  3. 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
        . . .
    }
  1. Gridwich automatycznie wypełnia kontekst operacji w kontekście rękawa w wierszu A. TrackingETag wartość domyślna to false.
  2. Po wierszu B sleeve.Context zawiera wartość ETag z wiersza A i zachowuje tę samą ClientRequestID wartość.
  3. Wiersz C wysyła zarówno ETag wartość z wiersza B, jak i .ClientRequestId
  4. Po wierszu C kontekst ma nową ETag wartość, która jest zwracana w Delete() odpowiedzi.
  5. Wiersz D nie wysyła ETag wartości dla żądania .AnotherOperation()
  6. Po wierszu D kontekst ma nową ETag wartość, która jest zwracana w AnotherOperation() 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:

Moduły microsoft Learn: