GoSuda

Go-palvelimen suorittaminen laajennettavasti .NET Aspire -ympäristössä

By snowmerak
views ...

dotnet aspire?

dotnet aspire on työkalu, joka on luotu auttamaan kehittäjiä pilvinatiivien sovellusten kehittämisessä ja konfiguroinnissa pilvinatiivien ympäristöjen yleistyessä. Tämä työkalu mahdollistaa .NET-kehittäjien ottaa helposti käyttöön .NET-projekteja ja erilaisia pilvinatiiveja infrastruktuureja sekä muilla kielillä kirjoitettuja palveluita tai kontteja.

Luonnollisesti dockerista k8s:ään on julkaistu ja otettu käyttöön, ja merkittävä määrä aloja, teollisuudenaloja ja kehittäjiä on siirtynyt tai siirtyy perinteisestä on-premise-ympäristöstä pilvinatiiviin ympäristöön. Nyt se on kypsä ala. Siksi en usko, että on tarpeen selittää perinteisiä hankaluuksia, jotka liittyvät isäntänimiin, porttikonfiguraatioihin, palomuureihin ja metrijärjestelmien hallintaan.

Siksi edellä olevien selitysten perusteella on todennäköisesti vaikea ymmärtää, mitä dotnet aspire tarkalleen ottaen on. Tämä johtuu siitä, että edes Microsoft ei ole antanut sille tarkkaa määritelmää. Siksi en myöskään anna sille erillistä määritelmää. Käytän kuitenkin tässä artikkelissa dotnet aspire -työkalun perustoimintoja, sellaisina kuin olen ne itse ymmärtänyt, joten voit käyttää niitä viitteenä määrittääksesi oman näkemyksesi.

Projektin konfiguraatio

dotnet aspire -projektin luominen

Jos dotnet aspire -mallia ei ole, se on asennettava ensin. Asenna malli seuraavalla komennolla. Jos .NET ei ole asennettuna, asenna se itse.

1dotnet new install Aspire.ProjectTemplates

Luo sitten uusi ratkaisu sopivaan kansioon.

1dotnet new sln

Tämän jälkeen suorita seuraava komento ratkaisukansiossa luodaksesi aspire-apphost-mallin mukaisen projektin.

1dotnet new aspire-apphost -o AppHost

Tämä luo aspire-apphost-projektin, joka sisältää vain yksinkertaisen koodin asetuksia varten.

Valkeyn lisääminen

Lisätään nyt yksinkertaisesti Valkey.

Ennen lisäämistä on mainittava, että dotnet aspire tarjoaa erilaisia kolmannen osapuolen ratkaisuja community hosting -palvelun kautta. Luonnollisesti Valkey voi myös hyötyä tästä yhteisön tuesta, ja sitä voidaan helposti käyttää seuraavan nuget-paketin kautta.

1dotnet add package Aspire.Hosting.Valkey

Se tarjoaa myös monia muita integroituja hosting-palveluita, jotka löytyvät täältä. Palataan takaisin Valkeyyn ja avaa AppHost-projektin Program.cs-tiedosto ja muokkaa sitä seuraavasti:

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

cache on IResourceBuilder-rajapinnan toteutus, joka sisältää tiedot Valkey-palvelun rakentamiseen.WithDataVolume luo volyymin välimuistitietojen tallentamista varten, ja WithPersistence mahdollistaa välimuistitietojen jatkuvan tallentamisen. Tähän asti näyttää siltä, että sillä on samankaltainen rooli kuin docker-compose-komennon volumes-kohdalla. On selvää, että voitte luoda tämän itse ilman vaikeuksia. Mutta koska tämä ylittää tämän artikkelin laajuuden, en käsittele sitä nyt.

Go-kielisen Echo-palvelimen luominen

Lisätään nyt yksinkertainen Go-kielinen palvelin. Aluksi luodaan työtila go work init -komennolla ratkaisukansiossa. .NET-kehittäjille Go-työtila on samankaltainen kuin ratkaisu.

Luo sitten kansio nimeltä EchoServer, siirry siihen ja suorita go mod init EchoServer. Tällä komennolla luodaan Go-moduuli. .NET-kehittäjille moduuli on samankaltainen kuin projekti. Luo sitten main.go-tiedosto ja kirjoita siihen seuraava koodi:

 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}

Tämä palvelin lukee PORT-ympäristömuuttujan ja käynnistää palvelimen kyseisessä portissa, kun Aspire AppHost suorittaa sen. Se on yksinkertainen palvelin, joka vastaanottaa name-kyselyparametrin ja palauttaa Hello, {name}.

Lisätään nyt tämä palvelin dotnet aspireen.

Kaikupalvelimen lisääminen aspireen

Siirry takaisin Aspire AppHost -projektiin, johon Valkey lisättiin, ja lisää Go-kielinen community hosting.

1dotnet add package CommunityToolkit.Aspire.Hosting.Golang

Avaa sitten Program.cs-tiedosto ja lisää seuraava lauseke.

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

Tässä echoServer on IResourceBuilder-rajapinnan toteutus, joka sisältää tiedot Go-kielisen palvelimen rakentamiseen. Juuri lisätty AddGolangApp-metodi on mukautetun isännän laajennusmetodi Go-kielisen palvelimen lisäämiseksi. Voimme nähdä, että se käyttää kiinteästi porttia 3000 ja syöttää PORT-ympäristömuuttujan. Lopuksi WithExternalHttpEndpoints mahdollistaa ulkoisen pääsyn.

Jos testaat yhteyden osoitteeseen http://localhost:3000/?name=world, näet todennäköisesti tulosteen "Hello, world".

Kuitenkin dotnet aspirella on tällä hetkellä suuri rangaistus non-dotnet-projekteille. Se on nimittäin...

Projektin laajennus

Miten skaalaus sitten tehdään?

Tällä hetkellä dotnet aspire tarjoaa WithReplica-vaihtoehdon vain AddProject-metodilla lisättyjen .NET-projektien rakentajille. Se ei kuitenkaan tarjoa tätä vaihtoehtoa Go-kielisille isännille tai ulkoisille projekteille, kuten AddContainer.

Siksi on tarpeen toteuttaa tämä erikseen käyttämällä erillistä kuormantasaajaa tai reverse proxya. Tämä voi kuitenkin tehdä reverse proxysta SPOFin, joten reverse proxyn olisi hyvä tarjota WithReplica-vaihtoehto. Tällöin reverse proxyn on välttämättä oltava .NET-projekti.

Olen tähän asti käyttänyt tällaisiin ongelmiin ratkaisuja, kuten nginx, trafik tai oma toteutus, mutta kun rajoituksena on .NET-projekti, minulla ei ollut heti käsillä ratkaisua. Siksi etsin .NET:llä toteutettua reverse proxya, ja onneksi YARP oli vaihtoehto. YARP on .NET:llä toteutettu reverse proxy, joka voi toimia myös kuormantasaajana ja tarjoaa monipuolisia ominaisuuksia, joten se oli hyvä valinta.

Lisätään nyt YARP.

Reverse proxyn konfigurointi YARP:lla

Luodaan ensin projekti YARP:n käyttöä varten.

1dotnet new web -n ReverseProxy

Siirry sitten projektiin ja asenna YARP.

1dotnet add package Yarp.ReverseProxy --version 2.2.0

Kun asennus on valmis, avaa Program.cs-tiedosto ja kirjoita siihen seuraava koodi.

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

Tämä koodi on YARP:n peruskoodi.routes sisältää reititystiedot, joita reverse proxy käyttää, ja clusters sisältää klusteritiedot, joita reverse proxy käyttää. Nämä tiedot ladataan reverse proxyyn LoadFromMemory-metodilla. Lopuksi reverse proxy kartoitetaan ja suoritetaan MapReverseProxy-metodilla.

Käyttöä varten lisätään reverse proxy -projekti viitteeksi aspire apphost -projektiin ja lisätään ja muutetaan seuraava lauseke Program.cs-tiedostoon.

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

Nyt reverse proxy voi viitata kaiku-palvelimeen. Ulkopuolelta tulevat pyynnöt vastaanotetaan reverse proxyssä ja välitetään kaiku-palvelimelle.

Reverse proxyn muokkaaminen

Aluksi reverse proxylle osoitetun projektin kuunteluosoitetta on muutettava. Poista applicationUrl Properties/launchSettings.json -tiedostosta. Avaa sitten Program.cs-tiedosto ja muokkaa sitä laajasti seuraavasti:

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

Ensin reititykseen ja klustereihin liittyviä tietoja muokataan. Lisätään echo-route ja echo-cluster siten, että pyynnöt lähetetään kaiku-palvelimelle. Sitten kaiku-palvelimen osoite luetaan ympäristömuuttujasta.

Tämän osoitteen sääntö on services__{service-name}__http__{index}. Kaiku-palvelimen tapauksessa palvelun nimi on echo-server, ja koska kyseessä on yksittäinen instanssi, indeksinä käytetään 0. Jos lisätään ASP.NET Core -palvelin, WithReplica-toiminnolla voidaan luoda useita instansseja, jolloin indeksiä kasvatetaan. Poikkeuskäsittelyssä oleva http://localhost:8080 on arvoton roskaluku.

Nyt kun suoritat projektin ja avaat http://localhost:3000/?name=world, näet edelleen "Hello, world" -tulosteen.

Laajennusideoita

Olemme nyt lisänneet Go-palvelimen dotnet aspireen ja varmistaneet, että pyynnöt välittyvät reverse proxyn kautta. Voimme nyt laajentaa tätä prosessia siten, että se voidaan toteuttaa ohjelmallisesti. Esimerkiksi echo-palvelimen tapauksessa voidaan luoda useita instansseja lisäämällä numerointi palvelun nimen perään ja lisätä reverse proxyn asetukset automaattisesti.

Muokataan aspire apphost -projektin Program.cs-tiedostossa reverse proxyn ja echo-palvelimen käyttämää koodia seuraavasti:

 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}

Ja muokkaa reverse proxy -projektin Program.cs-tiedostoa seuraavasti:

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

Lisätään kohdeasetukset kahdeksalle laajennetulle echo-palvelimen instanssille. Nyt reverse proxyllä on tiedot laajennettujen echo-palvelimien kohteista ja se voi välittää pyyntöjä niille. Jos muodostat yhteyden vanhaan http://localhost:3000/?name=world -osoitteeseen, huomaat, että "Hello, world" -teksti tulostuu edelleen.

Päätelmät

Tässä artikkelissa selvitettiin Go-palvelimen lisäämistä dotnet aspireen ja pyyntöjen välittämistä reverse proxyn kautta. Laajennusosio ei kuitenkaan ole vielä täysin valmis, ja olen luonut erilliseen repositorioon esimerkin, miten se voidaan toteuttaa ohjelmallisemmin ympäristömuuttujien avulla. Katso tarkempi projektin kokoonpano ja koodi osoitteesta snowmerak/AspireStartPack.

Itse odotan, että dotnet aspire voi toimia Docker Composen vaihtoehtona ja pilveenottotyökaluna, täyttäen oman roolinsa. Jo olemassa olevat generaattorit, jotka luovat Docker Compose- tai k8s-manifesteja, ovat mielestäni parantaneet yleisten kehittäjien mahdollisuuksia käyttää infrastruktuurityökaluja.