140 lines
4.6 KiB
Markdown
140 lines
4.6 KiB
Markdown
|
# Отчёт по лабораторной работе №3
|
|||
|
## REST API, Gateway и синхронный обмен между микросервисами
|
|||
|
|
|||
|
Выполнила: студентка гр. ИСЭбд-41 Халитова А.М.
|
|||
|
|
|||
|
## Создание микросервисов
|
|||
|
|
|||
|
В терминале помощью команд `dotnet new web -n worker-1` и `dotnet new web -n worker-2`создано два микросервиса:
|
|||
|
|
|||
|
[Код программы worker-1](worker-1/Program.cs)
|
|||
|
|
|||
|
[Код программы worker-2](worker-2/Program.cs)
|
|||
|
|
|||
|
|
|||
|
Далее были добавлены Swagger и OpenAi в проекты. Затем запустили приложения с помощью команды `dotnet run`.
|
|||
|
|
|||
|
Интерфейс микросервисов c CRUD-операциями - список записей, подробности конкретной записи, создание, удаление и изменение записи:
|
|||
|
worker-1:
|
|||
|

|
|||
|
worker-2:
|
|||
|

|
|||
|
|
|||
|
## Реализация синхронного обмена
|
|||
|
|
|||
|
Синхронный вызов данных с соседнего микросервиса для worker-2 при реализации получения, создания и обновления работ:
|
|||
|
```
|
|||
|
app.MapGet("/getJobs/{clientId}", (string clientId) =>
|
|||
|
{
|
|||
|
var secondWorkerResponse = httpClient.GetStringAsync("http://worker-1:8080/getClient/" + clientId).Result;
|
|||
|
Client client = JsonConvert.DeserializeObject<Client>(secondWorkerResponse);
|
|||
|
if (secondWorkerResponse == null)
|
|||
|
return Results.NotFound(new { message = "Клиент не найден" });
|
|||
|
List<Job> clientJobs = jobs.Where(x => x.ClientId == clientId).ToList();
|
|||
|
return Results.Json(clientJobs);
|
|||
|
})
|
|||
|
.WithName("GetJobs");
|
|||
|
|
|||
|
app.MapGet("getJob/{id}", (string id) =>
|
|||
|
{
|
|||
|
Job? job = jobs.FirstOrDefault(x => x.Id == id);
|
|||
|
if (job == null)
|
|||
|
return Results.NotFound(new { message = "Задача не найдена" });
|
|||
|
return Results.Json(job);
|
|||
|
})
|
|||
|
.WithName("GetJob");
|
|||
|
|
|||
|
app.MapPost("createJob", (JobViewModel jobVM) =>
|
|||
|
{
|
|||
|
var secondWorkerResponse = httpClient.GetStringAsync("http://worker-1:8080/getClient/" + jobVM.ClientId).Result;
|
|||
|
Client client = JsonConvert.DeserializeObject<Client>(secondWorkerResponse);
|
|||
|
if (secondWorkerResponse == null)
|
|||
|
return Results.NotFound(new { message = "Клиент не найден" });
|
|||
|
Job job = new Job
|
|||
|
{
|
|||
|
Id = Guid.NewGuid().ToString(),
|
|||
|
DeadLine = jobVM.DeadLine,
|
|||
|
Description = jobVM.Description,
|
|||
|
Client = client,
|
|||
|
ClientId = jobVM.ClientId,
|
|||
|
Title = jobVM.Title,
|
|||
|
};
|
|||
|
jobs.Add(job);
|
|||
|
return Results.Json(job);
|
|||
|
})
|
|||
|
.WithName("CreateJob");
|
|||
|
|
|||
|
app.MapPut("updateJob/{id}", (string id, JobViewModel data) =>
|
|||
|
{
|
|||
|
Job? job = jobs.FirstOrDefault(x => x.Id == id);
|
|||
|
if (job == null)
|
|||
|
return Results.NotFound(new { message = "Задача не найдена" });
|
|||
|
var secondWorkerResponse = httpClient.GetStringAsync("http://worker-1:8080/getClient/" + data.ClientId).Result;
|
|||
|
Client client = JsonConvert.DeserializeObject<Client>(secondWorkerResponse);
|
|||
|
if (secondWorkerResponse == null)
|
|||
|
return Results.NotFound(new { message = "Клиент не найден" });
|
|||
|
job.Title = data.Title;
|
|||
|
job.DeadLine = data.DeadLine;
|
|||
|
job.ClientId = data.ClientId;
|
|||
|
job.Client = client;
|
|||
|
job.Description = data.Description;
|
|||
|
return Results.Json(job);
|
|||
|
})
|
|||
|
.WithName("UpdateJob");
|
|||
|
```
|
|||
|
|
|||
|
## Реализация gateway при помощи nginx
|
|||
|
|
|||
|
Файл с настройкой nginx:
|
|||
|
```
|
|||
|
server {
|
|||
|
listen 8080;
|
|||
|
listen [::]:8080;
|
|||
|
server_name localhost;
|
|||
|
|
|||
|
location / {
|
|||
|
root /usr/share/nginx/html;
|
|||
|
index index.html index.htm;
|
|||
|
}
|
|||
|
|
|||
|
location /worker-1/ {
|
|||
|
proxy_pass http://worker-1:8080/;
|
|||
|
proxy_set_header Host $host;
|
|||
|
proxy_set_header X-Real-IP $remote_addr;
|
|||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|||
|
proxy_set_header X-Forwarded-Prefix /worker-1;
|
|||
|
}
|
|||
|
|
|||
|
location /worker-2/ {
|
|||
|
proxy_pass http://worker-2:8080/;
|
|||
|
proxy_set_header Host $host;
|
|||
|
proxy_set_header X-Real-IP $remote_addr;
|
|||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|||
|
proxy_set_header X-Forwarded-Prefix /worker-2;
|
|||
|
}
|
|||
|
}
|
|||
|
```
|
|||
|
Далее запустили команду `docker compose up --build`.
|
|||
|
|
|||
|
В Docker Desktop проверили, что приложение успешно запущено:
|
|||
|

|
|||
|
|
|||
|
Страница `index.html` на шлюзе geteway-1:
|
|||
|

|
|||
|
|
|||
|
worker-1:
|
|||
|

|
|||
|
|
|||
|
worker-2:
|
|||
|

|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|