8 Commits

Author SHA1 Message Date
6f6cbac2a3 lab8_done 2023-12-18 02:37:30 +04:00
9855bb264a lab8_done 2023-12-18 02:36:54 +04:00
d15b374999 lab7_done 2023-12-18 01:35:05 +04:00
e6cb8bd420 lab6_done 2023-12-17 00:55:54 +04:00
1627b65411 lab5_done 2023-12-16 23:31:32 +04:00
ab801f7c01 fix_lab4 2023-12-16 02:07:00 +04:00
918816654a lab4_done 2023-12-16 01:46:18 +04:00
083170f861 lab3_done 2023-12-15 22:14:31 +04:00
77 changed files with 2031 additions and 0 deletions

477
tasks/plaksina-av/lab_3/.gitignore vendored Normal file
View File

@@ -0,0 +1,477 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET
project.lock.json
project.fragment.lock.json
artifacts/
# Tye
.tye/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.tlog
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio 6 auto-generated project file (contains which files were open etc.)
*.vbp
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
*.dsw
*.dsp
# Visual Studio 6 technical files
*.ncb
*.aps
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# Visual Studio History (VSHistory) files
.vshistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
# VS Code files for those working on multiple tools
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace
# Local History for Visual Studio Code
.history/
# Windows Installer files from build outputs
*.cab
*.msi
*.msix
*.msm
*.msp
# JetBrains Rider
*.sln.iml
##
## Visual studio for Mac
##
# globs
Makefile.in
*.userprefs
*.usertasks
config.make
config.status
aclocal.m4
install-sh
autom4te.cache/
*.tar.gz
tarballs/
test-results/
# Mac bundle stuff
*.dmg
*.app
# content below from: https://github.com/github/gitignore/blob/master/Global/macOS.gitignore
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# content below from: https://github.com/github/gitignore/blob/master/Global/Windows.gitignore
# Windows thumbnail cache files
Thumbs.db
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk

View File

@@ -0,0 +1,91 @@
# Отчет по лабораторной работе №3
Выполнила студентка гр. ИСЭбд-41 Плаксина А.В.
## REST API, Gateway и синхронный обмен между микросервисами
## Создание микросервисов
1. С помощью команды `dotnet new web -n worker-1` в терминале был создан первый микросервис
2. В папке созданного проекта добавлено решение командой `dotnet new sln`
3. Затем связали решение и проект командой `dotnet sln worker-2.sln add worker-1.csproj`
![](photo/ph1.jpg)
4. Повторили те же действия для второго микросервиса
5. Добавили библиотеку Swagger и OpenAi в обе папки проектов и запустил с помощью команды `dotnet run`
Моя предметная область - университет. Реализовала две сущности - кафедра и специальность.
Скриншоты протестированных микросервисов:
Worker-1:
![](photo/ph4.jpg)
Worker-2:
![](photo/ph5.jpg)
## Реализация синхронного обмена
Был реализован код, который вызывает сихронно данные из соседнего микросервиса.
```cs
//worker-2
app.MapGet("/Requests/", async () =>
{
var httpClient = new HttpClient();
var secondWorkerResponse = await httpClient.GetStringAsync("http://worker-1:8085/");
return secondWorkerResponse;
})
.WithName("GetRequests")
.WithOpenApi();
```
## Реализация gateway при помощи nginx
Добавил nginx.conf:
```conf
server {
listen 8085;
listen [::]:8085;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /worker-1/ {
proxy_pass http://worker-1:8085/;
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:8085/;
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`:
Запущенные контейнеры в Docker Desktop:
![](photo/ph2.jpg)
Отображение index.html на gateway-1 после нажатия на ссылку `8085:8085` :
![](photo/ph3.jpg)
worker-1:
![](photo/ph6.jpg)
worker-2:
![](photo/ph7.jpg)

View File

@@ -0,0 +1,16 @@
version: "3.1"
services:
worker-1:
build: ./worker-1
worker-2:
build: ./worker-2
depends_on:
- worker-1
gateway:
image: nginx:latest
ports:
- 8085:8085
volumes:
- ./static:/usr/share/nginx/html:ro
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro

View File

@@ -0,0 +1,26 @@
server {
listen 8085;
listen [::]:8085;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /worker-1/ {
proxy_pass http://worker-1:8085/;
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:8085/;
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;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

View File

@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>РВИП, Лабораторная работа 3</title>
</head>
<body>
<p>Плаксина Александра Вадимовна, гр. ИСЭбд-41</p>
<p><a href="/worker-1/">Отправить запрос к worker-1</a></p>
<p><a href="/worker-2/">Отправить запрос к worker-2</a></p>
</body>
</html>

View File

@@ -0,0 +1,3 @@
{
"help":"https://go.microsoft.com/fwlink/?linkid=866610"
}

View File

@@ -0,0 +1,11 @@
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build-env
WORKDIR /app
COPY . ./
RUN dotnet restore
RUN dotnet publish -c Release -o out
FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "worker-1.dll"]

View File

@@ -0,0 +1,119 @@
List<Request> requests = new()
{
new Request() { Uuid= Guid.Parse("81a130d2-502f-4cf1-a376-63edeb000e9f"), NameDepartament = "Информационные системы", Manager = "Романов Антон Алексеевич", Faculty = "ФИСТ"},
new Request() { Uuid= Guid.Parse("65a9aed2-218a-468e-92b9-99f6a6a34543"), NameDepartament = "Прикладная математика и информатика", Manager = "Кувайскова Юлия Евгеньевна", Faculty = "ФИСТ"},
};
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.MapGet("/", () =>
{
return requests.Select(r => new RequestEntityDto()
{
Uuid = r.Uuid,
NameDepartament = r.NameDepartament,
Manager = r.Manager,
Faculty = r.Faculty,
});
})
.WithName("GetRequests")
.WithOpenApi();
app.MapGet("/{uuid}", (Guid uuid) =>
{
var request = requests.FirstOrDefault(r => r.Uuid == uuid);
if (request == null)
return Results.NotFound();
return Results.Json(new RequestEntityDto()
{
Uuid = request.Uuid,
NameDepartament = request.NameDepartament,
Manager = request.Manager,
Faculty = request.Faculty,
});
})
.WithName("GetRequestByGUID")
.WithOpenApi();
app.MapPost("/{nameDepartament}/{manager}/{faculty}", (string nameDepartament, string manager, string faculty) =>
{
Guid NewGuid = Guid.NewGuid();
requests.Add(new Request() { Uuid = NewGuid, NameDepartament = (string)nameDepartament, Manager = (string)manager, Faculty = (string)faculty});
var request = requests.FirstOrDefault(r => r.Uuid == NewGuid);
if (request == null)
return Results.NotFound();
return Results.Json(new RequestEntityDto()
{
Uuid = request.Uuid,
NameDepartament = request.NameDepartament,
Manager = request.Manager,
Faculty = request.Faculty,
});
})
.WithName("PostRequest")
.WithOpenApi();
app.MapPatch("/{uuid}/{title}/{sourceOfFunds}/{sum}/{isCompleted}", (Guid uuid, string ?nameDepartament, string ?manager, string ?faculty) =>
{
var request = requests.FirstOrDefault(r => r.Uuid == uuid);
if (request == null)
return Results.NotFound();
if (nameDepartament != null) request.NameDepartament = nameDepartament;
if (manager != null) request.Manager = manager;
if (faculty != null) request.Faculty = faculty;
return Results.Json(new RequestEntityDto()
{
Uuid = request.Uuid,
NameDepartament = request.NameDepartament,
Manager = request.Manager,
Faculty = request.Faculty,
});
})
.WithName("UpdateRequest")
.WithOpenApi();
app.MapDelete("/{uuid}", (Guid uuid) =>
{
var request = requests.FirstOrDefault(r => r.Uuid == uuid);
if (request == null)
return Results.NotFound();
requests.Remove(request);
return Results.Json(new RequestEntityDto()
{
Uuid = request.Uuid,
NameDepartament = request.NameDepartament,
Manager = request.Manager,
Faculty = request.Faculty,
});
})
.WithName("DeleteRequestByGUID")
.WithOpenApi();
app.Run();
public class Request
{
public Guid Uuid { get; set; }
public string NameDepartament { get; set; } = string.Empty;
public string Manager { get; set; } = string.Empty;
public string Faculty { get; set; } = string.Empty;
}
public class RequestEntityDto : Request { }

View File

@@ -0,0 +1,38 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:27639",
"sslPort": 44315
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:5111",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7158;http://localhost:5111",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

View File

@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>worker_1</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "worker-1", "worker-1.csproj", "{1349D735-BA13-4E34-A67C-D6C50025DFA2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "worker-2", "..\worker-2\worker-2.csproj", "{55A9B14A-B8D5-42C0-A17E-6615A6A224E9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1349D735-BA13-4E34-A67C-D6C50025DFA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1349D735-BA13-4E34-A67C-D6C50025DFA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1349D735-BA13-4E34-A67C-D6C50025DFA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1349D735-BA13-4E34-A67C-D6C50025DFA2}.Release|Any CPU.Build.0 = Release|Any CPU
{55A9B14A-B8D5-42C0-A17E-6615A6A224E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{55A9B14A-B8D5-42C0-A17E-6615A6A224E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{55A9B14A-B8D5-42C0-A17E-6615A6A224E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{55A9B14A-B8D5-42C0-A17E-6615A6A224E9}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D167A75B-99E2-45CB-8668-84D336B4370C}
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,11 @@
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build-env
WORKDIR /app
COPY . ./
RUN dotnet restore
RUN dotnet publish -c Release -o out
FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "worker-2.dll"]

View File

@@ -0,0 +1,144 @@
List<Agreement> agrs = new()
{
new Agreement() { Uuid= Guid.NewGuid(), Specialism = "Прикладная информатика", CountEGE = 3, DVI = false, IdRequest = Guid.Parse("81a130d2-502f-4cf1-a376-63edeb000e9f") }
};
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.MapGet("/", () =>
{
return agrs.Select(r => new AgreementEntityDto()
{
Uuid = r.Uuid,
Specialism = r.Specialism,
CountEGE = r.CountEGE,
DVI = r.DVI,
IdRequest = r.IdRequest,
});
})
.WithName("GetAgreements")
.WithOpenApi();
app.MapGet("/{uuid}", (Guid uuid) =>
{
var agr = agrs.FirstOrDefault(r => r.Uuid == uuid);
if (agr == null)
return Results.NotFound();
return Results.Json(new AgreementEntityDto()
{
Uuid = agr.Uuid,
Specialism = agr.Specialism,
CountEGE = agr.CountEGE,
DVI = agr.DVI,
IdRequest = agr.IdRequest,
});
})
.WithName("GetAgreementByGUID")
.WithOpenApi();
app.MapPost("/{specialism}/{countEGE}/{DVI}/{idRequest}", (string? specialism, decimal countEGE, bool DVI, Guid idRequest) =>
{
Guid NewGuid = Guid.NewGuid();
agrs.Add(new Agreement() { Uuid = NewGuid, Specialism = (string)specialism, CountEGE = (decimal)countEGE, DVI = (bool)DVI, IdRequest = (Guid)idRequest });
var agr = agrs.FirstOrDefault(r => r.Uuid == NewGuid);
if (agr == null)
return Results.NotFound();
return Results.Json(new AgreementEntityDto()
{
Uuid = agr.Uuid,
Specialism = agr.Specialism,
CountEGE = agr.CountEGE,
DVI = agr.DVI,
IdRequest = agr.IdRequest,
});
})
.WithName("PostAgreement")
.WithOpenApi();
app.MapPatch("/{uuid}/{specialism}/{countEGE}/{DVI}/{idRequest}", (Guid uuid, string? specialism, decimal countEGE, bool DVI, Guid idRequest) =>
{
var agr = agrs.FirstOrDefault(r => r.Uuid == uuid);
if (agr == null)
return Results.NotFound();
if (specialism != ",") agr.Specialism = specialism;
if (countEGE != agr.CountEGE && countEGE != 0) agr.CountEGE = countEGE;
if (DVI !=agr.DVI) agr.DVI = DVI;
if (idRequest != agr.IdRequest) agr.IdRequest = idRequest;
return Results.Json(new AgreementEntityDto()
{
Uuid = agr.Uuid,
Specialism = agr.Specialism,
CountEGE = agr.CountEGE,
DVI = agr.DVI,
IdRequest = agr.IdRequest,
});
})
.WithName("UpdateAgreement")
.WithOpenApi();
app.MapDelete("/{uuid}", (Guid uuid) =>
{
var agr = agrs.FirstOrDefault(r => r.Uuid == uuid);
if (agr == null)
return Results.NotFound();
agrs.Remove(agr);
return Results.Json(new AgreementEntityDto()
{
Uuid = agr.Uuid,
Specialism = agr.Specialism,
CountEGE = agr.CountEGE,
DVI = agr.DVI,
IdRequest = agr.IdRequest,
});
})
.WithName("DeleteAgreement")
.WithOpenApi();
app.MapGet("/Requests/", async () =>
{
var httpClient = new HttpClient();
var secondWorkerResponse = await httpClient.GetStringAsync("http://worker-1:8085/");
return secondWorkerResponse;
})
.WithName("GetRequests")
.WithOpenApi();
app.Run();
public class Agreement
{
public Guid Uuid { get; set; }
public string Specialism { get; set; } = string.Empty;
public decimal CountEGE { get; set; } = 0;
public Guid IdRequest { get; set; }
public bool DVI { get; set; }
}
public class AgreementEntityDto : Agreement { }
public class Request
{
public Guid Uuid { get; set; }
public string NameDepartament { get; set; } = string.Empty;
public string Manager { get; set; } = string.Empty;
public Guid IdRequest { get; set; }
public string Faculty { get; set; } = string.Empty;
}
public class RequestEntityDto : Request { }

View File

@@ -0,0 +1,38 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:6437",
"sslPort": 44360
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:5041",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7064;http://localhost:5041",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

View File

@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>worker_2</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "worker-2", "worker-2.csproj", "{1663B908-C10A-4E6D-A301-F964216E8D0B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1663B908-C10A-4E6D-A301-F964216E8D0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1663B908-C10A-4E6D-A301-F964216E8D0B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1663B908-C10A-4E6D-A301-F964216E8D0B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1663B908-C10A-4E6D-A301-F964216E8D0B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,71 @@
# Отчет по лабораторной работе №4
Выполнила студентка гр. ИСЭбд-41 Плаксина А.В.
## Прохождение tutorial
Установила RabbitMQ server, erlang и зашла в брокер под гостем по `http://localhost:15672/#/`
Открытый RabbitMQ:
![](photo/ph13.jpg)
Прохождение туториала 1:
Сначала был запущен receive.py, который становится в ожидании сообщения. Затем запустили с отдельном терминале send.py, который отправил сообщение
![](photo/ph8.jpg)
![](photo/ph9.jpg)
Прохождение туториала 2:
Открыли три терминала: в первых двух запустили поочередно потребителей worker.py. В третьем терминале запустили new_task.py и отправили пять сообщений.
![](photo/ph10.jpg)
В результате эти сообщения были распределены между двумя воркерами.
![](photo/ph11.jpg)
![](photo/ph12.jpg)
Прохождение туториала 3:
Сначала в первом терминале запустили receive_logs.py, затем во втором запустили emit_log.py, тем самы отправив сообщение в первый
![](photo/ph14.jpg)
![](photo/ph15.jpg)
![](pic/tut3.png)
## Разработка демонстрационных приложений
Предметная область:университет, его мониторинг
Собрали и одновременно запустили приложения по одному экземпляру:
1. Publisher
![](photo/ph16.jpg)
2. Consumer 1.
![](photo/ph17.jpg)
3. Consumer 2.
![](photo/ph18.jpg)
## Результаты выполнения лабораторной работы
Результат отработки Consumer_1:
![](photo/ph19.jpg)
![](photo/ph20.jpg)
Результат отработки Consumer_2:
![](photo/ph21.jpg)
![](photo/ph22.jpg)
Вывод: Consumer_2 нагружает меньше памяти, чем Consumer_1 и принимает сообщения гораздо быстрее, тем самым не позволяя очереди накапливать огромное количество сообщений.

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

3
tasks/plaksina-av/lab_4/pythontasks/.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

View File

@@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.12 (python4Lab)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12 (python4Lab)" project-jdk-type="Python SDK" />
</project>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/python4Lab.iml" filepath="$PROJECT_DIR$/.idea/python4Lab.iml" />
</modules>
</component>
</project>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/venv" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -0,0 +1,160 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/

View File

@@ -0,0 +1,20 @@
import pika
import time
def process_message(ch, method, properties, body):
print(f"Получено сообщение: {body}")
time.sleep(3)
print("Сообщение успешно обработано")
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
result = channel.queue_declare(queue='', exclusive=True)
queue_name = result.method.queue
channel.queue_bind(exchange='Agreements', queue=queue_name)
channel.basic_consume(queue=queue_name, on_message_callback=process_message, auto_ack=True)
print('Ожидание сообщений...')
channel.start_consuming()

View File

@@ -0,0 +1,19 @@
import pika
def process_message(ch, method, properties, body):
print(f"Получено сообщение: {body}")
print("Сообщение успешно обработано")
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
result = channel.queue_declare(queue='', exclusive=True)
queue_name = result.method.queue
channel.queue_bind(exchange='Agreements', queue=queue_name)
channel.basic_consume(queue=queue_name, on_message_callback=process_message, auto_ack=True)
print('Ожидание сообщений...')
channel.start_consuming()

View File

@@ -0,0 +1,19 @@
import pika
import time
import random
collection = ["Indicator Successfully Calculated", "DVI Is Not Provided For This Specialty", "The Student Went To The Academy"]
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
channel.exchange_declare(exchange='Agreements', exchange_type='fanout')
while True:
message = f"Message: {random.choice(collection)}"
channel.basic_publish(exchange='Agreements', routing_key='', body=message)
time.sleep(1)
connection.close()

View File

@@ -0,0 +1,25 @@
import pika, sys, os
def main():
connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = connection.channel()
channel.queue_declare(queue='ugolek')
def callback(ch, method, properties, body):
print(f" [x] Получено сообщение: {body}")
channel.basic_consume(queue='ugolek', on_message_callback=callback, auto_ack=True)
print(' [*] Ожидание сообщений. Для завершения CTRL+C')
channel.start_consuming()
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
print('Произошла ошибка')
try:
sys.exit(0)
except SystemExit:
os._exit(0)

View File

@@ -0,0 +1,11 @@
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
channel.queue_declare(queue='ugolek')
channel.basic_publish(exchange='',routing_key='ugolek',body='Hello, My Name Alex!')
print(" [x] Отправлено 'Hello, My Name Alex!")
connection.close()

View File

@@ -0,0 +1,13 @@
import pika
import sys
connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = connection.channel()
channel.queue_declare(queue='milka', durable=True)
message = ' '.join(sys.argv[1:]) or "Hello My Name is Alex"
channel.basic_publish(exchange='', routing_key='milka', body=message, properties=pika.BasicProperties(
delivery_mode=pika.spec.PERSISTENT_DELIVERY_MODE))
print(f" [x] Отправлено {message}")
connection.close()

View File

@@ -0,0 +1,19 @@
import pika
import time
connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = connection.channel()
channel.queue_declare(queue='milka', durable=True)
print(' [*] Ожидание сообщений. Для завершения CTRL+C')
def callback(ch, method, properties, body):
print(f" [x] Получено сообщение: {body.decode()}")
time.sleep(body.count(b'.'))
print(" [x] Выполнено")
ch.basic_ack(delivery_tag=method.delivery_tag)
channel.basic_qos(prefetch_count=1)
channel.basic_consume(queue='milka', on_message_callback=callback)
channel.start_consuming()

View File

@@ -0,0 +1,12 @@
import pika
import sys
connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = connection.channel()
channel.exchange_declare(exchange='tishka', exchange_type='fanout')
message = ' '.join(sys.argv[1:]) or "Info: Hello My Name is Alex"
channel.basic_publish(exchange='tishka', routing_key='', body=message)
print(f" [x] Отправлено сообщение: {message}")
connection.close()

View File

@@ -0,0 +1,21 @@
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = connection.channel()
channel.exchange_declare(exchange='tishka', exchange_type='fanout')
result = channel.queue_declare(queue='', exclusive=True)
queue_name = result.method.queue
channel.queue_bind(exchange='tishka', queue=queue_name)
print(' [*] Ожидание сообщений. Для завершения CTRL+C')
def callback(ch, method, properties, body):
print(f" [x] {body}")
channel.basic_consume(
queue=queue_name, on_message_callback=callback, auto_ack=True)
channel.start_consuming()

View File

@@ -0,0 +1,100 @@
# Отчет по лабораторной работе №5
Выполнила студентка гр. ИСЭбд-41 Плаксина А.В.
# Описание работы приложения
Приложение реализовнао на языке питон, использована среда PyCharm для разработки.
Было развернуто два приложения:
1. Веб приложение для умножения матриц
2. Консольное приложение для бенчмаркинга
Последовательно запускаем две программы: сначала simple_app.py, затем benchmark.py.
Веб - приложение позволяет указать размеры матрицы и используемый алгоритм, и на основании этого получить результат перемножения матриц в интерактивном режиме
Развернули два приложения
1. Приложение 1 - веб приложение для умножения матриц
2. Приложение 2 - консольное приложение для сравнения эффективности работы алгоритмов.
Первое приложение дает нам возможность умножить матрицы, получить результат в интерактивном режиме
с указанием используемого алгоритма и с указанием размера матрицы.
При запуске веб приложения с выбором последовательного умножения:
![](photo/ph23.jpg)
Результат последовательного умножения:
![](photo/ph24.jpg)
Код реализующий последовательное умножение матриц:
```cs
def multiply_matrices(matrix_a, matrix_b):
if len(matrix_a[0]) != len(matrix_b):
raise ValueError("матрицы имеют разную длину")
result = [[0 for _ in range(len(matrix_b[0]))] for _ in range(len(matrix_a))]
for i in range(len(matrix_a)):
for j in range(len(matrix_b[0])):
for k in range(len(matrix_b)):
result[i][j] += matrix_a[i][k] * matrix_b[k][j]
return result
```
При запуске веб приложения с выбором параллельного умножения:
![](photo/ph25.jpg)
Результат параллельного умножения:
![](photo/ph26.jpg)
Код реализующий параллельное умножение матриц:
```cs
def multiply_matrices_parallel(matrix_a, matrix_b, threads):
if len(matrix_a[0]) != len(matrix_b):
raise ValueError("матрицы имеют разную длину")
result = [[0 for _ in range(len(matrix_b[0]))] for _ in range(len(matrix_a))]
with multiprocessing.Pool(processes=threads) as pool:
args_list = [(matrix_a, matrix_b, i) for i in range(len(matrix_a))]
rows_results = pool.map(multiply_row, args_list)
for row_result, row_index in rows_results:
result[row_index] = row_result
return result
```
# Бенчмаркинг
Для сравнения времени работы двух алгоритмов умножения, проведем несколько бенчмарков
Для матриц размерностью 100x100, 300x300, 500x500, для параллельного алгоритма дополнительно для каждого введенного количества потоков (4, 16, 32)
Результаты бенчмаркинга для последовательного способа матриц различной размерности:
![](photo/ph27.jpg)
Результаты бенчмаркинга для параллельного способа матриц различной размерности с количеством потоков равном 4:
![](photo/ph28.jpg)
Результаты бенчмаркинга для параллельного способа матриц различной размерности с количеством потоков равном 16:
![](photo/ph29.jpg)
Результаты бенчмаркинга для параллельного способа матриц различной размерности с количеством потоков равном 32:
![](photo/ph30.jpg)
# Вывод
С использованием параллельного алгоритма скорость обработки существенно увеличивается, особенно при большой размерности матрицы.
В данном примере оптимальная скорость достигается при количестве потоков равном 16.

View File

@@ -0,0 +1,82 @@
import multiprocessing
import numpy as np
import time
def multiply_matrices(matrix_a, matrix_b):
if len(matrix_a[0]) != len(matrix_b):
raise ValueError("матрицы имеют разную длину")
result = [[0 for _ in range(len(matrix_b[0]))] for _ in range(len(matrix_a))]
for i in range(len(matrix_a)):
for j in range(len(matrix_b[0])):
for k in range(len(matrix_b)):
result[i][j] += matrix_a[i][k] * matrix_b[k][j]
return result
def multiply_row(args):
matrix_a, matrix_b, i = args
row_result = [0 for _ in range(len(matrix_b[0]))]
for j in range(len(matrix_b[0])):
for k in range(len(matrix_b)):
row_result[j] += matrix_a[i][k] * matrix_b[k][j]
return row_result, i
def multiply_matrices_parallel(matrix_a, matrix_b, threads):
if len(matrix_a[0]) != len(matrix_b):
raise ValueError("матрицы имеют разную длину")
result = [[0 for _ in range(len(matrix_b[0]))] for _ in range(len(matrix_a))]
with multiprocessing.Pool(processes=threads) as pool:
args_list = [(matrix_a, matrix_b, i) for i in range(len(matrix_a))]
rows_results = pool.map(multiply_row, args_list)
for row_result, row_index in rows_results:
result[row_index] = row_result
return result
def benchmark_sequential(size):
matrix_a = np.random.rand(size, size)
matrix_b = np.random.rand(size, size)
start_time = time.time()
multiply_matrices(matrix_a, matrix_b)
end_time = time.time()
return end_time - start_time
def benchmark_parallel(size, num_threads):
matrix_a = np.random.rand(size, size)
matrix_b = np.random.rand(size, size)
start_time = time.time()
multiply_matrices_parallel(matrix_a, matrix_b, num_threads)
end_time = time.time()
return end_time - start_time
if __name__ == "__main__":
sizes = [100, 300, 500]
threads = [4, 16, 32]
for size in sizes:
sequential_time = benchmark_sequential(size)
print(f"Время для последовательного способа: {sequential_time} с")
print(f"Размер матрицы: {size}x{size}")
for thread in threads:
for size in sizes:
parallel_time = benchmark_parallel(size, thread)
print(f"Размер матрицы: {size}x{size}")
print(f"Время для параллельного спобсоба: {parallel_time} с")
print(f"Потоков: {thread}")

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

View File

@@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Умножение матриц</title>
</head>
<body>
<h1>Умножение матриц</h1>
<form action="/multiply" method="post">
<label for="matrix_a">Размер матриц:</label>
<input type="text" name="matrix_a" required><br>
<label for="operation_type">Способ умножения:</label>
<select name="operation_type">
<option value="sequential">Последовательно</option>
<option value="parallel">Параллельно</option>
</select><br>
<button type="submit">Умножение матриц</button>
</form>
</body>
</html>

View File

@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Результат</title>
</head>
<body>
<h1>Результат</h1>
<p>Матрица A:</p>
<pre>{{ matrix_a }}</pre>
<p>Матрица B:</p>
<pre>{{ matrix_b }}</pre>
<p>Результат:</p>
<pre>{{ result }}</pre>
<a href="/">Назад</a>
</body>
</html>

View File

@@ -0,0 +1,73 @@
import multiprocessing
from flask import Flask, render_template, request
import numpy as np
import concurrent.futures
app = Flask(__name__)
def multiply_matrices(matrix_a, matrix_b):
if len(matrix_a[0]) != len(matrix_b):
raise ValueError("матрицы имеют разную длину")
result = [[0 for _ in range(len(matrix_b[0]))] for _ in range(len(matrix_a))]
for i in range(len(matrix_a)):
for j in range(len(matrix_b[0])):
for k in range(len(matrix_b)):
result[i][j] += matrix_a[i][k] * matrix_b[k][j]
return result
def multiply_row(args):
matrix_a, matrix_b, i = args
row_result = [0 for _ in range(len(matrix_b[0]))]
for j in range(len(matrix_b[0])):
for k in range(len(matrix_b)):
row_result[j] += matrix_a[i][k] * matrix_b[k][j]
return row_result, i
def multiply_matrices_parallel(matrix_a, matrix_b, threads):
if len(matrix_a[0]) != len(matrix_b):
raise ValueError("матрицы имеют разную длину")
result = [[0 for _ in range(len(matrix_b[0]))] for _ in range(len(matrix_a))]
with multiprocessing.Pool(processes=threads) as pool:
args_list = [(matrix_a, matrix_b, i) for i in range(len(matrix_a))]
rows_results = pool.map(multiply_row, args_list)
for row_result, row_index in rows_results:
result[row_index] = row_result
return result
@app.route('/')
def index():
return render_template('index.html')
@app.route('/multiply', methods=['POST'])
def multiply():
n = int(request.form.get('matrix_a'))
matrix_a = np.random.randint(10, size=(n, n))
matrix_b = np.random.randint(10, size=(n, n))
operation_type = request.form.get('operation_type')
if operation_type == 'sequential':
result = multiply_matrices(matrix_a, matrix_b)
elif operation_type == 'parallel':
result = multiply_matrices_parallel(matrix_a, matrix_b, 16)
else:
return "Invalid operation type"
return render_template('result.html', matrix_a=matrix_a, matrix_b=matrix_b, result=result)
if __name__ == '__main__':
app.run(debug=True)

View File

@@ -0,0 +1,79 @@
# Отчет по лабораторной работе №6
Выполнила студентка гр. ИСЭбд-41 Плаксина А.В.
# Описание работы приложения
Приложение реализовнао на языке питон, использована среда PyCharm для разработки.
Это консольное приложение, которое вычисляет детерминант матриц. Задается размерность матрицы, элементы генерируются рандомно (указываетя только диапазон их значений), количество
Код реализующий заполнение данных:
```cs
if __name__ == "__main__":
matrix_size = 10 # размер матрицы
lower_limit = 5 # числа в матрице от
upper_limit = 15 # и до
processes = [2, 4, 8, 16, 32]
#
# последовательное вычисление
sequential_determinant_calculation(matrix_size, lower_limit, upper_limit)
# параллельное вычисление
for i in processes:
print("Потоков " + str(i))
parallel_determinant_calculation(matrix_size, lower_limit, upper_limit, i)
```
Код реализующий последовательное вычисление детерминанта матриц:
```cs
def sequential_determinant_calculation(matrix_size, lower_limit, upper_limit):
random_matrix = generate_random_matrix(matrix_size, lower_limit, upper_limit)
start_time = time.time()
result = determinant(random_matrix)
end_time = time.time()
print(f"Последовательный детерминант: {result}")
print(f"Последовательное время: {end_time - start_time} секунд")
```
Код реализующий параллельное вычисление детерминанта матриц:
```cs
def parallel_determinant_calculation(matrix_size, lower_limit, upper_limit, num_processes):
random_matrix = generate_random_matrix(matrix_size, lower_limit, upper_limit)
matrices_to_process = [submatrix(random_matrix, 0, col) for col in range(matrix_size)]
start_time = time.time()
with Pool(processes=num_processes) as pool:
determinants = pool.map(determinant, matrices_to_process)
result = sum(((-1) ** col) * random_matrix[0][col] * det for col, det in enumerate(determinants))
end_time = time.time()
print(f"Параллельный детерминант: {result}")
print(f"Параллельное время: {end_time - start_time} секунд")
```
# Бенчмаркинг
Для матриц болших размеров детерминант вычисляется очень долгое время, поэтому для примера я взяла размерность матрица 10х10
Результаты бенчмаркинга для последовательного способа вычисления детерминанта матриц:
![](photo/ph32.jpg)
Результаты бенчмаркинга для параллельного способа вычисления детерминанта матриц с различным количеством потока:
![](photo/ph31.jpg)
# Вывод
Скорость обработки у параллельного способа значительно выше, чем у последовательного
При увеличении количества потоков время обработки сначала снижается, затем, по примеру, начиная с 16 потока, время опять увеличивается, так как потоков становится слишком много.

View File

@@ -0,0 +1,71 @@
import random
from multiprocessing import Pool
import time
def submatrix(matrix, row, col):
return [[matrix[i][j] for j in range(len(matrix[i])) if j != col] for i in range(len(matrix)) if i != row]
def determinant(matrix):
size = len(matrix)
# Простой случай: детерминант матрицы 1x1
if size == 1:
return matrix[0][0]
# Простой случай: детерминант матрицы 2x2
if size == 2:
return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]
det = 0
for col in range(size):
det += ((-1) ** col) * matrix[0][col] * determinant(submatrix(matrix, 0, col))
return det
def generate_random_matrix(size, lower_limit, upper_limit):
return [[random.uniform(lower_limit, upper_limit) for _ in range(size)] for _ in range(size)]
def sequential_determinant_calculation(matrix_size, lower_limit, upper_limit):
random_matrix = generate_random_matrix(matrix_size, lower_limit, upper_limit)
start_time = time.time()
result = determinant(random_matrix)
end_time = time.time()
print(f"Последовательный детерминант: {result}")
print(f"Последовательное время: {end_time - start_time} секунд")
def parallel_determinant_calculation(matrix_size, lower_limit, upper_limit, num_processes):
random_matrix = generate_random_matrix(matrix_size, lower_limit, upper_limit)
matrices_to_process = [submatrix(random_matrix, 0, col) for col in range(matrix_size)]
start_time = time.time()
with Pool(processes=num_processes) as pool:
determinants = pool.map(determinant, matrices_to_process)
result = sum(((-1) ** col) * random_matrix[0][col] * det for col, det in enumerate(determinants))
end_time = time.time()
print(f"Параллельный детерминант: {result}")
print(f"Параллельное время: {end_time - start_time} секунд")
if __name__ == "__main__":
matrix_size = 10 # размер матрицы
lower_limit = 5 # числа в матрице от
upper_limit = 15 # и до
processes = [2, 4, 8, 16, 32]
#
# последовательное вычисление
#sequential_determinant_calculation(matrix_size, lower_limit, upper_limit)
# параллельное вычисление
for i in processes:
print("Потоков " + str(i))
parallel_determinant_calculation(matrix_size, lower_limit, upper_limit, i)

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

View File

@@ -0,0 +1,28 @@
# Отчет по лабораторной работе №7
Выполнила студентка гр. ИСЭбд-41 Плаксина А.В.
# Эссе на тему балансировки нагрузки
Балансировка нагрузки в распределенных системах - это такой алгоритм, который помогает избежать перегрузки одних узлов системы и застоя других, что повышает производительность системы и ее отказоустойчивость.
Существует несколько методой балансировки нагрузки, например, такие как :
- раунд-робин, или по круговороту; запросы распределяются по серверам ко кругу
- взвешенное распределение, то есть с помощью весовых коэффициентов
- на основе состояния, здесь учитывается загрузка сервера
Также предусмотрены несколько открытых технологий для балансировки нагрузки, к примеру:
- nginx, веб и прокси сервер, поддерживает многие методы балансировки
- apache, имеет модуль mod_proxy_balancer, который позволяет распределить трафик между несколькими серверами.
- а также happroxy, varnish cache и docker swarm
Данные платформы включают в себя не только балансировку нагрузки, но и кэширование, оптимизацию и шифрование.
Процесс балансировки нагрузки на базах данных отличается от балансировки на серверах.важно принимать во внимание особенности SQL и NoSQL баз данных и выбрать один из методов распределения запросов. Такие как:
- репликация, когда запрос копируется на доступные серверы
- шардинг, такое разделение данных на несколько независимых фрагментов (шардов)
- кластеризация, объединение нескольких баз данных
Одним из ключевых элементом балансировки нагрузки является реверс - прокси. Они действуют как посредники между пользователями и серверами. Они используются как для и балансировки нагрузки, так и для кэширования данных, оптимизации производительности, аутентификации пользователей и защиты от вредоносных атак.
Подводя итоги, можно сказать, что балансировка нагрузки является очень важным элементом работы современных систем. Они позволяют улучшить производительность и стабильность систем.

View File

@@ -0,0 +1,27 @@
# Отчет по лабораторной работе №8
Выполнила студентка гр. ИСЭбд-41 Плаксина А.В.
# Эссе на тему уйстройства распределенных систем
Сложные системы, такие как социальная сеть ВКонтакете пишутся в распределенном стиле, так как такие сервисы обладают очень большим числом пользователей и соответствующей нагрузкой на сервисы, то логично было бы разбить такое приложение на несколько микросерсивов.
Во-первых, это повышает масштабируемость, что позволяет работать системе более эффективно, при этом не понижая ее производительность;
Во-вторых, это увеличение отказоустойчивости, так как если один элемент выходить из строя, то вся система будет продолжать работать.
Существуют такие системы как оркестры приложений, это такие технологии, которые поддерживают сложные распределенные системы с большим количеством компонентов. Они облегчают развертывание, масштабирование и самое управление такими приложениями, тем самым повышая производительность и отказоустойчивость.
Такие системы помогают управлять всеми докер контейнерами сразу, минимизирует работу при их разварачивании, тем самым давая возможность разработчикам концетрироваться на улучшениие функциональности, не отвлекаясь на саму инфаструктуру.
Существует такой механизм, как очереди обработки сообщений, который является интсрументом для управления асинхронными сообщениями в распределенных системах. Очереди помогают равномерно распределять нагрузку на систему и обеспечивать более стабильную работу, улучшая ее гибкость и отказоустойчивость. Сообщения в этом случае это просто данные или команды, которые передаются между компонентами системы для выполнения определенных действий.
На мой взгляд, у распределенных систем есть как и преимущества, так и недостатки.
Например, к плюсам можно отнести:
- способность обрабатывать большое количество запросов;
- при отказе работы одного из микросерверов, другие его распределят его работу между собой;
- высокая производительность;
К минусам относится:
- сложность разработки таких систем
- задержки передачи данных по сети
В распределенные системы можно внедрить параллельные вычисления.
Это целесобразно сделать тогда, когда нужно повысить производительность ситсемы и обрабатывается большой объем матрицы (такое мы могли наблюдать при перемножение матриц и вычислении детерминанта). Если задачи незавсимы друг от друга, то распараллеливание тоже может быть эффективно;
Если же объем данных небольшой и задачи зависимы друг от друга, должны выполняться последовательно (в таких случаях сложно выявить ошибку), то внедрять параллельные вычисления будет нецелесообразно.