Udostępnij za pośrednictwem


Magazyn obiektów blob bez struktury (tworzenie aplikacji w chmurze Real-World za pomocą platformy Azure)

Autor : Rick Anderson, Tom Dykstra

Pobierz naprawę projektu lub pobierz książkę elektroniczną

Książka elektroniczna Building Real World Cloud Apps with Azure (Tworzenie rzeczywistych aplikacji w chmurze za pomocą platformy Azure ) jest oparta na prezentacji opracowanej przez Scotta Guthrie. Wyjaśniono w nim 13 wzorców i rozwiązań, które mogą pomóc w pomyślnym tworzeniu aplikacji internetowych dla chmury. Aby uzyskać informacje na temat książki e-book, zobacz pierwszy rozdział.

W poprzednim rozdziale przyjrzeliśmy się schematom partycjonowania i wyjaśniliśmy, jak aplikacja Fix It przechowuje obrazy w usłudze Azure Storage Blob Service oraz inne dane zadań w usłudze Azure SQL Database. W tym rozdziale bardziej szczegółowo omówimy usługę Blob Service i pokażemy, jak jest ona zaimplementowana w kodzie projektu Fix It.

Co to jest usługa Blob Storage?

Usługa Azure Storage Blob Service umożliwia przechowywanie plików w chmurze. Usługa Blob Service ma wiele zalet w porównaniu z przechowywaniem plików w lokalnym systemie plików sieciowych:

  • Jest wysoce skalowalna. Pojedyncze konto magazynu może przechowywać setki terabajtów i mieć wiele kont magazynu. Niektórzy z największych klientów platformy Azure przechowują setki petabajtów. Usługa Microsoft SkyDrive używa magazynu obiektów blob.
  • Jest trwały. Kopie zapasowe każdego pliku przechowywanego w usłudze Blob Service są automatycznie tworzone.
  • Zapewnia wysoką dostępność. Umowa SLA dla magazynu obiecuje czas pracy przez 99,9% lub 99,99% w zależności od wybranej opcji nadmiarowości geograficznej.
  • Jest to funkcja platformy jako usługi (PaaS) platformy Azure, co oznacza, że po prostu przechowujesz i pobierasz pliki, płacąc tylko za rzeczywistą ilość używanego magazynu, a platforma Azure automatycznie zajmuje się konfigurowaniem wszystkich maszyn wirtualnych i dysków wymaganych dla usługi i zarządzaniem nimi.
  • Dostęp do usługi Blob Service można uzyskać przy użyciu interfejsu API REST lub interfejsu API języka programowania. Zestawy SDK są dostępne dla platform .NET, Java, Ruby i innych.
  • Podczas przechowywania pliku w usłudze Blob Service można łatwo udostępnić go publicznie za pośrednictwem Internetu.
  • Możesz zabezpieczyć pliki w usłudze Blob Service, aby mogły uzyskiwać do nich dostęp tylko przez autoryzowanych użytkowników, lub udostępnić tymczasowe tokeny dostępu, które udostępniają je komuś tylko przez ograniczony czas.

Za każdym razem, gdy tworzysz aplikację dla platformy Azure i chcesz przechowywać wiele danych w środowisku lokalnym, takich jak obrazy, filmy wideo, pliki PDF, arkusze kalkulacyjne itp. — rozważ usługę Blob Service.

Tworzenie konta magazynu

Aby rozpocząć pracę z usługą Blob Service, utwórz konto usługi Storage na platformie Azure. W portalu kliknij pozycję Nowy -- magazyn -- usług -- danych— szybkie tworzenie, a następnie wprowadź adres URL i lokalizację centrum danych. Lokalizacja centrum danych powinna być taka sama jak w przypadku aplikacji internetowej.

Tworzenie dostępu do magazynu

Wybierasz region podstawowy, w którym chcesz przechowywać zawartość, a jeśli wybierzesz opcję replikacji geograficznej , platforma Azure utworzy repliki wszystkich danych w innym centrum danych w innej części kraju/regionu. Jeśli na przykład wybierzesz centrum danych w regionie Zachodnie stany USA, gdy przechowujesz plik, przechodzi on do centrum danych w regionie Zachodnie stany USA, ale w tle platforma Azure kopiuje je również do jednego z innych amerykańskich centrów danych. Jeśli awaria wystąpi w jednej części kraju/regionu, dane są nadal bezpieczne.

Platforma Azure nie będzie replikować danych w granicach geopolitycznych: jeśli lokalizacja podstawowa znajduje się w Stanach Zjednoczonych, pliki są replikowane tylko do innego regionu w Stanach Zjednoczonych; Jeśli lokalizacja podstawowa to Australia, pliki są replikowane tylko do innego centrum danych w Australii.

Oczywiście możesz również utworzyć konto magazynu, wykonując polecenia ze skryptu, jak pokazano wcześniej. Oto polecenie Windows PowerShell służące do tworzenia konta magazynu:

# Create a new storage account
New-AzureStorageAccount -StorageAccountName $Name -Location $Location -Verbose

Po utworzeniu konta usługi Storage możesz natychmiast rozpocząć przechowywanie plików w usłudze Blob Service.

Używanie usługi Blob Storage w aplikacji Fix It

Aplikacja Fix It umożliwia przekazywanie zdjęć.

Tworzenie zadania Naprawa

Po kliknięciu przycisku Utwórz element FixIt aplikacja przekazuje określony plik obrazu i zapisuje go w usłudze Blob Service.

Konfigurowanie kontenera obiektów blob

Do przechowywania pliku w usłudze Blob Service potrzebny jest kontener do jego przechowywania. Kontener usługi Blob Service odpowiada folderowi systemu plików. Skrypty tworzenia środowiska, które przejrzeliśmy w rozdziale Automatyzowanie wszystkiego , tworzą konto magazynu, ale nie tworzą kontenera. Dlatego celem CreateAndConfigure metody PhotoService klasy jest utworzenie kontenera, jeśli jeszcze nie istnieje. Ta metoda jest wywoływana Application_Start z metody w pliku Global.asax.

public async void CreateAndConfigureAsync()
{
    try
    {
        CloudStorageAccount storageAccount = StorageUtils.StorageAccount;

        // Create a blob client and retrieve reference to images container
        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
        CloudBlobContainer container = blobClient.GetContainerReference("images");

        // Create the "images" container if it doesn't already exist.
        if (await container.CreateIfNotExistsAsync())
        {
            // Enable public access on the newly created "images" container
            await container.SetPermissionsAsync(
                new BlobContainerPermissions
                {
                    PublicAccess =
                        BlobContainerPublicAccessType.Blob
                });

            log.Information("Successfully created Blob Storage Images Container and made it public");
        }
    }
    catch (Exception ex)
    {
        log.Error(ex, "Failure to Create or Configure images container in Blob Storage Service");
    }
}

Nazwa konta magazynu i klucz dostępu są przechowywane w appSettings kolekcji pliku Web.config , a kod w StorageUtils.StorageAccount metodzie używa tych wartości do utworzenia parametrów połączenia i ustanowienia połączenia:

string account = CloudConfigurationManager.GetSetting("StorageAccountName");
string key = CloudConfigurationManager.GetSetting("StorageAccountAccessKey");
string connectionString = String.Format("DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1}", account, key);
return CloudStorageAccount.Parse(connectionString);

Następnie CreateAndConfigureAsync metoda tworzy obiekt reprezentujący usługę Blob Service oraz obiekt reprezentujący kontener (folder) o nazwie "images" w usłudze Blob Service:

CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference("images");

Jeśli kontener o nazwie "images" jeszcze nie istnieje — co będzie prawdziwe przy pierwszym uruchomieniu aplikacji na nowym koncie magazynu — kod tworzy kontener i ustawia uprawnienia, aby go upublicznić. (Domyślnie nowe kontenery obiektów blob są prywatne i są dostępne tylko dla użytkowników, którzy mają uprawnienia dostępu do konta magazynu).

if (await container.CreateIfNotExistsAsync())
{
    // Enable public access on the newly created "images" container
    await container.SetPermissionsAsync(
        new BlobContainerPermissions
        {
            PublicAccess =
                BlobContainerPublicAccessType.Blob
        });

    log.Information("Successfully created Blob Storage Images Container and made it public");
}

Przechowywanie przekazanego zdjęcia w usłudze Blob Storage

Aby przekazać i zapisać plik obrazu, aplikacja używa IPhotoService interfejsu i implementacji interfejsu PhotoService w klasie . Plik PhotoService.cs zawiera cały kod w aplikacji Fix It, która komunikuje się z usługą Blob Service.

Następująca metoda kontrolera MVC jest wywoływana, gdy użytkownik kliknie przycisk Utwórz fixIt. W tym kodzie photoService odwołuje się do wystąpienia PhotoService klasy i fixittask odwołuje się do wystąpienia FixItTask klasy jednostki, które przechowuje dane dla nowego zadania.

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create([Bind(Include = "FixItTaskId,CreatedBy,Owner,Title,Notes,PhotoUrl,IsDone")]FixItTask fixittask, HttpPostedFileBase photo)
{
    if (ModelState.IsValid)
    {
        fixittask.CreatedBy = User.Identity.Name;
        fixittask.PhotoUrl = await photoService.UploadPhotoAsync(photo);
        await fixItRepository.CreateAsync(fixittask);
        return RedirectToAction("Success");
    }

    return View(fixittask);
}

Metoda UploadPhotoAsync w PhotoService klasie przechowuje przekazany plik w usłudze Blob i zwraca adres URL wskazujący nowy obiekt blob.

public async Task<string> UploadPhotoAsync(HttpPostedFileBase photoToUpload)
{            
    if (photoToUpload == null || photoToUpload.ContentLength == 0)
    {
        return null;
    }

    string fullPath = null;
    Stopwatch timespan = Stopwatch.StartNew();

    try
    {
        CloudStorageAccount storageAccount = StorageUtils.StorageAccount;

        // Create the blob client and reference the container
        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
        CloudBlobContainer container = blobClient.GetContainerReference("images");

        // Create a unique name for the images we are about to upload
        string imageName = String.Format("task-photo-{0}{1}",
            Guid.NewGuid().ToString(),
            Path.GetExtension(photoToUpload.FileName));

        // Upload image to Blob Storage
        CloudBlockBlob blockBlob = container.GetBlockBlobReference(imageName);
        blockBlob.Properties.ContentType = photoToUpload.ContentType;
        await blockBlob.UploadFromStreamAsync(photoToUpload.InputStream);

        // Convert to be HTTP based URI (default storage path is HTTPS)
        var uriBuilder = new UriBuilder(blockBlob.Uri);
        uriBuilder.Scheme = "http";
        fullPath = uriBuilder.ToString();

        timespan.Stop();
        log.TraceApi("Blob Service", "PhotoService.UploadPhoto", timespan.Elapsed, "imagepath={0}", fullPath);
    }
    catch (Exception ex)
    {
        log.Error(ex, "Error upload photo blob to storage");
    }

    return fullPath;
}

Podobnie jak w metodzie CreateAndConfigure , kod łączy się z kontem magazynu i tworzy obiekt reprezentujący kontener obiektów blob "images", z wyjątkiem sytuacji, w której zakłada, że kontener już istnieje.

Następnie tworzy unikatowy identyfikator obrazu, który ma zostać przekazany, łącząc nową wartość identyfikatora GUID z rozszerzeniem pliku:

string imageName = String.Format("task-photo-{0}{1}",
    Guid.NewGuid().ToString(),
    Path.GetExtension(photoToUpload.FileName));

Następnie kod używa obiektu kontenera obiektów blob i nowego unikatowego identyfikatora do utworzenia obiektu blob, ustawia atrybut na tym obiekcie wskazujący, jakiego rodzaju plik jest, a następnie używa obiektu blob do przechowywania pliku w magazynie obiektów blob.

CloudBlockBlob blockBlob = container.GetBlockBlobReference(imageName);
blockBlob.Properties.ContentType = photoToUpload.ContentType;
blockBlob.UploadFromStream(photoToUpload.InputStream);

Na koniec pobiera adres URL odwołujący się do obiektu blob. Ten adres URL będzie przechowywany w bazie danych i może być używany na stronach sieci Web Fix It do wyświetlania przekazanego obrazu.

fullPath = String.Format("http://{0}{1}", blockBlob.Uri.DnsSafeHost, blockBlob.Uri.AbsolutePath);

Ten adres URL jest przechowywany w bazie danych jako jedna z kolumn tabeli FixItTask.

public class FixItTask
{
    public int FixItTaskId  { get; set; }
    public string CreatedBy { get; set; }
    [Required]
    public string Owner     { get; set; }
    [Required]
    public string Title     { get; set; }
    public string Notes     { get; set; }
    public string PhotoUrl  { get; set; }
    public bool IsDone      { get; set; } 
}

Przy użyciu tylko adresu URL w bazie danych i obrazów w usłudze Blob Storage aplikacja Fix It przechowuje bazę danych małą, skalowalną i niedrogią, podczas gdy obrazy są przechowywane, gdzie magazyn jest tani i może obsługiwać terabajty lub petabajty. Jedno konto magazynu może przechowywać setki terabajtów zdjęć Fix It i płacisz tylko za to, czego używasz. Więc można zacząć od małych płacących 9 centów za pierwszy gigabajt i dodać więcej obrazów dla groszy za dodatkowy gigabajt.

Wyświetlanie przekazanego pliku

Aplikacja Fix It wyświetla przekazany plik obrazu po wyświetleniu szczegółów zadania.

Napraw szczegóły zadania za pomocą zdjęcia

Aby wyświetlić obraz, cały widok MVC musi zawierać PhotoUrl wartość w kodzie HTML wysłanym do przeglądarki. Serwer internetowy i baza danych nie używają cykli do wyświetlania obrazu, obsługują tylko kilka bajtów do adresu URL obrazu. W poniższym kodzie Model Razor odwołuje się do wystąpienia FixItTask klasy jednostki.

<fieldset>
<legend>@Html.DisplayFor(model => model.Title)</legend>
<dl>
    <dt>Opened By</dt>
    <dd>@Html.DisplayFor(model => model.CreatedBy)</dd>
                <br />
    <dt>@Html.DisplayNameFor(model => model.Notes)</dt>
    <dd>@Html.DisplayFor(model => model.Notes)</dd>
                <br />
                @if(Model.PhotoUrl != null) {
        <dd><img src="@Model.PhotoUrl" title="@Model.Title" /></dd>
                }
</dl>
</fieldset>

Jeśli przyjrzysz się kodowi HTML wyświetlanej strony, zobaczysz adres URL wskazujący bezpośrednio obraz w magazynie obiektów blob, podobny do następującego:

<fieldset>
<legend>Brush the dog again</legend>
<dl>
    <dt>Opened By</dt>
    <dd>Tom</dd>
                <br />
    <dt>Notes</dt>
    <dd>Another dog brushing task</dd>
                <br />
    <dd>
<img src="http://storageaccountname.blob.core.windows.net/images/task-photo-312dd635-ba87-4542-8b15-767032c55f4e.jpg" 
           title="Brush the dog again" />
    </dd>
</dl>
</fieldset>

Podsumowanie

Pokazano, jak aplikacja Fix It przechowuje obrazy w usłudze Blob Service i tylko adresy URL obrazów w bazie danych SQL. Korzystanie z usługi Blob service sprawia, że baza danych SQL jest znacznie mniejsza niż w przeciwnym razie, umożliwia skalowanie w górę do niemal nieograniczonej liczby zadań i można je wykonać bez konieczności pisania dużej ilości kodu.

Możesz mieć setki terabajtów na koncie magazynu, a koszt magazynu jest znacznie mniej kosztowny niż SQL Database magazynu, począwszy od około 3 centów za gigabajt miesięcznie plus niewielka opłata za transakcję. Pamiętaj, że nie płacisz za maksymalną pojemność, ale tylko za kwotę, którą faktycznie przechowujesz, więc aplikacja jest gotowa do skalowania, ale nie płacisz za całą tę dodatkową pojemność.

W następnym rozdziale omówimy znaczenie tworzenia aplikacji w chmurze, która może bezpiecznie obsługiwać błędy.

Zasoby

Aby uzyskać więcej informacji, zobacz następujące zasoby: