Próbálja ki a Go szerver futtatását bővíthető módon a dotnet aspire-ben
dotnet aspire?
A dotnet aspire egy olyan eszköz, amelyet a felhőnatív környezetek terjedésével hoztak létre, hogy segítse a fejlesztőket a felhőnatív fejlesztésben és konfigurációban. Ez az eszköz lehetővé teszi a .NET fejlesztők számára, hogy könnyen telepíthessenek .NET projekteket, különféle felhőnatív infrastruktúrákat, valamint más nyelven írt szolgáltatásokat vagy konténereket.
Természetesen a docker-től a k8s-ig terjedően kiadható és üzemeltethető, a meglévő on-premise környezetekből pedig meglehetősen sok terület, iparág és fejlesztő tér át a felhőnatív környezetbe, vagy már át is tért. Ez már egy érett terület. Ezért azt gondolom, hogy nem szükséges elmagyarázni a hosztnevek, portkonfigurációk, tűzfalak és metrikák kezelésének korábbi kényelmetlenségeit.
Ezért a fenti leírások alapján azonnal nem fogja megérteni, hogy mi is a dotnet aspire. Ugyanis a Microsoft sem határozta meg pontosan. Ezért én sem fogok különösebb definíciót adni. Azonban ebben a bejegyzésben a dotnet aspire általam értelmezett alapvető funkcióit fogom használni, ezért kérem, ezt figyelembe véve alakítsa ki saját álláspontját.
Projekt konfiguráció
dotnet aspire projekt létrehozása
Ha nincs dotnet aspire sablon, akkor először a sablont kell telepítenie. Telepítse a sablont a következő paranccsal. Ha nincs .net, akkor azt saját maga telepítse.
1dotnet new install Aspire.ProjectTemplates
Majd hozzon létre egy új megoldást egy megfelelő mappában.
1dotnet new sln
Ezután a megoldás mappájában futtassa a következő parancsot az aspire-apphost sablon projektjének létrehozásához.
1dotnet new aspire-apphost -o AppHost
Ezzel létrejön egy aspire-apphost projekt, amely csak egy egyszerű kódot tartalmaz a beállításhoz.
Valkey hozzáadása
Akkor egyszerűen adjunk hozzá egy Valkey-t.
Mielőtt hozzáadnánk, a dotnet aspire community hostingon keresztül különféle harmadik féltől származó megoldásokat kínál.
Természetesen a valkey is részesülhet a közösségi hosting támogatásában, és a következő nuget csomaggal könnyen használható.
1dotnet add package Aspire.Hosting.Valkey
Emellett különféle integrált hostingot is kínál, melyeket itt tekinthet meg.
Visszatérve a valkeyhez, nyissa meg a Program.cs fájlt az AppHost projektben, és módosítsa a következőképpen.
1var builder = DistributedApplication.CreateBuilder(args);
2
3var cache = builder.AddValkey("cache")
4 .WithDataVolume(isReadOnly: false)
5 .WithPersistence(interval: TimeSpan.FromMinutes(5),
6 keysChangedThreshold: 100);
7
8builder.Build().Run();
A cache
egy IResourceBuilder
interfész implementációja, amely információkat tartalmaz a valkey szolgáltatás létrehozásához.
A WithDataVolume
egy olyan kötetet hoz létre, amelyben a gyorsítótár adatai tárolódnak, a WithPersistence
pedig lehetővé teszi a gyorsítótár adatainak folyamatos tárolását.
Eddig úgy tűnik, hogy a docker-compose
volumes
funkciójához hasonlót látunk.
Természetesen ezt Önök is könnyen létrehozhatják.
Azonban ez a bejegyzés hatókörén kívül esik, ezért most nem fogok erről beszélni.
Go nyelvű echo szerver létrehozása
Akkor adjunk hozzá egy egyszerű Go nyelvű szervert.
Először is hozzon létre egy munkaterületet a go work init
paranccsal a megoldás mappájában.
A .NET fejlesztők számára a Go munkaterület hasonló a megoldáshoz.
Ezután hozzon létre egy EchoServer nevű mappát, lépjen be oda, majd futtassa a go mod init EchoServer
parancsot.
Ezzel a paranccsal egy Go modult hoz létre. A modul a .NET fejlesztők számára a projekthez hasonlóként értelmezhető.
Ezután hozza létre a main.go
fájlt, és írja bele a következőket.
1package main
2
3import (
4 "log"
5 "net/http"
6 "os"
7)
8
9func main() {
10 addr := os.Getenv("PORT")
11 log.Printf("Server started on %s", addr)
12
13 http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) {
14 name := request.URL.Query().Get("name")
15 writer.Write([]byte("Hello, " + name))
16 })
17
18 http.ListenAndServe(":"+addr, nil)
19}
Ez a szerver az Aspire AppHost futtatásakor, a PORT
környezeti változót, amelyen hallgatnia kell, átadja, majd beolvassa ezt a portot és elindítja a szervert.
Egyszerűen megkapja a name
lekérdezést, és visszaadja a Hello, {name}
-t.
Most adjuk hozzá ezt a szervert a dotnet aspire-hoz.
Echo szerver hozzáadása az aspire-hoz
Menjen vissza az Aspire AppHost projekthez, ahova a Valkey-t is hozzáadta, és adja hozzá a Go nyelvű közösségi hostingot.
1dotnet add package CommunityToolkit.Aspire.Hosting.Golang
Ezután nyissa meg a Program.cs fájlt, és adja hozzá a következő kódot.
1var builder = DistributedApplication.CreateBuilder(args);
2
3var cache = builder.AddValkey("cache")
4 .WithDataVolume(isReadOnly: false)
5 .WithPersistence(interval: TimeSpan.FromMinutes(5),
6 keysChangedThreshold: 100);
7
8var echoServer = builder.AddGolangApp("echo-server", "../EchoServer")
9 .WithHttpEndpoint(port: 3000, env: "PORT")
10 .WithExternalHttpEndpoints();
11
12builder.Build().Run();
Itt az echoServer
egy IResourceBuilder
interfész implementációja, amely információkat tartalmaz a Go nyelvű szerver létrehozásához.
Az imént hozzáadott AddGolangApp
metódus egy egyéni gazdagép bővítő metódusa a Go nyelvű szerver hozzáadásához.
Fixen a 3000-es portot használja, és a PORT
környezeti változót adja át, amint látható.
Végül a WithExternalHttpEndpoints
teszi lehetővé a külső hozzáférést.
A teszteléshez, ha a http://localhost:3000/?name=world
-re navigál, akkor a Hello, world
kell, hogy megjelenjen.
Azonban a dotnet aspire-ban jelenleg egy komoly büntetés sújtja a nem .NET projekteket.
Ez pedig...
Projekt kiterjesztése
Akkor hogyan történik a horizontális skálázás?
A dotnet aspire jelenleg csak az AddProject
metódussal hozzáadott .NET projektek builder-eihez biztosítja a WithReplica
opciót.
Azonban a Go nyelvű gazdagépek vagy az AddContainer
típusú külső projektek esetében nem kínálja ezt az opciót.
Ezért külön terheléselosztót vagy fordított proxyt kell használnia a közvetlen megvalósításhoz.
De mivel ez a fordított proxy egyetlen hibaforrássá válhat, a fordított proxy számára is jó lenne a WithReplica
opció.
Akkor elkerülhetetlen, hogy a fordított proxy .NET projekt legyen.
Eddig az nginx, trafik, direkt implementáció és más módszerekkel kezeltük a problémát, de mivel a .NET projekt korlátozás bejött, hirtelen nem volt megoldás a kezemben.
Ezért kerestem egy .NET-tel megvalósított fordított proxyt, és szerencsére ott volt a YARP választási lehetőség.
A YARP egy .NET-tel megvalósított fordított proxy, amely képes terheléselosztóként is működni, és számos funkciót kínált, ezért jó választásnak ítéltem.
Akkor most adjuk hozzá a YARP-t.
Fordított proxy konfigurálása a YARP-pel
Először hozzon létre egy projektet a YARP használatához.
1dotnet new web -n ReverseProxy
Ezután lépjen be a projektbe, és telepítse a YARP-ot.
1dotnet add package Yarp.ReverseProxy --version 2.2.0
A telepítés befejezése után nyissa meg a Program.cs fájlt, és írja bele a következőket.
1using Yarp.ReverseProxy.Configuration;
2
3var builder = WebApplication.CreateBuilder(args);
4
5var routes = new List<RouteConfig>();
6var clusters = new List<ClusterConfig>();
7
8builder.Services.AddReverseProxy()
9 .LoadFromMemory(routes, clusters);
10
11var app = builder.Build();
12
13app.MapReverseProxy();
14app.Run(url: $"http://0.0.0.0:{Environment.GetEnvironmentVariable("PORT") ?? "5000"}");
Ez a kód a YARP használatának alapvető kódja.
A routes
a fordított proxy által használt útvonalinformációkat, a clusters
pedig a fordított proxy által használt klaszterinformációkat tartalmazza.
Ezek az információk a LoadFromMemory
metódussal kerülnek betöltésre a fordított proxyba.
Végül a MapReverseProxy
metódussal leképezi és elindítja a fordított proxyt.
A tényleges használathoz adjon hozzá egy hivatkozást a fordított proxy projektre az aspire apphost projektben, majd adja hozzá és módosítsa a következő kódot a Program.cs fájlban.
1dotnet add reference ../ReverseProxy
1var echoServer = builder.AddGolangApp("echo-server", "../EchoServer")
2 .WithHttpEndpoint(env: "PORT");
3
4var reverseProxy = builder.AddProject<Projects.ReverseProxy>("gateway")
5 .WithReference(echoServer)
6 .WithHttpEndpoint(port: 3000, env: "PORT", isProxied: true)
7 .WithExternalHttpEndpoints();
Most a fordított proxy hivatkozhat az echo szerverre.
A kívülről érkező kéréseket a fordított proxy fogadja, és továbbítja az echo szervernek.
Fordított proxy módosítása
Először is módosítania kell a fordított proxyhoz rendelt projekt figyelési címét.
Távolítsa el az applicationUrl
-t a Properties/launchSettings.json
fájlon belül.
Ezután nyissa meg a Program.cs fájlt, és módosítsa alapvetően az alábbiak szerint.
1using Yarp.ReverseProxy.Configuration;
2
3var builder = WebApplication.CreateBuilder(args);
4
5var routes = new List<RouteConfig>
6{
7 new RouteConfig
8 {
9 ClusterId = "cluster-echo",
10 RouteId = "route-echo",
11 Match = new RouteMatch
12 {
13 Path = "/"
14 }
15 }
16};
17
18var echoServerAddr = Environment.GetEnvironmentVariable("services__echo-server__http__0") ?? "http://localhost:8080";
19
20var clusters = new List<ClusterConfig>
21{
22 new ClusterConfig
23 {
24 ClusterId = "cluster-echo",
25 Destinations = new Dictionary<string, DestinationConfig>
26 {
27 { "destination-echo", new DestinationConfig { Address = echoServerAddr } }
28 }
29 }
30};
31
32builder.Services.AddReverseProxy()
33 .LoadFromMemory(routes, clusters);
34
35var app = builder.Build();
36
37app.MapReverseProxy();
38app.Run(url: $"http://0.0.0.0:{Environment.GetEnvironmentVariable("PORT") ?? "5000"}");
Először is módosítsa az routes
és clusters
információit.
Adjon hozzá egy echo-route
-ot és egy echo-cluster
-t, hogy a kéréseket az echo szerverre küldje.
Ezután módosítsa az echo szerver címét, hogy környezeti változóból olvassa be.
Ennek a címnek a szabálya: services__{service-name}__http__{index}
.
Az echo szerver esetében a szolgáltatás neve echo-server
, és mivel egyetlen példányról van szó, az indexhez a 0
-t használja.
Ha hozzáad egy asp .net core szervert, akkor több példány is létrehozható a WithReplica
segítségével, így az index növelhető.
A http://localhost:8080
kivételkezelése egy értelmetlen szemét érték.
Most, hogy elindítja a projektet, és a http://localhost:3000/?name=world
címre navigál, a Hello, world
jelenik meg.
Bővítési ötlet
Most már ellenőriztük, hogy hozzáadtunk egy Go szervert a dotnet aspire-hoz, és a fordított proxy továbbítja a kéréseket.
Akkor most ezt a folyamatot programozható módon is ki tudjuk terjeszteni.
Például, ha egy számozást ad az echo szerver szolgáltatásneve után, több példányt hozhat létre, és automatikusan hozzáadhatja a fordított proxy konfigurációjához.
Módosítsa a fordított proxyt és az echo szervert használó kódot az aspire apphost projekt Program.cs fájljában az alábbiak szerint.
1var reverseProxy = builder.AddProject<Projects.ReverseProxy>("gateway")
2 .WithHttpEndpoint(port: 3000, env: "PORT", isProxied: true)
3 .WithExternalHttpEndpoints();
4
5for (var i = 0; i < 8; i++)
6{
7 var echoServer = builder.AddGolangApp($"echo-server-{i}", "../EchoServer")
8 .WithHttpEndpoint(env: "PORT");
9 reverseProxy.WithReference(echoServer);
10}
Ezután módosítsa a fordított proxy projekt Program.cs fájlját az alábbiak szerint.
1var echoServerDestinations = new Dictionary<string, DestinationConfig>();
2for (var i = 0; i < 8; i++)
3{
4 echoServerDestinations[$"destination-{i}"] = new DestinationConfig
5 {
6 Address = Environment.GetEnvironmentVariable($"services__echo-server-{i}__http__0") ?? "http://localhost:8080"
7 };
8}
9
10var clusters = new List<ClusterConfig>
11{
12 new ClusterConfig
13 {
14 ClusterId = "cluster-echo",
15 Destinations = echoServerDestinations
16 }
17};
Adjon hozzá egy célhely konfigurációt a 8-ra bővített echo szerver példányhoz.
Most a fordított proxy rendelkezik a megnövekedett számú echo szerver célhely információival, és továbbíthatja a kéréseket.
Ha most a http://localhost:3000/?name=world
címre navigál, továbbra is a Hello, world
jelenik meg.
Összegzés
Ebben a bejegyzésben elmagyaráztam, hogyan kell Go szervert hozzáadni a dotnet aspire-hoz, és hogyan kell a kéréseket a fordított proxy segítségével továbbítani.
A bővítés tekintetében azonban még nem írtam le teljesen, és egy külön repoban helyeztem el a környezeti változókon keresztül programozhatóbb megvalósítást bemutató példákat.
A részletes projektkonfigurációért és kódért tekintse meg a snowmerak/AspireStartPack oldalt.
Én személy szerint remélem, hogy a dotnet aspire a docker compose alternatívájaként, és felhőtelepítési eszközként is képes lesz betölteni a saját szerepét.
Mivel már létezik egy generátor, amely docker compose vagy k8s manifesztet generál, azt gondolom, hogy az átlagos fejlesztők számára a hozzáférés az infrastrukturális eszközökhöz könnyebbé vált.