Övning – Ansluta en app till cachen
Nu när vår Redis-cache har skapats i Azure ska vi skapa ett program för att använda den. Kontrollera att du har information om din anslutningssträng från Azure Portal.
Kommentar
Integrerad Cloud Shell är tillgängligt till höger. Du kan använda kommandotolken för att skapa och köra exempelkoden som vi skapar här, eller utföra de här stegen lokalt om du har konfigurerat en .NET Core-utvecklingsmiljö.
Skapa ett konsolprogram
Vi använder ett konsolprogram så att vi kan fokusera på Redis-implementeringen.
I Cloud Shell skapar du ett nytt .NET Core-konsolprogram och ger det
SportsStatsTracker
namnet .dotnet new console --name SportsStatsTracker
Ändra aktuell katalog till mappen för det nya projektet.
cd SportsStatsTracker
Lägga till anslutningssträngen
Vi lägger till den anslutningssträng som vi fick från Azure Portal i koden. Lagra aldrig autentiseringsuppgifterna så här i källkoden. För att det här exemplet ska vara enkelt ska vi använda en konfigurationsfil. En bättre metod för ett program på serversidan i Azure är att använda Azure Key Vault med certifikat.
Skapa en ny appsettings.json-fil som ska läggas till i projektet.
touch appsettings.json
Öppna kodredigeraren genom att skriva
code .
i projektmappen. Om du arbetar lokalt rekommenderar vi att du använder Visual Studio Code. De här stegen anpassas huvudsakligen med dess användning.Välj filen appsettings.json i redigeringsprogrammet och lägg till följande text. Klistra in anslutningssträngen i värdet för inställningen.
{ "CacheConnection": "[value-goes-here]" }
Spara ändringarna.
Viktigt!
När du klistrar in eller ändrar kod i en fil i redigeraren ska du spara efteråt med hjälp av menyn ... eller acceleratornyckeln (Ctrl+S i Windows och Linux, Cmd+S på macOS).
Välj filen SportsStatsTracker.csproj i redigeringsprogrammet för att öppna den.
Lägg till följande
<ItemGroup>
konfigurationsblock i rotelementet<Project>
under elementet<PropertyGroup>
. Den här konfigurationen innehåller den nya filen i projektet och kopierar den till utdatamappen. Anvisningarna i det här blocket säkerställer att appkonfigurationsfilen placeras i utdatakatalogen när appen kompileras/skapas.<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> ... </PropertyGroup> <ItemGroup> <None Update="appsettings.json"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> </ItemGroup> </Project>
Spara filen.
Viktigt!
Om du inte sparar filen förlorar du ändringen när du lägger till paketet senare.
Lägga till stöd för läsning från en JSON-konfigurationsfil
Ett .NET Core-program kräver att andra NuGet-paket läser en JSON-konfigurationsfil.
I kommandotolken i fönstret lägger du till en referens till NuGet-paketet Microsoft.Extensions.Configuration.Json :
dotnet add package Microsoft.Extensions.Configuration.Json
Lägga till kod för att läsa konfigurationsfilen
Nu när vi har lagt till de bibliotek som krävs för att aktivera läskonfigurationen måste vi aktivera den funktionen i konsolprogrammet.
Välj Program.cs i redigeraren. Ersätt innehållet i filen med följande kod:
using Microsoft.Extensions.Configuration; namespace SportsStatsTracker { class Program { static void Main(string[] args) { var config = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json") .Build(); } } }
Med
using
instruktionen kan vi komma åt biblioteken för att läsa konfigurationen, och koden iMain
metoden initierar konfigurationssystemet att läsa från appsettings.json-filen.
Hämta anslutningssträngen från konfigurationen
I Program.cs, i slutet av Main-metoden, använder du den nya variabeln config till att hämta anslutningssträngen och lagra den i en ny variabel med namnet connectionString.
Variabeln config innehåller en indexerare där du kan skicka en sträng som hämtas från din appSettings.json-fil.
string connectionString = config["CacheConnection"];
Lägga till stöd för Redis-cachens .NET-klient
Nu ska vi konfigurera konsolprogrammet till att använda StackExchange.Redis-klienten för .NET.
Lägg till NuGet-paketet StackExchange.Redis i projektet med kommandotolken längst ned i Cloud Shell-redigeraren.
dotnet add package StackExchange.Redis
Välj Program.cs i redigeringsprogrammet och lägg till en
using
för namnområdet StackExchange.Redisusing StackExchange.Redis;
När installationen är klar är Redis-cacheklienten redo för användning med ditt projekt.
Ansluta till cachen
Nu ska vi lägga till koden för att ansluta till cachen.
Välj Program.cs i redigeraren.
Skapa en
ConnectionMultiplexer
medConnectionMultiplexer.Connect
genom att skicka den till din anslutningssträng. Ge det returnerade värdet namnet cache.Eftersom anslutningen är kasserbar omsluter du den i ett
using
-block. Koden bör se ut ungefär som följande.string connectionString = config["CacheConnection"]; using (var cache = ConnectionMultiplexer.Connect(connectionString)) { }
Kommentar
Anslutningen till Azure Cache for Redis hanteras av klassen ConnectionMultiplexer
. Den här klassen delas och återanvändas i hela klientprogrammet. Vi vill inte skapa en ny anslutning för varje åtgärd. I stället vill vi lagra den utanför som ett fält i vår klass och återanvända den för varje åtgärd. Här ska vi bara använda den i main-metoden, men i ett produktionsprogram ska den lagras i ett klassfält eller en singleton.
Lägga till ett värde i cachen
Nu när vi har anslutningen ska vi lägga till ett värde i cachen.
I blocket
using
efter att anslutningen har skapats använder duGetDatabase
metoden för att hämta enIDatabase
instans:IDatabase db = cache.GetDatabase();
Anropa
StringSet
iIDatabase
-objektet för att ändra nyckeln ”test:key” till värdet ”some value”.
Returvärdet från StringSet
är en bool
som visar huruvida nyckeln har lagts till.
Visa returvärdet från
StringSet
konsolen:bool setValue = db.StringSet("test:key", "some value"); Console.WriteLine($"SET: {setValue}");
Hämta ett värde från cachen
Sedan hämtar vi värdet med hjälp av
StringGet
. Den här metoden tar nyckeln för att hämta och returnerar värdet.Mata ut det returnerade värdet:
string? getValue = db.StringGet("test:key"); Console.WriteLine($"GET: {getValue}");
Koden bör se ut så hä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}"); } } } }
Kör programmet för att se resultatet. Skriv
dotnet run
i terminalfönstret nedanför redigeringsprogrammet. Kontrollera att du är i projektmappen, annars hittar den inte din kod för att skapa och köra.dotnet run
Dricks
Om programmet inte gör det du förväntar dig, men kompileras, kan det bero på att du inte har sparat ändringarna i redigeraren. Kom alltid ihåg att spara ändringar när du växlar mellan terminalen och redigerarfönstren.
Använda de asynkrona versionerna av metoderna
Vi har kunnat hämta och ange värden från cacheminnet, men vi använder de äldre synkrona versionerna av dessa metoder. I program på serversidan är dessa metoder inte en effektiv användning av våra trådar. I stället vill vi använda de asynkrona versionerna. Du kan enkelt upptäcka dem; de slutar alla i Async.
För att göra dessa metoder enkla att arbeta med använder vi async
i C# och await
-nyckelord. Om du använder en egen .NET Core-utvecklingsmiljö i stället för det integrerade Cloud Shell måste du använda minst C# 7.1 för att kunna tillämpa dessa nyckelord på Main-metoden .
Använda async-nyckelordet
Tillämpa nyckelordet async
på Main-metoden. Vi måste göra två saker.
Lägga till
async
-nyckelordet i Main-metodens signatur.Ändra returtypen från
void
tillTask
.using Microsoft.Extensions.Configuration; using StackExchange.Redis; namespace SportsStatsTracker { class Program { static async Task Main(string[] args) { ...
Hämta och ange värden asynkront
Vi kan låta de synkrona metoderna vara kvar. Nu ska vi lägga till ett anrop till metoderna StringSetAsync
och StringGetAsync
för att lägga till ytterligare ett värde i cacheminnet. Ange räknare till värdet 100.
StringSetAsync
Använd metoderna ochStringGetAsync
för att ange och hämta en nyckel med namnet counter. Ange värdet till 100.Tillämpa
await
-nyckelordet för att få resultat från varje metod.Mata ut resultatet till konsolfönstret, precis som du gjorde med de synkrona versionerna:
// 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}");
Kör programmet igen. Det bör fortfarande fungera och har nu två värden.
Öka värdet
Använd
StringIncrementAsync
-metoden till att öka ditt värde i räknaren. Skicka talet 50 som ska läggas till i räknaren:Observera att metoden tar nyckeln och antingen en
long
ellerdouble
.Beroende på vilka parametrar som skickades returnerar den antingen en
long
ellerdouble
.
Visa resultaten från metoden i konsolen.
long newValue = await db.StringIncrementAsync("counter", 50); Console.WriteLine($"INCR new value = {newValue}");
Andra åtgärder
Slutligen ska vi prova att köra några fler metoder med ExecuteAsync
stöd.
Kör PING för att testa serveranslutningen. Den bör svara med PONG.
Kör FLUSHDB för att rensa databasvärdena. Den bör svara med OK:
var result = await db.ExecuteAsync("ping"); Console.WriteLine($"PING = {result.Type} : {result}"); result = await db.ExecuteAsync("flushdb"); Console.WriteLine($"FLUSHDB = {result.Type} : {result}");
Den slutliga koden bör se ut ungefär så hä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}");
}
}
}
}
När du kör programmet igen bör du se följande utdata:
SET: True
GET: some value
SET: True
GET: 100
INCR new value = 150
PING = SimpleString : PONG
FLUSHDB = SimpleString : OK
Uppgift
Som en utmaning kan du försöka att serialisera en objekttyp till cachen. Här är de grundläggande stegen.
Skapa en ny
class
med några offentliga egenskaper. Du kan göra en egen (”Person” eller ”Bil” är populära), eller använda exemplet ”GameStats” i den föregående utbildningsenhet.Lägg till stöd för NuGet-paketet Newtonsoft.Json med hjälp av
dotnet add package
.Lägg till en
using
förNewtonsoft.Json
-namnområdet.Skapa ett av objekten.
Serialisera det med
JsonConvert.SerializeObject
och användStringSetAsync
för att skicka det till cachen.Hämta tillbaka det från cachen med
StringGetAsync
och deserialisera det sedan medJsonConvert.DeserializeObject<T>
.
Nu när vår Redis-cache har skapats i Azure ska vi skapa ett program för att använda den. Kontrollera att du har information om din anslutning från Azure-portalen.
Kommentar
Integrerad Cloud Shell är tillgängligt till höger. Du kan använda den kommandotolken för att skapa och köra exempelkoden vi skapar här, eller utföra de här stegen lokalt om du har en .Node.js-utvecklingsmiljökonfiguration.
Skapa ett konsolprogram
Vi använder ett konsolprogram så att vi kan fokusera på Redis-implementeringen.
I Cloud Shell skapar du en ny katalog med namnet
redisapp
och initierar en ny Node.js-app där.mkdir redisapp cd redisapp npm init -y touch app.js
Vår app använder följande npm-paket:
- redis: Det vanligaste JavaScript-paketet för anslutning till Redis.
- bluebird: Används för att konvertera metoderna i motringningsstilen
redis
i paketet till ett väntande löfte. - dotenv: Läser in miljövariabler från en
.env
fil, där vi lagrar vår Redis-anslutningsinformation.
Nu ska vi installera dem. Kör det här kommandot för att lägga till dem i vår app:
npm install redis bluebird dotenv
Lägga till konfiguration
Nu ska vi lägga till anslutningsinformationen vi fick från Azure-portalen i en .env
-konfigurationsfil.
Skapa en ny .env-fil i projektet:
touch .env
Öppna kodredigeraren genom att skriva
code .
i projektmappen. Om du arbetar lokalt rekommenderar vi att du använder Visual Studio Code. De här stegen anpassas huvudsakligen med dess användning.Välj .env-filen i redigeraren och klistra in följande text:
REDISHOSTNAME= REDISKEY= REDISPORT=
Klistra in i värdnamnet, primärnyckeln och porten efter är lika med-tecknet på varje respektive rad. Den fullständiga filen ser ut ungefär som följande exempel:
REDISHOSTNAME=myredishost.redis.cache.windows.net REDISKEY=K21mLSMN++z8d1FvIeMGy3VOAgoOmqaNYCqeE44eMDc= REDISPORT=6380
Spara filen med Ctrl + S på Windows och Linux eller Cmd + S på macOS.
Konfigurera implementeringen
Nu är det dags att skriva koden för vårt program.
Välj app.js i redigeringsprogrammet.
Först lägger vi till våra
require
-instruktioner. Klistra in följande kod högst upp i filen.var Promise = require("bluebird"); var redis = require("redis");
Sedan läser vi in konfigurationen
.env
och använder bluebirdspromisifyAll
funktion för att konverteraredis
paketets funktioner och metoder till ett väntande löfte. Klistra in följande kod:require("dotenv").config(); Promise.promisifyAll(redis);
Nu ska vi initiera en Redis-klient. Klistra in den formaterade exempelkoden från föregående lektion (använd
process.env
för att komma åt värdnamnet, porten och nyckeln) för att skapa klienten:const client = redis.createClient( process.env.REDISPORT, process.env.REDISHOSTNAME, { password: process.env.REDISKEY, tls: { servername: process.env.REDISHOSTNAME } } );
Använda klienten för att arbeta med cachen
Vi är redo att skriva kod för att interagera med vår Redis-cache.
Först lägger vi till en
async
funktionsomslutning längst ned i filen för att innehålla vår huvudkod. Vi behöver den här omslutningen för attawait
kunna de asynkrona funktionsanrop som vi ska använda. All resten av koden som vi lägger till i den här lektionen finns i den här omslutningen.(async () => { // The rest of the code you'll paste in goes here. })();
Lägg till ett värde i cachen med
setAsync
-metoden och läs tillbaka det medgetAsync
:console.log("Adding value to the cache"); await client.setAsync("myKey", "myValue"); console.log("Reading value back:"); console.log(await client.getAsync("myKey"));
Skicka ett ping till cachen med
pingAsync
:console.log("Pinging the cache"); console.log(await client.pingAsync());
Ta bort alla nycklar i cachen med
flushdbAsync
:await client.flushdbAsync();
Slutligen stänger du anslutningen med
quitAsync
:await client.quitAsync();
Spara filen. Det färdiga programmet bör se ut så här:
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(); })();
Kör programmet. I Cloud Shell kör du följande kommando.
node app.js
Du bör se nedanstående resultat.
Adding value to the cache Reading value back: myValue Pinging the cache PONG