Alıştırma - Bir uygulamayı önbelleğe bağlama

Tamamlandı

Redis önbelleğimiz Azure'da oluşturulduğuna göre, şimdi bunu kullanmak için bir uygulama oluşturalım. Azure portaldan bağlantı dizesini aldığınızdan emin olun.

Not

Tümleşik Cloud Shell sağ tarafta bulunur. Burada oluşturduğumuz örnek kodu oluşturmak ve çalıştırmak için bu komut istemini kullanabilir veya bir .NET Core geliştirme ortamı ayarladıysanız bu adımları yerel olarak gerçekleştirebilirsiniz.

Konsol uygulaması oluşturma

Redis uygulamasına odaklanabilmemiz için bir konsol uygulaması kullanacağız.

  1. Cloud Shell'de yeni bir .NET Core Konsol Uygulaması oluşturun ve adını verin SportsStatsTracker.

    dotnet new console --name SportsStatsTracker
    
  2. Geçerli dizini yeni projeye yönelik klasör olarak değiştirin.

    cd SportsStatsTracker
    

Bağlantı dizesini ekleme

Şimdi Azure portaldan aldığımız bağlantı dizesini koda ekleyelim. Bunun gibi kimlik bilgilerini asla kaynak kodunuzda depolamayın. Örneği basit tutmak için bir yapılandırma dosyası kullanacağız. Azure'daki bir sunucu uygulamasında en iyi yaklaşım, Azure Key Vault ve sertifikaları kullanmak olacaktır.

  1. Projeye eklemek üzere yeni bir appsettings.json dosyası oluşturun.

    touch appsettings.json
    
  2. Proje klasöründe code . ifadesini girerek kod düzenleyicisini açın. Yerel olarak çalışıyorsanız Visual Studio Code kullanmanızı öneririz. Buradaki adımlar uygulamayla büyük ölçüde paralel gidecektir.

  3. Düzenleyicide appsettings.json dosyasını seçin ve aşağıdaki metni ekleyin. Bağlantı dizenizi ayarın değerine yapıştırın.

    {
      "CacheConnection": "[value-goes-here]"
    }
    
  4. Değişiklikleri kaydedin.

    Önemli

    Düzenleyicideki bir dosyaya her kod yapıştırdığınızda veya değiştirdiğinizde, daha sonra ... menüsünü veya hızlandırıcı tuşunu (Windows ve Linux'ta Ctrl+S, macOS'ta Cmd+S) kullanarak kaydettiğinizden emin olun.

  5. Düzenleyicide açmak için SportsStatsTracker.csproj dosyasını seçin.

  6. Aşağıdaki <ItemGroup> yapılandırma bloğunu öğesinin altındaki <PropertyGroup> kök <Project> öğesine ekleyin. Bu yapılandırma, projedeki yeni dosyayı içerir ve çıkış klasörüne kopyalar. Bu bloktaki yönergeler, uygulama derlendiğinde/derlendiğinde uygulama yapılandırma dosyasının çıkış dizinine yerleştirilmesini sağlar.

    <Project Sdk="Microsoft.NET.Sdk">
    
      <PropertyGroup>
          ...
      </PropertyGroup>
    
      <ItemGroup>
         <None Update="appsettings.json">
           <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
         </None>
      </ItemGroup>
    
    </Project>
    
  7. Dosyayı kaydedin.

    Önemli

    Dosyayı kaydetmezseniz, paketi daha sonra eklediğinizde değişikliği kaybedersiniz.

JSON yapılandırma dosyası okumak için destek ekleme

.NET Core uygulaması, diğer NuGet paketlerinin bir JSON yapılandırma dosyasını okumasını gerektirir.

Pencerenin komut istemi bölümünde Microsoft.Extensions.Configuration.Json NuGet paketine bir başvuru ekleyin:

dotnet add package Microsoft.Extensions.Configuration.Json

Yapılandırma dosyasını okumak için kod ekleme

Okuma yapılandırmasını etkinleştirmek için gerekli kitaplıkları eklediğimize göre, konsol uygulamamızda bu işlevselliği etkinleştirmemiz gerekir.

  1. Düzenleyicide Program.cs’yi seçin. Bu dosyanın içeriğini aşağıdaki kodla değiştirin:

    using Microsoft.Extensions.Configuration;
    
    namespace SportsStatsTracker
    {
        class Program
        {
            static void Main(string[] args)
            {
                var config = new ConfigurationBuilder()
                    .SetBasePath(Directory.GetCurrentDirectory())
                    .AddJsonFile("appsettings.json")
                    .Build();
            }
        }
    }
    

    deyimiusing, yapılandırmayı okumak için kitaplıklara erişmemize olanak tanır ve yöntemdeki Main kod, appsettings.json dosyasından okumak için yapılandırma sistemini başlatır.

Yapılandırmadan bağlantı dizesini alma

Program.cs dosyasında, Main metodunun sonunda, yeni config değişkenini kullanarak bağlantı dizesini alın ve connectionString adlı yeni bir değişkene kaydedin.

config değişkeni, appSettings.json dosyanızdan veri almak için dize gönderebileceğiniz bir dizin oluşturucuya sahiptir.

string connectionString = config["CacheConnection"];

Redis önbelleği .NET istemcisi desteği ekleme

Şimdi .NET için StackExchange.Redis istemcisini kullanmak üzere konsol uygulamasını yapılandıralım.

  1. Cloud Shell düzenleyicisinin en altındaki komut istemini kullanarak StackExchange.Redis NuGet paketini projeye ekleyin.

    dotnet add package StackExchange.Redis
    
  2. Düzenleyicide Program.cs dosyasını seçin ve StackExchange.Redis ad alanı için using sözcüğünü ekleyin

    using StackExchange.Redis;
    

Yükleme tamamlandıktan sonra Redis önbellek istemcisi projeniz ile kullanılabilir duruma gelir.

Önbelleğe bağlanma

Şimdi önbelleğe bağlanmak için gerekli kodu ekleyelim.

  1. Düzenleyicide Program.cs’yi seçin.

  2. Bağlantı dizenizi ileterek ConnectionMultiplexer.Connect kullanan bir ConnectionMultiplexer oluşturun. Döndürülen değere cache adını verin.

  3. Oluşturulan bağlantı atılabilir olduğundan bunu bir using bloğu içine alın. Kodunuz aşağıdaki gibi görünmelidir.

    string connectionString = config["CacheConnection"];
    
    using (var cache = ConnectionMultiplexer.Connect(connectionString))
    {
    
    }
    

Not

Redis için Azure Cache bağlantısı ConnectionMultiplexer sınıfı tarafından yönetilir. Bu sınıf, istemci uygulamanız genelinde paylaşılmalı ve yeniden kullanılmalıdır. Her işlem için yeni bir bağlantı oluşturmak istemiyoruz. Bunun yerine sınıfımızda bir alan olarak kullanıp her işlemde yeniden kullanmak istiyoruz. Burada bunu yalnızca Main yönteminde kullanacağız, ancak bir üretim uygulamasında bir sınıf alanında veya tekil alanda depolanmalıdır.

Önbelleğe değer ekleme

Bağlantıya sahip olduğumuza göre artık önbelleğe değer ekleyebiliriz.

  1. using Bağlantı oluşturulduktan sonra bloğun içinde bir IDatabase örneği almak için yöntemini kullanınGetDatabase:

     IDatabase db = cache.GetDatabase();
    
  2. "test:key" anahtarını "some value" değeri olarak ayarlamak için IDatabase üzerinde StringSet çağrısını yapın.

StringSet metodunun döndürdüğü değer bool türündedir ve anahtarın eklenip eklenmediğini gösterir.

  1. dönüş değerini StringSet konsola görüntüleyin:

     bool setValue = db.StringSet("test:key", "some value");
     Console.WriteLine($"SET: {setValue}");
    

Önbellekten değer alma

  1. Ardından StringGet ile değeri alın. Bu yöntem almak için anahtarı alır ve değerini döndürür.

  2. Döndürülen değerin çıktısını verir:

     string? getValue = db.StringGet("test:key");
     Console.WriteLine($"GET: {getValue}");
    
  3. Kodunuzun şu şekilde olmalıdır:

     using System;
     using Microsoft.Extensions.Configuration;
     using System.IO;
     using StackExchange.Redis;
    
     namespace SportsStatsTracker
     {
         class Program
         {
             static void Main(string[] args)
             {
                 var config = new ConfigurationBuilder()
                     .SetBasePath(Directory.GetCurrentDirectory())
                     .AddJsonFile("appsettings.json")
                     .Build();
    
                 string connectionString = config["CacheConnection"];
    
                 using (var cache = ConnectionMultiplexer.Connect(connectionString))
                 {
                     IDatabase db = cache.GetDatabase();
    
                     bool setValue = db.StringSet("test:key", "some value");
                     Console.WriteLine($"SET: {setValue}");
    
                     string? getValue = db.StringGet("test:key");
                     Console.WriteLine($"GET: {getValue}");
                 }
             }
         }
     }
    
  4. Sonucu görmek için uygulamayı çalıştırın. Düzenleyicinin altındaki terminal penceresine dotnet run ifadesini girin. Proje klasöründe olduğunuzdan emin olun, aksi durumda derlenip çalıştırılacak kodunuzu bulamaz.

     dotnet run
    

İpucu

Program beklediğiniz şeyi yapmaz ancak derlerse, bunun nedeni düzenleyicideki değişiklikleri kaydetmemiş olmanız olabilir. Terminal ile düzenleyici pencereleri arasında geçiş yaparken değişiklikleri kaydetmeyi unutmayın.

Metotların zaman uyumsuz sürümlerini kullanma

Önbellekten değer alıp ayarlayabildik, ancak bu yöntemlerin daha eski zaman uyumlu sürümlerini kullanıyoruz. Sunucu tarafı uygulamalarda bu yöntemler iş parçacıklarımızın verimli bir kullanımı değildir. Bunun yerine, zaman uyumsuz sürümleri kullanmak istiyoruz. Bunları kolayca fark edebilirsiniz; hepsi Async ile biter.

Bu yöntemlerle çalışmayı kolaylaştırmak için C# async ve await anahtar sözcüklerini kullanabiliriz. Tümleşik Cloud Shell yerine kendi .NET Core geliştirme ortamınızı kullanıyorsanız, bu anahtar sözcükleri Main yöntemine uygulayabilmek için en az C# 7.1 kullanmanız gerekir.

async anahtar sözcüğünü uygulama

Anahtar sözcüğünü async Main yöntemine uygulamak için. İki şey yapmamız gerekecek.

  1. Main metodu imzasına async sözcüğünü ekleyin.

  2. Dönüş türünü void yerine Task olarak değiştirin.

    using Microsoft.Extensions.Configuration;
    using StackExchange.Redis;
    
    namespace SportsStatsTracker
    {
       class Program
       {
          static async Task Main(string[] args)
          {
             ...
    

Değerleri zaman uyumsuz şekilde alma ve ayarlama

Zaman uyumlu metotları olduğu gibi bırakabiliriz. Önbelleğe başka bir değer eklemek için StringSetAsync ve StringGetAsync metotlarına yönelik bir çağrı ekleyelim. Sayacı 100 değerine ayarlayın.

  1. StringSetAsync counter adlı bir anahtar ayarlamak ve almak için ve StringGetAsync yöntemlerini kullanın. Değeri 100 olarak ayarlayın.

  2. Metotların sonuçlarını almak için await anahtar sözcüğünü uygulayın.

  3. Sonuçları, zaman uyumlu sürümlerde yaptığınız gibi konsol penceresine çıkış yapın:

    // Simple get and put of integral data types into the cache
    setValue = await db.StringSetAsync("counter", "100");
    Console.WriteLine($"SET: {setValue}");
    
    getValue = await db.StringGetAsync("counter");
    Console.WriteLine($"GET: {getValue}");
    
  4. Uygulamayı yeniden çalıştırın. Çalışmaya devam etmeli ve şimdi iki değere sahip olmalıdır.

Değeri artırma

  1. StringIncrementAsync yöntemini kullanarak counter değerini artırın. Sayaca eklenmek üzere 50 değerini geçirin:

    • Metodun anahtarı velong ya da double değerini aldığına dikkat edin.

    • İletilen parametrelere bağlı olarak long veya double döndürür.

  2. Metodun sonuçlarını konsolda görüntüleyin.

    long newValue = await db.StringIncrementAsync("counter", 50);
    Console.WriteLine($"INCR new value = {newValue}");
    

Diğer işlemler

Son olarak, destekle birkaç yöntem daha yürütmeyi ExecuteAsync deneyelim.

  1. Sunucu bağlantısını test etmek için PING'i yürütür. PONG ile yanıt vermelidir.

  2. Veritabanı değerlerini temizlemek için FLUSHDB'yi yürütür. Tamam ile yanıt vermelidir:

    var result = await db.ExecuteAsync("ping");
    Console.WriteLine($"PING = {result.Type} : {result}");
    
    result = await db.ExecuteAsync("flushdb");
    Console.WriteLine($"FLUSHDB = {result.Type} : {result}");
    

Son kod aşağıdakine benzer olmalıdır:

using Microsoft.Extensions.Configuration;
using StackExchange.Redis;

namespace SportsStatsTracker
{
   class Program
   {
      static async Task Main(string[] args)
      {
         var config = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json")
            .Build();

         string connectionString = config["CacheConnection"];

         using (var cache = ConnectionMultiplexer.Connect(connectionString))
         {
            IDatabase db = cache.GetDatabase();

            bool setValue = db.StringSet("test:key", "some value");
            Console.WriteLine($"SET: {setValue}");

            string getValue = db.StringGet("test:key");
            Console.WriteLine($"GET: {getValue}");

            setValue = await db.StringSetAsync("counter", "100");
            Console.WriteLine($"SET: {setValue}");

            getValue = await db.StringGetAsync("counter");
            Console.WriteLine($"GET: {getValue}");

            long newValue = await db.StringIncrementAsync("counter", 50);
            Console.WriteLine($"INCR new value = {newValue}");  

            var result = await db.ExecuteAsync("ping");
            Console.WriteLine($"PING = {result.Type} : {result}");

            result = await db.ExecuteAsync("flushdb");
            Console.WriteLine($"FLUSHDB = {result.Type} : {result}");
         }
      }
   }
}

Uygulamayı yeniden çalıştırdığınızda aşağıdaki çıkışı görmeniz gerekir:

SET: True
GET: some value
SET: True
GET: 100
INCR new value = 150
PING = SimpleString : PONG
FLUSHDB = SimpleString : OK

Sınama

Sınama kapsamında bir nesne türünü önbellek için seri hale getirmeyi deneyin. Temel adımlar aşağıda verilmiştir.

  1. Ortak özelliklere sahip yeni bir class oluşturun. Kendiniz bir tane oluşturabilir ("Person" veya "Car" popülerdir) veya önceki ünitede verilen "GameStats" örneğini kullanabilirsiniz.

  2. dotnet add package kullanarak Newtonsoft.Json NuGet paketi için destek ekleyin.

  3. Newtonsoft.Json ad alanı için bir using ekleyin.

  4. Nesnelerinizden birini oluşturun.

  5. JsonConvert.SerializeObject ile seri hale getirin ve StringSetAsync kullanarak önbelleğe gönderin.

  6. StringGetAsync ile önbellekten geri alın ve JsonConvert.DeserializeObject<T> ile seri durumdan çıkarın.

Redis önbelleğimiz Azure'da oluşturulduğuna göre, şimdi bunu kullanmak için bir uygulama oluşturalım. Azure portalından bağlantı bilgilerini aldığınızdan emin olun.

Not

Tümleşik Cloud Shell sağ tarafta bulunur. Burada gösterilen kodu oluşturup çalıştırmak için bu komut istemini kullanabilir veya bir Node.js geliştirme ortamınız varsa bu adımları yerel olarak gerçekleştirebilirsiniz.

Konsol Uygulaması oluşturma

Redis uygulamasına odaklanabilmemiz için bir konsol uygulaması kullanacağız.

  1. Cloud Shell'de redisapp adlı yeni bir dizin oluşturun ve burada yeni bir Node.js uygulaması başlatın.

     mkdir redisapp
     cd redisapp
     npm init -y
     touch app.js
    
  2. Uygulamamız aşağıdaki npm paketlerini kullanacaktır:

    • redis: Redis'e bağlanmak için en yaygın kullanılan JavaScript paketidir.
    • bluebird: Paketteki geri çağırma stili yöntemleri redis beklenebilir bir Promise'e dönüştürmek için kullanılır.
    • dotenv: Redis bağlantı bilgilerimizi depolayacağımız dosyadan .env ortam değişkenlerini yükler.

    Şimdi onları yükleyelim. Onları uygulamamıza eklemek için şu komutu çalıştırın:

    npm install redis bluebird dotenv
    

Yapılandırma ekleme

Azure portalından aldığımız bağlantı bilgilerini .env yapılandırma dosyasına ekleyelim.

  1. Projeye yeni bir .env dosyası oluşturun:

    touch .env
    
  2. Proje klasöründe code . ifadesini girerek kod düzenleyicisini açın. Yerel olarak çalışıyorsanız Visual Studio Code kullanmanızı öneririz. Buradaki adımlar uygulamayla büyük ölçüde paralel gidecektir.

  3. Düzenleyicide .env dosyasını seçin ve aşağıdaki metni yapıştırın:

    REDISHOSTNAME=
    REDISKEY=
    REDISPORT=
    
  4. İlgili satırların her birine eşittir işaretinden sonra konak adını, birincil anahtarı ve bağlantı noktasını yapıştırın. Dosyanın tamamı aşağıdaki örneğe benzer şekilde görünür:

    REDISHOSTNAME=myredishost.redis.cache.windows.net
    REDISKEY=K21mLSMN++z8d1FvIeMGy3VOAgoOmqaNYCqeE44eMDc=
    REDISPORT=6380
    
  5. Windows ve Linux'ta Ctrl+S tuşlarıyla veya macOS'ta Cmd+S tuşlarıyla dosyayı kaydedin.

Uygulamayı ayarlama

Şimdi uygulamamızın kodunu yazmanın zamanı geldi.

  1. Düzenleyicide app.js öğesini seçin.

  2. İlk olarak require deyimlerimizi ekleyeceğiz. Dosyanın üst kısmına aşağıdaki kodu yapıştırın.

    var Promise = require("bluebird");
    var redis = require("redis");
    
  3. Ardından yapılandırmamızı .env yükleyip bluebird promisifyAll işlevini kullanarak paketin redis işlevlerini ve yöntemlerini beklenebilir bir Promise'e dönüştüreceğiz. Aşağıdaki kodu yapıştırın:

    require("dotenv").config();
    Promise.promisifyAll(redis);
    
  4. Şimdi Redis istemcisini başlatacağız. İstemciyi oluşturmak için önceki üniteden demirbaş kodu (konak adı, bağlantı noktası ve anahtarımıza erişmek için process.env kullanarak) yapıştırın:

    const client = redis.createClient(
       process.env.REDISPORT,
       process.env.REDISHOSTNAME,
       {
          password: process.env.REDISKEY,
          tls: { servername: process.env.REDISHOSTNAME }
       }
    );
    

Önbellekle çalışmak için istemciyi kullanma

Redis önbelleğimizle etkileşim kurmak için kodu yazmaya hazırız.

  1. İlk olarak, dosyanın alt kısmına ana kodumuzu içerecek bir async işlev sarmalayıcı ekleyeceğiz. Kullanacağımız zaman uyumsuz işlev çağrılarını yapabilmek için await bu sarmalayıcıya ihtiyacımız var. Bu ünitede ekleyeceğiniz kodun geri kalanı bu sarmalayıcıda olacak.

    (async () => {
    
       // The rest of the code you'll paste in goes here.
    
    })();
    
  2. Önbelleğe setAsync yöntemiyle bir değer ekleyin ve getAsync ile bunu geri okuyun:

    console.log("Adding value to the cache");
    await client.setAsync("myKey", "myValue");
    
    console.log("Reading value back:");
    console.log(await client.getAsync("myKey"));
    
  3. pingAsync ile önbelleğe bir ping gönderin:

    console.log("Pinging the cache");
    console.log(await client.pingAsync());
    
  4. Önbellekteki tüm anahtarları flushdbAsync ile silin:

    await client.flushdbAsync();
    
  5. Son olarak quitAsync ile bağlantıyı kapatın:

    await client.quitAsync();
    
  6. Dosyayı kaydedin. Bitmiş uygulamanızın şuna benzer olması gerekir:

    var Promise = require("bluebird");
    var redis = require("redis");
    
    require("dotenv").config();
    
    Promise.promisifyAll(redis);
    
    const client = redis.createClient(
    process.env.REDISPORT,
    process.env.REDISHOSTNAME,
    {
       password: process.env.REDISKEY,
       tls: { servername: process.env.REDISHOSTNAME }
    }
    );
    
    (async () => {
      console.log("Adding value to the cache");
      await client.setAsync("myKey", "myValue");
      console.log("Reading value back:");
      console.log(await client.getAsync("myKey"));
      console.log("Pinging the cache");
      console.log(await client.pingAsync());
      await client.flushdbAsync();
      await client.quitAsync();
    })();
    
  7. Uygulamayı çalıştırın. Cloud Shell’de aşağıdaki komutu yürütün.

    node app.js
    

    Aşağıdaki sonuçları görürsünüz.

    Adding value to the cache
    Reading value back:
    myValue
    Pinging the cache
    PONG