Yapılandırılmamış Blob Depolama (Azure ile Real-World Cloud Apps Oluşturma)

Tarafından Rick Anderson, Tom Dykstra

Fix It Project'i indirin veya E-kitap indirin

Azure ile Gerçek Dünya Bulut Uygulamaları Oluşturma e-kitabı, Scott Guthrie tarafından geliştirilen bir sunuyu temel alır. Bulut için web uygulamalarını başarıyla geliştirmenize yardımcı olabilecek 13 desen ve uygulama açıklanmaktadır. E-kitap hakkında bilgi için ilk bölüme bakın.

Önceki bölümde bölümleme şemalarını inceledik ve Düzelt uygulamasının Azure Depolama Blobu hizmetinde görüntüleri ve diğer görev verilerini Azure SQL Veritabanı'nda nasıl depoladığı açıklandı. Bu bölümde Blob hizmetinin ayrıntılarına inecek ve Bunu Düzelt proje kodunda nasıl uygulandığını göstereceğiz.

Blob depolama nedir?

Azure Depolama Blob hizmeti, dosyaları bulutta depolamak için bir yol sağlar. Blob hizmeti, dosyaları yerel bir ağ dosya sisteminde depolamaya kıyasla çeşitli avantajlara sahiptir:

  • Yüksek oranda ölçeklenebilir. Tek bir Depolama hesabı yüzlerce terabayt depolayabilir ve birden çok Depolama hesabınız olabilir. En büyük Azure müşterilerinden bazıları yüzlerce petabayt depolar. Microsoft SkyDrive blob depolamayı kullanır.
  • Dayanıklıdır. Blob hizmetinde depoladığınız her dosya otomatik olarak yedekleniyor.
  • Yüksek kullanılabilirlik sağlar. Depolama için SLA, seçtiğiniz coğrafi yedeklilik seçeneğine bağlı olarak %99,9 veya %99,99 çalışma süresi sunar.
  • Azure'ın bir hizmet olarak platform (PaaS) özelliğidir. Bu, yalnızca kullandığınız gerçek depolama alanı miktarı için ödeme yaparak yalnızca dosyaları depolayıp almanız ve Azure'ın hizmet için gerekli tüm VM'leri ve disk sürücülerini ayarlama ve yönetme işlemini otomatik olarak üstlendiği anlamına gelir.
  • Blob hizmetine REST API veya programlama dili API'sini kullanarak erişebilirsiniz. SDK'lar .NET, Java, Ruby ve diğerleri için kullanılabilir.
  • Bir dosyayı Blob hizmetinde depoladığınızda, kolayca İnternet üzerinden herkese açık hale getirebilirsiniz.
  • Blob hizmetindeki dosyaların güvenliğini, yalnızca yetkili kullanıcılar tarafından erişilebilecek şekilde sağlayabilir veya bunları yalnızca sınırlı bir süre için birinin kullanımına sunan geçici erişim belirteçleri sağlayabilirsiniz.

Azure için bir uygulama oluştururken şirket içi ortamda resimler, videolar, PDF'ler, elektronik tablolar gibi dosyalarda yer alacak çok fazla veri depolamak istediğinizde. -- Blob hizmetini göz önünde bulundurun.

Depolama hesabı oluşturma

Blob hizmetini kullanmaya başlamak için Azure'da bir Depolama hesabı oluşturursunuz. Portalda Yeni -- Veri Hizmetleri -- Depolama -- Hızlı Oluşturma'ya tıklayın ve bir URL ve veri merkezi konumu girin. Veri merkezi konumu, web uygulamanızla aynı olmalıdır.

Depolama hesabı oluşturma

İçeriği depolamak istediğiniz birincil bölgeyi seçersiniz ve coğrafi çoğaltma seçeneğini belirlerseniz Azure, tüm verilerinizin çoğaltmalarını ülkenin/bölgenin başka bir bölümündeki farklı bir veri merkezinde oluşturur. Örneğin, Batı ABD veri merkezini seçerseniz, bir dosyayı depoladığınızda dosya Batı ABD veri merkezine gider, ancak arka planda Azure da bunu diğer ABD veri merkezlerinden birine kopyalar. Ülkenin/bölgenin bir bölümünde olağanüstü durum olursa verileriniz yine de güvende olur.

Azure coğrafi sınırların ötesinde verileri çoğaltmaz: Birincil konumunuz ABD'deyse dosyalarınız yalnızca ABD içindeki başka bir bölgeye çoğaltılır; Birincil konumunuz Avustralya ise, dosyalarınız yalnızca Avustralya'daki başka bir veri merkezine çoğaltılır.

Elbette, daha önce gördüğümüz gibi bir betikten komut yürüterek bir Depolama hesabı da oluşturabilirsiniz. Depolama hesabı oluşturmak için bir Windows PowerShell komutu aşağıdadır:

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

Depolama hesabınız olduğunda, dosyaları Blob hizmetinde depolamaya hemen başlayabilirsiniz.

Düzelt uygulamasında Blob depolamayı kullanma

Düzelt uygulaması fotoğrafları karşıya yüklemenize olanak tanır.

Düzelt görevi oluşturma

FixIt Oluştur'a tıkladığınızda, uygulama belirtilen görüntü dosyasını karşıya yükler ve Blob hizmetinde depolar.

Blob kapsayıcısını ayarlama

Bir dosyayı Blob hizmetinde depolamak için bir kapsayıcıya ihtiyacınız vardır. Blob hizmeti kapsayıcısı bir dosya sistemi klasörüne karşılık gelir. Her Şeyi Otomatikleştir bölümünde incelediğimiz ortam oluşturma betikleri Depolama hesabını oluşturur ancak kapsayıcı oluşturmaz. Bu nedenle sınıfının yönteminin CreateAndConfigurePhotoService amacı, henüz yoksa bir kapsayıcı oluşturmaktır. Bu yöntem Global.asax içindeki yönteminden Application_Start çağrılır.

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");
    }
}

Depolama hesabı adı ve erişim anahtarı ,Web.config dosyasının koleksiyonunda appSettings depolanır ve yöntemindeki StorageUtils.StorageAccount kod bir bağlantı dizesi oluşturmak ve bağlantı kurmak için bu değerleri kullanır:

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);

Yöntemi CreateAndConfigureAsync daha sonra Blob hizmetini temsil eden bir nesne ve Blob hizmetinde "images" adlı bir kapsayıcıyı (klasör) temsil eden bir nesne oluşturur:

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

Uygulamayı yeni bir depolama hesabında ilk kez çalıştırdığınızda geçerli olacak olan "images" adlı bir kapsayıcı henüz yoksa kod kapsayıcıyı oluşturur ve genel kullanıma açmak için izinleri ayarlar. (Varsayılan olarak, yeni blob kapsayıcıları özeldir ve yalnızca depolama hesabınıza erişim izni olan kullanıcılar tarafından erişilebilir.)

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");
}

Karşıya yüklenen fotoğrafı Blob depolamada depolama

Uygulama, görüntü dosyasını karşıya yüklemek ve kaydetmek için arabirimini IPhotoService ve sınıfındaki arabirimin PhotoService uygulamasını kullanır. PhotoService.cs dosyası, Blob hizmetiyle iletişim kuran Düzelt uygulamasındaki tüm kodu içerir.

Kullanıcı FixIt'i Oluştur'a tıkladığında aşağıdaki MVC denetleyici yöntemi çağrılır. Bu kodda, photoService sınıfın PhotoService bir örneğine ve fixittask yeni bir görevin verilerini depolayan varlık sınıfının örneğine FixItTask başvurur.

[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);
}

UploadPhotoAsync sınıfındaki PhotoService yöntemi karşıya yüklenen dosyayı Blob hizmetinde depolar ve yeni bloba işaret eden bir URL döndürür.

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;
}

yönteminde CreateAndConfigure olduğu gibi kod, depolama hesabına bağlanır ve "images" blob kapsayıcısını temsil eden bir nesne oluşturur, ancak burada kapsayıcının zaten var olduğunu varsayar.

Ardından dosya uzantısıyla yeni bir GUID değeri birleştirerek karşıya yüklenmek üzere olan görüntü için benzersiz bir tanımlayıcı oluşturur:

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

Kod daha sonra blob kapsayıcı nesnesini ve yeni benzersiz tanımlayıcıyı kullanarak blob nesnesi oluşturur, bu nesnede ne tür bir dosya olduğunu belirten bir öznitelik ayarlar ve ardından blob nesnesini kullanarak dosyayı blob depolamada depolar.

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

Son olarak bloba başvuran bir URL alır. Bu URL veritabanında depolanır ve karşıya yüklenen görüntüyü görüntülemek için Düzelt web sayfalarında kullanılabilir.

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

Bu URL, Veritabanında FixItTask tablosunun sütunlarından biri olarak depolanır.

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; } 
}

Yalnızca veritabanındaki URL ve Blob depolamadaki görüntülerle Düzelt uygulaması veritabanını küçük, ölçeklenebilir ve ucuz tutarken, görüntüler depolamanın ucuz olduğu ve terabayt veya petabayt işleyebilen yerlerde depolanır. Bir depolama hesabı yüzlerce terabaytlık Düzelt fotoğrafını depolayabilir ve yalnızca kullandığınız kadar ödersiniz. Böylece ilk gigabayt için 9 sent ödeyerek küçük bir başlangıç yapabilir ve ek gigabayt başına para için daha fazla görüntü ekleyebilirsiniz.

Karşıya yüklenen dosyayı görüntüleme

Düzelt uygulaması, bir görevin ayrıntılarını görüntülerken karşıya yüklenen görüntü dosyasını görüntüler.

Fotoğrafla Bt görev ayrıntılarını düzeltme

Görüntüyü görüntülemek için MVC görünümünün tek yapması gereken, tarayıcıya gönderilen HTML'deki değeri eklemektir PhotoUrl . Web sunucusu ve veritabanı, görüntüyü görüntülemek için döngüleri kullanmıyor, görüntü URL'sine yalnızca birkaç bayt hizmet ediyor. Aşağıdaki Razor kodunda varlık Model sınıfının bir örneğine başvurur FixItTask .

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

Görüntülenen sayfanın HTML'sine bakarsanız, URL'nin blob depolamadaki görüntüye doğrudan işaret ettiğini görürsünüz, örneğin:

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

Özet

Düzelt uygulamasının Blob hizmetinde görüntüleri ve SQL veritabanındaki yalnızca görüntü URL'lerini nasıl depoladüğünü gördünüz. Blob hizmetinin kullanılması SQL veritabanının normalde olduğundan çok daha küçük olmasını sağlar, neredeyse sınırsız sayıda görev için ölçeği artırmayı mümkün kılar ve çok fazla kod yazmadan yapılabilir.

Bir depolama hesabında yüzlerce terabayt olabilir ve depolama maliyeti, aylık gigabayt başına yaklaşık 3 sent artı küçük bir işlem ücretinden başlayarak SQL Veritabanı depolamadan çok daha ucuzdur. Ayrıca maksimum kapasite için değil yalnızca gerçekten depoladığınız miktar için ödeme yaptığınıza dikkat edin. Bu nedenle uygulamanız ölçeklendirmeye hazır ancak tüm bu ek kapasite için ödeme yapmadınız.

Sonraki bölümde, bir bulut uygulamasını hataları düzgün bir şekilde işleyebilen hale getirmenin öneminden bahsedeceğiz.

Kaynaklar

Daha fazla bilgi için aşağıdaki kaynaklara bakın: