Samouczek: tworzenie aplikacji usługi Service Fabric platformy .NET
Ten samouczek jest częścią jednej z serii. Z tego samouczka dowiesz się, jak utworzyć aplikację usługi Azure Service Fabric z frontonem internetowego interfejsu API platformy ASP.NET Core i stanową usługą zaplecza do przechowywania danych. Po zakończeniu masz aplikację do głosowania z frontonem internetowym ASP.NET Core, która zapisuje wyniki głosowania w stanowej usłudze zaplecza w klastrze.
Ta seria samouczków wymaga komputera dewelopera z systemem Windows. Jeśli nie chcesz ręcznie tworzyć aplikacji do głosowania, możesz pobrać kod źródłowy ukończonej aplikacji i przejść od razu do sekcji Szczegółowe omówienie przykładowej aplikacji do głosowania. Możesz również wyświetlić przewodnik wideo z tego samouczka.
Z tego samouczka dowiesz się, jak wykonywać następujące czynności:
- Tworzenie usługi internetowego interfejsu API platformy ASP.NET Core jako niezawodnej stanowej usługi
- Tworzenie usługi aplikacji internetowej platformy ASP.NET Core jako bezstanowej usługi internetowej
- Używanie zwrotnego serwera proxy do komunikowania się z usługą stanową
W serii samouczków pokazano, jak wykonać następujące działania:
- Tworzenie aplikacji .NET Service Fabric (w tym samouczku)
- Wdrażanie aplikacji w klastrze zdalnym
- Dodawanie punktu końcowego HTTPS do usługi frontonu platformy ASP.NET Core
- Konfigurowanie ciągłej integracji/ciągłego wdrażania przy użyciu usługi Azure Pipelines
- Konfigurowanie monitorowania i diagnostyki dla aplikacji
Wymagania wstępne
Przed rozpoczęciem tego samouczka:
- Jeśli nie masz subskrypcji platformy Azure, utwórz bezpłatne konto.
- Zainstaluj program Visual Studio 2019 w wersji 15.5 lub nowszej, w tym pakiet roboczy Programowanie na platformie Azure oraz pakiet roboczy tworzenia aplikacji internetowych i ASP.NET.
- Zainstaluj zestaw SDK usługi Service Fabric.
Tworzenie usługi internetowego interfejsu API platformy ASP.NET jako niezawodnej usługi
Najpierw utwórz fronton internetowy aplikacji do głosowania przy użyciu ASP.NET Core. ASP.NET Core to uproszczone międzyplatformowe środowisko programistyczne, którego można używać do tworzenia nowoczesnych internetowych interfejsów użytkownika i interfejsów API.
Aby uzyskać pełną wiedzę na temat integracji ASP.NET Core z usługą Service Fabric, zdecydowanie zalecamy przejrzenie ASP.NET Core w usłudze Service Fabric Reliable Services. Na tym etapie wystarczy wykonać czynności opisane w tym samouczku, aby szybko rozpocząć pracę. Aby dowiedzieć się więcej na temat ASP.NET Core, zobacz dokumentację platformy ASP.NET Core.
Aby utworzyć usługę:
Otwórz program Visual Studio przy użyciu opcji Uruchom jako administrator .
Wybierz pozycję Plik>nowy>projekt, aby utworzyć nowy projekt.
W obszarze Tworzenie nowego projektu wybierz pozycję Aplikacja usługi Cloud>Service Fabric. Wybierz Dalej.
Wybierz pozycję Bezstanowe ASP.NET Core dla nowego typu projektu, nadaj usłudze nazwę VotingWeb, a następnie wybierz pozycję Utwórz.
W następnym okienku zostanie wyświetlony zestaw szablonów projektów ASP.NET Core. Na potrzeby tego samouczka wybierz pozycję Aplikacja internetowa (Model-View-Controller), a następnie wybierz przycisk OK.
Program Visual Studio tworzy aplikację i projekt usługi, a następnie wyświetla je w programie Visual Studio Eksplorator rozwiązań:
Aktualizowanie pliku site.js
Przejdź do strony wwwroot/js/site.js i otwórz plik. Zastąp zawartość pliku następującym kodem JavaScript używanym przez widoki Narzędzia główne, a następnie zapisz zmiany.
var app = angular.module('VotingApp', ['ui.bootstrap']);
app.run(function () { });
app.controller('VotingAppController', ['$rootScope', '$scope', '$http', '$timeout', function ($rootScope, $scope, $http, $timeout) {
$scope.refresh = function () {
$http.get('api/Votes?c=' + new Date().getTime())
.then(function (data, status) {
$scope.votes = data;
}, function (data, status) {
$scope.votes = undefined;
});
};
$scope.remove = function (item) {
$http.delete('api/Votes/' + item)
.then(function (data, status) {
$scope.refresh();
})
};
$scope.add = function (item) {
var fd = new FormData();
fd.append('item', item);
$http.put('api/Votes/' + item, fd, {
transformRequest: angular.identity,
headers: { 'Content-Type': undefined }
})
.then(function (data, status) {
$scope.refresh();
$scope.item = undefined;
})
};
}]);
Aktualizowanie pliku Index.cshtml
Przejdź do pozycji Views/Home/Index.cshtml i otwórz plik. Ten plik ma widok specyficzny dla kontrolera home. Zastąp jego zawartość następującym kodem, a następnie zapisz zmiany.
@{
ViewData["Title"] = "Service Fabric Voting Sample";
}
<div ng-controller="VotingAppController" ng-init="refresh()">
<div class="container-fluid">
<div class="row">
<div class="col-xs-8 col-xs-offset-2 text-center">
<h2>Service Fabric Voting Sample</h2>
</div>
</div>
<div class="row">
<div class="col-xs-8 col-xs-offset-2">
<form class="col-xs-12 center-block">
<div class="col-xs-6 form-group">
<input id="txtAdd" type="text" class="form-control" placeholder="Add voting option" ng-model="item"/>
</div>
<button id="btnAdd" class="btn btn-default" ng-click="add(item)">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
Add
</button>
</form>
</div>
</div>
<hr/>
<div class="row">
<div class="col-xs-8 col-xs-offset-2">
<div class="row">
<div class="col-xs-4">
Click to vote
</div>
</div>
<div class="row top-buffer" ng-repeat="vote in votes.data">
<div class="col-xs-8">
<button class="btn btn-success text-left btn-block" ng-click="add(vote.Key)">
<span class="pull-left">
{{vote.key}}
</span>
<span class="badge pull-right">
{{vote.value}} Votes
</span>
</button>
</div>
<div class="col-xs-4">
<button class="btn btn-danger pull-right btn-block" ng-click="remove(vote.Key)">
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
Remove
</button>
</div>
</div>
</div>
</div>
</div>
</div>
Aktualizowanie pliku _Layout.cshtml
Przejdź do pozycji Views/Shared/_Layout.cshtml i otwórz plik. Ten plik ma domyślny układ aplikacji ASP.NET. Zastąp jego zawartość następującym kodem, a następnie zapisz zmiany.
<!DOCTYPE html>
<html ng-app="VotingApp" xmlns:ng="https://angularjs.org">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>@ViewData["Title"]</title>
<link href="~/lib/bootstrap/dist/css/bootstrap.css" rel="stylesheet"/>
<link href="~/css/site.css" rel="stylesheet"/>
</head>
<body>
<div class="container body-content">
@RenderBody()
</div>
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.2/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.5.0/ui-bootstrap-tpls.js"></script>
<script src="~/js/site.js"></script>
@RenderSection("Scripts", required: false)
</body>
</html>
Aktualizowanie pliku VotingWeb.cs
Otwórz plik VotingWeb.cs. Ten plik tworzy ASP.NET Core WebHost wewnątrz usługi bezstanowej przy użyciu serwera internetowego WebListener.
Na początku pliku dodaj dyrektywę using System.Net.Http;
.
CreateServiceInstanceListeners()
Zastąp funkcję następującym kodem, a następnie zapisz zmiany.
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return new ServiceInstanceListener[]
{
new ServiceInstanceListener(
serviceContext =>
new KestrelCommunicationListener(
serviceContext,
"ServiceEndpoint",
(url, listener) =>
{
ServiceEventSource.Current.ServiceMessage(serviceContext, $"Starting Kestrel on {url}");
return new WebHostBuilder()
.UseKestrel()
.ConfigureServices(
services => services
.AddSingleton<HttpClient>(new HttpClient())
.AddSingleton<FabricClient>(new FabricClient())
.AddSingleton<StatelessServiceContext>(serviceContext))
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
.UseUrls(url)
.Build();
}))
};
}
Następnie dodaj następującą GetVotingDataServiceName
metodę po CreateServiceInstanceListeners()
metodzie , a następnie zapisz zmiany. Metoda GetVotingDataServiceName
zwraca nazwę usługi w przypadku sondowania.
internal static Uri GetVotingDataServiceName(ServiceContext context)
{
return new Uri($"{context.CodePackageActivationContext.ApplicationName}/VotingData");
}
Dodawanie pliku VotesController.cs
Dodaj kontroler w celu zdefiniowania akcji głosowania. Kliknij prawym przyciskiem myszy folder Controllers, a następnie wybierz polecenie Dodaj>nowy element>Visual C#>ASP.NET Core>Class. Nadaj plikowi nazwę VotesController.cs, a następnie wybierz pozycję Dodaj.
Zastąp zawartość pliku VotesController.cs następującym kodem, a następnie zapisz zmiany. Dalej, w sekcji Aktualizowanie pliku VotesController.cs, ten plik zostanie zmodyfikowany na potrzeby odczytywania danych głosowania z usługi zaplecza i ich zapisywania. Na razie ten kontroler zwraca do widoku dane w postaci statycznego ciągu.
namespace VotingWeb.Controllers
{
using System;
using System.Collections.Generic;
using System.Fabric;
using System.Fabric.Query;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
[Produces("application/json")]
[Route("api/Votes")]
public class VotesController : Controller
{
private readonly HttpClient httpClient;
public VotesController(HttpClient httpClient)
{
this.httpClient = httpClient;
}
// GET: api/Votes
[HttpGet]
public async Task<IActionResult> Get()
{
List<KeyValuePair<string, int>> votes= new List<KeyValuePair<string, int>>();
votes.Add(new KeyValuePair<string, int>("Pizza", 3));
votes.Add(new KeyValuePair<string, int>("Ice cream", 4));
return Json(votes);
}
}
}
Konfigurowanie portu nasłuchującego
Po utworzeniu usługi frontonu VotingWeb program Visual Studio losowo wybiera port, na którym usługa będzie nasłuchiwała. Usługa VotingWeb działa jako fronton dla tej aplikacji i akceptuje ruch zewnętrzny. W tej sekcji powiążesz tę usługę ze stałym i dobrze znanym portem. Manifest usługi deklaruje punkty końcowe usługi.
W Eksploratorze rozwiązań otwórz plik VotingWeb/PackageRoot/ServiceManifest.xml. Resources
W sekcji znajdź Endpoint
element , a następnie zmień wartość na Port
8080
.
Aby wdrożyć i uruchomić aplikację lokalnie, port nasłuchujący aplikacji musi być otwarty i dostępny na komputerze.
<Resources>
<Endpoints>
<!-- This endpoint is used by the communication listener to obtain the port on which to
listen. Please note that if your service is partitioned, this port is shared with
replicas of different partitions that are placed in your code. -->
<Endpoint Protocol="http" Name="ServiceEndpoint" Type="Input" Port="8080" />
</Endpoints>
</Resources>
Następnie zaktualizuj Application URL
wartość właściwości w projekcie Voting, aby przeglądarka internetowa otwierała prawidłowy port podczas debugowania aplikacji. W Eksplorator rozwiązań wybierz projekt Voting, a następnie zaktualizuj Application URL
właściwość na 8080
.
Wdrażanie i uruchamianie aplikacji Voting lokalnie
Teraz możesz uruchomić aplikację Voting, aby ją debugować. W programie Visual Studio wybierz pozycję F5, aby wdrożyć aplikację w lokalnym klastrze usługi Service Fabric w trybie debugowania. Aplikacja kończy się niepowodzeniem, jeśli wcześniej nie otwarto programu Visual Studio przy użyciu opcji Uruchom jako administrator .
Uwaga
Przy pierwszym uruchomieniu i wdrożeniu aplikacji lokalnie program Visual Studio tworzy lokalny klaster usługi Service Fabric do użycia do debugowania. Proces tworzenia klastra może zająć trochę czasu. Stan tworzenia klastra jest wyświetlany w oknie Dane wyjściowe programu Visual Studio.
Po wdrożeniu aplikacji do głosowania w lokalnym klastrze usługi Service Fabric aplikacja internetowa zostanie automatycznie otwarta na karcie przeglądarki. Wygląda podobnie do tego przykładu:
Aby zatrzymać debugowanie aplikacji, wróć do programu Visual Studio i wybierz pozycję Shift+F5.
Dodawanie stanowej usługi zaplecza do aplikacji
Teraz, gdy usługa internetowego interfejsu API ASP.NET jest uruchomiona w aplikacji, dodaj stanową niezawodną usługę do przechowywania niektórych danych w aplikacji.
Za pomocą usługi Service Fabric można spójnie i niezawodnie przechowywać dane w usłudze przy użyciu niezawodnych kolekcji. Niezawodne kolekcje to zestaw klas kolekcji o wysokiej dostępności i niezawodności, które są znane każdemu, kto ma doświadczenie w korzystaniu z kolekcji języka C#.
Aby utworzyć usługę, która przechowuje wartość licznika w niezawodnej kolekcji:
W Eksplorator rozwiązań kliknij prawym przyciskiem myszy pozycję Usługi w projekcie aplikacji do głosowania i wybierz pozycję Dodaj>nową usługę Service Fabric.
W oknie dialogowym Nowa usługa Service Fabric wybierz pozycję Stanowe ASP.NET Core, nadaj usłudze nazwę VotingData, a następnie wybierz przycisk OK.
Po utworzeniu projektu usługi masz dwie usługi w aplikacji. W miarę kontynuowania tworzenia aplikacji możesz dodać więcej usług w taki sam sposób. Każda usługa może być niezależnie wersjonowana i uaktualniana.
W następnym okienku zostanie wyświetlony zestaw szablonów projektów ASP.NET Core. Na potrzeby tego samouczka wybierz pozycję Interfejs API.
Program Visual Studio tworzy projekt usługi VotingData i wyświetla go w Eksplorator rozwiązań:
Dodawanie pliku VoteDataController.cs
W projekcie VotingData kliknij prawym przyciskiem myszy folder Controllers, a następnie wybierz polecenie Dodaj>nową klasę elementu.> Nadaj plikowi nazwę VoteDataController.cs i wybierz pozycję Dodaj. Zastąp zawartość pliku następującym kodem, a następnie zapisz zmiany.
namespace VotingData.Controllers
{
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.ServiceFabric.Data;
using Microsoft.ServiceFabric.Data.Collections;
[Route("api/[controller]")]
public class VoteDataController : Controller
{
private readonly IReliableStateManager stateManager;
public VoteDataController(IReliableStateManager stateManager)
{
this.stateManager = stateManager;
}
// GET api/VoteData
[HttpGet]
public async Task<IActionResult> Get()
{
CancellationToken ct = new CancellationToken();
IReliableDictionary<string, int> votesDictionary = await this.stateManager.GetOrAddAsync<IReliableDictionary<string, int>>("counts");
using (ITransaction tx = this.stateManager.CreateTransaction())
{
Microsoft.ServiceFabric.Data.IAsyncEnumerable<KeyValuePair<string, int>> list = await votesDictionary.CreateEnumerableAsync(tx);
Microsoft.ServiceFabric.Data.IAsyncEnumerator<KeyValuePair<string, int>> enumerator = list.GetAsyncEnumerator();
List<KeyValuePair<string, int>> result = new List<KeyValuePair<string, int>>();
while (await enumerator.MoveNextAsync(ct))
{
result.Add(enumerator.Current);
}
return this.Json(result);
}
}
// PUT api/VoteData/name
[HttpPut("{name}")]
public async Task<IActionResult> Put(string name)
{
IReliableDictionary<string, int> votesDictionary = await this.stateManager.GetOrAddAsync<IReliableDictionary<string, int>>("counts");
using (ITransaction tx = this.stateManager.CreateTransaction())
{
await votesDictionary.AddOrUpdateAsync(tx, name, 1, (key, oldvalue) => oldvalue + 1);
await tx.CommitAsync();
}
return new OkResult();
}
// DELETE api/VoteData/name
[HttpDelete("{name}")]
public async Task<IActionResult> Delete(string name)
{
IReliableDictionary<string, int> votesDictionary = await this.stateManager.GetOrAddAsync<IReliableDictionary<string, int>>("counts");
using (ITransaction tx = this.stateManager.CreateTransaction())
{
if (await votesDictionary.ContainsKeyAsync(tx, name))
{
await votesDictionary.TryRemoveAsync(tx, name);
await tx.CommitAsync();
return new OkResult();
}
else
{
return new NotFoundResult();
}
}
}
}
}
Łączenie usług
W tej sekcji połączysz dwie usługi. Aplikacja internetowa frontonu uzyskuje informacje o głosowaniu z usługi zaplecza, a następnie ustawia informacje w aplikacji.
Usługa Service Fabric zapewnia pełną elastyczność w sposobie komunikowania się z niezawodnymi usługami. W ramach jednej aplikacji mogą istnieć usługi, które są dostępne za pośrednictwem protokołu TCP/IP, za pośrednictwem interfejsu API REST PROTOKOŁU HTTP lub za pośrednictwem protokołu WebSocket. Aby zapoznać się z dostępnymi opcjami i ich kompromisami, zobacz Komunikacja z usługami.
W tym samouczku użyto ASP.NET Core internetowego interfejsu API i zwrotnego serwera proxy usługi Service Fabric, aby usługa internetowa frontonu VotingWeb mogła komunikować się z usługą VotingData zaplecza. Zwrotny serwer proxy jest domyślnie skonfigurowany do używania portu 19081. Port zwrotnego serwera proxy jest ustawiany w szablonie usługi Azure Resource Manager, który konfiguruje klaster. Aby dowiedzieć się, który port jest używany, poszukaj w szablonie klastra w zasobie Microsoft.ServiceFabric/clusters
:
"nodeTypes": [
{
...
"httpGatewayEndpointPort": "[variables('nt0fabricHttpGatewayPort')]",
"isPrimary": true,
"vmInstanceCount": "[parameters('nt0InstanceCount')]",
"reverseProxyEndpointPort": "[parameters('SFReverseProxyPort')]"
}
],
Aby znaleźć port zwrotnego serwera proxy używany w lokalnym klastrze programistycznym, wyświetl HttpApplicationGatewayEndpoint
element w lokalnym manifeście klastra usługi Service Fabric:
- Aby otworzyć narzędzie Service Fabric Explorer, otwórz przeglądarkę i przejdź do
http://localhost:19080
witryny . - Wybierz pozycję Manifest klastra>.
- Zanotuj
HttpApplicationGatewayEndpoint
port elementu. Domyślnie port to 19081. Jeśli nie jest to 19081, zmień port wGetProxyAddress
metodzie VotesController.cs kodu zgodnie z opisem w następnej sekcji.
Aktualizowanie pliku VotesController.cs
W projekcie VotingWeb otwórz plik Controllers/VotesController.cs . Zastąp VotesController
zawartość definicji klasy następującym kodem, a następnie zapisz zmiany. Jeśli port zwrotnego serwera proxy wykryty w kroku nie jest 19081, zmień port w GetProxyAddress
metodzie z 19081
na odnaleziony port.
public class VotesController : Controller
{
private readonly HttpClient httpClient;
private readonly FabricClient fabricClient;
private readonly StatelessServiceContext serviceContext;
public VotesController(HttpClient httpClient, StatelessServiceContext context, FabricClient fabricClient)
{
this.fabricClient = fabricClient;
this.httpClient = httpClient;
this.serviceContext = context;
}
// GET: api/Votes
[HttpGet("")]
public async Task<IActionResult> Get()
{
Uri serviceName = VotingWeb.GetVotingDataServiceName(this.serviceContext);
Uri proxyAddress = this.GetProxyAddress(serviceName);
ServicePartitionList partitions = await this.fabricClient.QueryManager.GetPartitionListAsync(serviceName);
List<KeyValuePair<string, int>> result = new List<KeyValuePair<string, int>>();
foreach (Partition partition in partitions)
{
string proxyUrl =
$"{proxyAddress}/api/VoteData?PartitionKey={((Int64RangePartitionInformation) partition.PartitionInformation).LowKey}&PartitionKind=Int64Range";
using (HttpResponseMessage response = await this.httpClient.GetAsync(proxyUrl))
{
if (response.StatusCode != System.Net.HttpStatusCode.OK)
{
continue;
}
result.AddRange(JsonConvert.DeserializeObject<List<KeyValuePair<string, int>>>(await response.Content.ReadAsStringAsync()));
}
}
return this.Json(result);
}
// PUT: api/Votes/name
[HttpPut("{name}")]
public async Task<IActionResult> Put(string name)
{
Uri serviceName = VotingWeb.GetVotingDataServiceName(this.serviceContext);
Uri proxyAddress = this.GetProxyAddress(serviceName);
long partitionKey = this.GetPartitionKey(name);
string proxyUrl = $"{proxyAddress}/api/VoteData/{name}?PartitionKey={partitionKey}&PartitionKind=Int64Range";
StringContent putContent = new StringContent($"{{ 'name' : '{name}' }}", Encoding.UTF8, "application/json");
putContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
using (HttpResponseMessage response = await this.httpClient.PutAsync(proxyUrl, putContent))
{
return new ContentResult()
{
StatusCode = (int) response.StatusCode,
Content = await response.Content.ReadAsStringAsync()
};
}
}
// DELETE: api/Votes/name
[HttpDelete("{name}")]
public async Task<IActionResult> Delete(string name)
{
Uri serviceName = VotingWeb.GetVotingDataServiceName(this.serviceContext);
Uri proxyAddress = this.GetProxyAddress(serviceName);
long partitionKey = this.GetPartitionKey(name);
string proxyUrl = $"{proxyAddress}/api/VoteData/{name}?PartitionKey={partitionKey}&PartitionKind=Int64Range";
using (HttpResponseMessage response = await this.httpClient.DeleteAsync(proxyUrl))
{
if (response.StatusCode != System.Net.HttpStatusCode.OK)
{
return this.StatusCode((int) response.StatusCode);
}
}
return new OkResult();
}
/// <summary>
/// Constructs a reverse proxy URL for a given service.
/// Example: http://localhost:19081/VotingApplication/VotingData/
/// </summary>
/// <param name="serviceName"></param>
/// <returns></returns>
private Uri GetProxyAddress(Uri serviceName)
{
return new Uri($"http://localhost:19081{serviceName.AbsolutePath}");
}
/// <summary>
/// Creates a partition key from the given name.
/// Uses the zero-based numeric position in the alphabet of the first letter of the name (0-25).
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
private long GetPartitionKey(string name)
{
return Char.ToUpper(name.First()) - 'A';
}
}
Szczegółowe omówienie przykładowej aplikacji do głosowania
Aplikacja do głosowania składa się z dwóch usług:
- Usługa frontonu internetowego (VotingWeb): usługa frontonu internetowego platformy ASP.NET Core, która obsługuje stronę internetową i uwidacznia internetowe interfejsy API do komunikowania się z usługą zaplecza.
- Usługa zaplecza (VotingData): usługa internetowa platformy ASP.NET Core, która uwidacznia interfejs API do przechowywania wyników głosowania w niezawodnym słowniku utrwalonego na dysku.
Podczas głosowania w aplikacji występują następujące zdarzenia:
Plik JavaScript wysyła żądanie głosowania do internetowego interfejsu API w usłudze frontonu internetowego jako żądanie HTTP PUT.
Usługa internetowa frontonu używa serwera proxy w celu zlokalizowania i przesłania żądania HTTP PUT do usługi zaplecza.
Usługa zaplecza pobiera żądanie przychodzące i przechowuje zaktualizowany wynik w niezawodnym słowniku. Słownik jest replikowany do wielu węzłów w klastrze i utrwalany na dysku. Wszystkie dane aplikacji są przechowywane w klastrze, więc baza danych nie jest wymagana.
Debugowanie w programie Visual Studio
Podczas debugowania aplikacji w programie Visual Studio należy użyć lokalnego klastra programistycznego usługi Service Fabric. Możesz dostosować środowisko debugowania do swojego scenariusza.
W tej aplikacji przechowuj dane w usłudze zaplecza przy użyciu niezawodnego słownika. Program Visual Studio domyślnie usuwa aplikację po zatrzymaniu debugera. Usunięcie aplikacji spowoduje, że dane w usłudze zaplecza także zostaną usunięte. Aby zachować dane między sesjami debugowania, możesz zmienić Tryb debugowania aplikacji jako właściwość w projekcie Voting (Głosowanie) w programie Visual Studio.
Aby zobaczyć, co się dzieje w kodzie, wykonaj następujące kroki:
Otwórz plik VotingWeb\VotesController.cs i ustaw punkt przerwania w metodzie internetowego interfejsu
Put
API (wiersz 72).Otwórz plik VotingData\VoteDataController.cs i ustaw punkt przerwania w metodzie tego internetowego interfejsu
Put
API (wiersz 54).Wybierz F5, aby uruchomić aplikację w trybie debugowania.
Wróć do przeglądarki i wybierz opcję głosowania lub dodaj nową opcję głosowania. Pierwszy punkt przerwania został osiągnięty w kontrolerze interfejsu API frontonu internetowego.
Skrypt JavaScript w przeglądarce wysyła żądanie do internetowego kontrolera interfejsu API w usłudze frontonu:
- Najpierw skonstruuj adres URL odwrotnego serwera proxy dla usługi zaplecza. (1)
- Następnie wyślij żądanie HTTP PUT do zwrotnego serwera proxy. (2)
- Na koniec zwróć odpowiedź z usługi zaplecza do klienta. (3)
Wybierz F5, aby kontynuować.
Teraz znajdujesz się w punkcie przerwania w usłudze zaplecza:
- W pierwszym wierszu metody użyj polecenia
stateManager
, aby pobrać lub dodać niezawodny słownik o nazwiecounts
. (1) - Wszystkie interakcje, które mają wartości w niezawodnym słowniku, wymagają transakcji. Ta
using
instrukcja tworzy tę transakcję. (2) - W transakcji zaktualizuj wartość odpowiedniego klucza dla opcji głosowania i zatwierdź operację.
commit
Gdy metoda zwraca, dane są aktualizowane w słowniku. Następnie jest replikowany do innych węzłów w klastrze. Dane są teraz bezpiecznie przechowywane w klastrze, a usługa zaplecza może przejść w tryb failover do innych węzłów i nadal mieć dostępne dane. (3)
- W pierwszym wierszu metody użyj polecenia
Wybierz F5, aby kontynuować.
Aby zatrzymać sesję debugowania, wybierz pozycję Shift+F5.
Następny krok
Przejdź do następnego samouczka: