iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 28
0

Azure Redis 服務

在使用 WebApp 服務時,在實作Session時,可以使用Redis來儲存session。

關於 Azure Cache for Redis

Azure Cache for Redis定價

https://ithelp.ithome.com.tw/upload/images/20200928/20072651NDBwHbExmO.png

基本

單一節點快取適用於開發/測試和非重大工作負載的單一節點快取。基本層未提供 SLA。

https://ithelp.ithome.com.tw/upload/images/20200928/20072651v9dP1eYUij.png

標準

預設的複寫快取設定為主要/次要兩個節點。我們會管理這兩個節點之間的自動複寫,從而提供高可用性 SLA。

https://ithelp.ithome.com.tw/upload/images/20200928/20072651LdGN5lYI4e.png

創建 Redis Cash Server

查看Redis Cash Server

查看 az redis 指令

az redis -h

https://ithelp.ithome.com.tw/upload/images/20200928/20072651I8qbJEpf35.png

查看 az redis create 指令

az redis create -h 

https://ithelp.ithome.com.tw/upload/images/20200928/20072651tidQSIKWtV.png
https://ithelp.ithome.com.tw/upload/images/20200928/20072651qaoQR1p60J.png

創建Redis Server

位於:eastasia
資源群組:PellokIThomePipelineRG
名稱:pellok-redis
SKU: Basic # Basic, Premium, Standard
VM-SIZE: c0 # c0, c1, c2, c3, c4, c5, c6, p1, p2, p3, p4, p5

az redis create --location eastasia -g PellokIThomePipelineRG --name pellok-redis --sku Basic --vm-size c0

https://ithelp.ithome.com.tw/upload/images/20200928/20072651DYaw1BJClh.png

注意 "hostName": "pellok-redis.redis.cache.windows.net"

取得連線密碼

az redis list-keys -g PellokIThomePipelineRG --name pellok-redis

https://ithelp.ithome.com.tw/upload/images/20200928/20072651ENKMLmuJX5.png

連線字串

pellok-redis.redis.cache.windows.net:6380,password=<password>,ssl=True,abortConnect=False

您可以從 Azure 入口網站取得主機名稱、連接埠和金鑰
https://ithelp.ithome.com.tw/upload/images/20200928/20072651Zc05ySgBW9.png

使用 Redis Cash

快速入門:搭配使用 Azure Cache for Redis 與 .NET Core 應用程式

建立主控台應用程式

dotnet new console -o Redistest

https://ithelp.ithome.com.tw/upload/images/20200928/20072651IknVKITBQ4.png

將祕密管理員新增至專案
編輯 Redistest.csproj 檔案,增加 Microsoft.Extensions.SecretManager.Tools

  <ItemGroup>
    <DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools" Version="2.0.0" />
  </ItemGroup>

將 Microsoft.Extensions.Configuration.UserSecrets 套件新增至專案

dotnet add package Microsoft.Extensions.Configuration.UserSecrets

https://ithelp.ithome.com.tw/upload/images/20200928/20072651npCL5DmZAD.png

設定 dotnet user-secrets 變數名稱 CacheConnection

dotnet user-secrets init

dotnet user-secrets set CacheConnection "pellok-redis.redis.cache.windows.net,abortConnect=false,ssl=true,password=<primary-access-key>"

修改 Program.cs,使用 user-secrets

using Microsoft.Extensions.Configuration;

private static IConfigurationRoot Configuration { get; set; }
const string SecretName = "CacheConnection";

private static void InitializeConfiguration()
{
    var builder = new ConfigurationBuilder()
        .AddUserSecrets<Program>();

    Configuration = builder.Build();
}

完整 Program.cs 程式碼

using System;
using Microsoft.Extensions.Configuration;

namespace Redistest
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
        private static IConfigurationRoot Configuration { get; set; }
        const string SecretName = "CacheConnection";

        private static void InitializeConfiguration()
        {
            var builder = new ConfigurationBuilder()
                .AddUserSecrets<Program>();

            Configuration = builder.Build();
        }
    }
    
}

設定快取用戶端

新增 StackExchange.Redis 套件

dotnet add package StackExchange.Redis

https://ithelp.ithome.com.tw/upload/images/20200928/20072651wHq3NzoGt6.png

在 Program.cs 使用 Redis

using StackExchange.Redis;

private static Lazy<ConnectionMultiplexer> lazyConnection = new Lazy<ConnectionMultiplexer>(() =>
{
    string cacheConnection = Configuration[SecretName];
    return ConnectionMultiplexer.Connect(cacheConnection);
});

public static ConnectionMultiplexer Connection
{
    get
    {
        return lazyConnection.Value;
    }
}

完整 Program.cs 程式碼

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

namespace Redistest
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
        private static IConfigurationRoot Configuration { get; set; }
        const string SecretName = "CacheConnection";

        private static void InitializeConfiguration()
        {
            var builder = new ConfigurationBuilder()
                .AddUserSecrets<Program>();

            Configuration = builder.Build();
        }

        private static Lazy<ConnectionMultiplexer> lazyConnection = new Lazy<ConnectionMultiplexer>(() =>
        {
            string cacheConnection = Configuration[SecretName];
            return ConnectionMultiplexer.Connect(cacheConnection);
        });

        public static ConnectionMultiplexer Connection
        {
            get
            {
                return lazyConnection.Value;
            }
        }
    }
    
}

執行快取命令

修改 Program.cs 檔案

static void Main(string[] args)
{
    InitializeConfiguration();

    // Connection refers to a property that returns a ConnectionMultiplexer
    // as shown in the previous example.
    IDatabase cache = lazyConnection.Value.GetDatabase();

    // Perform cache operations using the cache object...

    // Simple PING command
    string cacheCommand = "PING";
    Console.WriteLine("\nCache command  : " + cacheCommand);
    Console.WriteLine("Cache response : " + cache.Execute(cacheCommand).ToString());

    // Simple get and put of integral data types into the cache
    cacheCommand = "GET Message";
    Console.WriteLine("\nCache command  : " + cacheCommand + " or StringGet()");
    Console.WriteLine("Cache response : " + cache.StringGet("Message").ToString());

    cacheCommand = "SET Message \"Hello! The cache is working from a .NET Core console app!\"";
    Console.WriteLine("\nCache command  : " + cacheCommand + " or StringSet()");
    Console.WriteLine("Cache response : " + cache.StringSet("Message", "Hello! The cache is working from a .NET Core console app!").ToString());

    // Demonstrate "SET Message" executed as expected...
    cacheCommand = "GET Message";
    Console.WriteLine("\nCache command  : " + cacheCommand + " or StringGet()");
    Console.WriteLine("Cache response : " + cache.StringGet("Message").ToString());

    // Get the client list, useful to see if connection list is growing...
    cacheCommand = "CLIENT LIST";
    Console.WriteLine("\nCache command  : " + cacheCommand);
    Console.WriteLine("Cache response : \n" + cache.Execute("CLIENT", "LIST").ToString().Replace("id=", "id="));

    lazyConnection.Value.Dispose();
}

專案建置

dotnet build

https://ithelp.ithome.com.tw/upload/images/20200928/20072651KcMdTyz5Jl.png

執行專案

dotnet run

https://ithelp.ithome.com.tw/upload/images/20200928/20072651X1AGDGrHe9.png

使用快取中的 .NET 物件

新增 Newtonsoft.json 套件至應用程式

dotnet add package Newtonsoft.json
using Newtonsoft.Json;

Employee 類別定義新增至 Program.cs

class Employee
{
    public string Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }

    public Employee(string EmployeeId, string Name, int Age)
    {
        this.Id = EmployeeId;
        this.Name = Name;
        this.Age = Age;
    }
}
// Store .NET object to cache
Employee e007 = new Employee("007", "Davide Columbo", 100);
Console.WriteLine("Cache response from storing Employee .NET object : " + 
cache.StringSet("e007", JsonConvert.SerializeObject(e007)));

// Retrieve .NET object from cache
Employee e007FromCache = JsonConvert.DeserializeObject<Employee>(cache.StringGet("e007"));
Console.WriteLine("Deserialized Employee .NET object :\n");
Console.WriteLine("\tEmployee.Name : " + e007FromCache.Name);
Console.WriteLine("\tEmployee.Id   : " + e007FromCache.Id);
Console.WriteLine("\tEmployee.Age  : " + e007FromCache.Age + "\n");

完整 Program.cs 程式碼

using System;
using Microsoft.Extensions.Configuration;
using StackExchange.Redis;
using Newtonsoft.Json;

namespace Redistest
{
    class Program
    {
        static void Main(string[] args)
        {
            InitializeConfiguration();

            // Connection refers to a property that returns a ConnectionMultiplexer
            // as shown in the previous example.
            IDatabase cache = lazyConnection.Value.GetDatabase();

            // Simple PING command
            string cacheCommand = "PING";
            Console.WriteLine("\nCache command  : " + cacheCommand);
            Console.WriteLine("Cache response : " + cache.Execute(cacheCommand).ToString());

            // Simple get and put of integral data types into the cache
            cacheCommand = "GET Message";
            Console.WriteLine("\nCache command  : " + cacheCommand + " or StringGet()");
            Console.WriteLine("Cache response : " + cache.StringGet("Message").ToString());

            cacheCommand = "SET Message \"Hello! The cache is working from a .NET Core console app!\"";
            Console.WriteLine("\nCache command  : " + cacheCommand + " or StringSet()");
            Console.WriteLine("Cache response : " + cache.StringSet("Message", "Hello! The cache is working from a .NET Core console app!").ToString());

            // Demonstrate "SET Message" executed as expected...
            cacheCommand = "GET Message";
            Console.WriteLine("\nCache command  : " + cacheCommand + " or StringGet()");
            Console.WriteLine("Cache response : " + cache.StringGet("Message").ToString());

            // Get the client list, useful to see if connection list is growing...
            cacheCommand = "CLIENT LIST";
            Console.WriteLine("\nCache command  : " + cacheCommand);
            Console.WriteLine("Cache response : \n" + cache.Execute("CLIENT", "LIST").ToString().Replace("id=", "id="));

            // Store .NET object to cache
            Employee e007 = new Employee("007", "Davide Columbo", 100);
            Console.WriteLine("Cache response from storing Employee .NET object : " + 
            cache.StringSet("e007", JsonConvert.SerializeObject(e007)));

            // Retrieve .NET object from cache
            Employee e007FromCache = JsonConvert.DeserializeObject<Employee>(cache.StringGet("e007"));
            Console.WriteLine("Deserialized Employee .NET object :\n");
            Console.WriteLine("\tEmployee.Name : " + e007FromCache.Name);
            Console.WriteLine("\tEmployee.Id   : " + e007FromCache.Id);
            Console.WriteLine("\tEmployee.Age  : " + e007FromCache.Age + "\n");

            lazyConnection.Value.Dispose();
        }
        private static IConfigurationRoot Configuration { get; set; }
        const string SecretName = "CacheConnection";

        private static void InitializeConfiguration()
        {
            var builder = new ConfigurationBuilder()
                .AddUserSecrets<Program>();

            Configuration = builder.Build();
        }

        private static Lazy<ConnectionMultiplexer> lazyConnection = new Lazy<ConnectionMultiplexer>(() =>
        {
            string cacheConnection = Configuration[SecretName];
            return ConnectionMultiplexer.Connect(cacheConnection);
        });

        public static ConnectionMultiplexer Connection
        {
            get
            {
                return lazyConnection.Value;
            }
        }
    }
    class Employee
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }

        public Employee(string EmployeeId, string Name, int Age)
        {
            this.Id = EmployeeId;
            this.Name = Name;
            this.Age = Age;
        }
    }
    
}

執行程式

dotnet run

https://ithelp.ithome.com.tw/upload/images/20200928/20072651lUtrX3jtmf.png

相關連結:

上一篇 Day27 Azure Blob 儲存體文件
下一篇 Day29 Azure 平台架設 Jenkins 系統


上一篇
Day27 Azure Blob 儲存體文件
下一篇
Day29 Azure 平台架設 Jenkins 系統
系列文
Azure 的自我修煉30

尚未有邦友留言

立即登入留言