distributed-computing/tasks/mironov-eo/lab_4/README.md
2023-12-06 00:12:01 +03:00

170 lines
5.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Отчет по лабораторной работе №4
Выполнил студент гр. ИСЭбд-41 Миронов Е.О.
## Прохождение tutorial
Установил rabbitMQ server, erlang и зашел в брокер под гостем по http://localhost:15672/#/
Туториал 1:
![](pic/tut1.png)
Туториал 2:
![](pic/tut2.png)
Туториал 3:
![](pic/tut3.png)
## Разработка демонстрационных приложений
Предметная область: Доставка еды. Производитель - кухня, которая сигнализирует о том, что заказ готов. Потребитель 1 - курьер тратит время и доставляет заказ. Потребитель 2 - самовывоз, клиент сам забирает свой заказ, и мы не тратим время
1. Publisher
```py
using System.Text;
using RabbitMQ.Client;
Random rand = new Random();
var factory = new ConnectionFactory { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();
channel.ExchangeDeclare(exchange: "delivery", type: ExchangeType.Fanout);
foreach (var item in Enumerable.Range(0, 1000))
{
var message = rand.Next().ToString();
var body = Encoding.UTF8.GetBytes(message);
channel.BasicPublish(exchange: "delivery",
routingKey: string.Empty,
basicProperties: null,
body: body);
Console.WriteLine($" [x] Готов заказ {message}");
await Task.Delay(500);
}
Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();
static string GetMessage(string[] args)
{
return ((args.Length > 0) ? string.Join(" ", args) : "info: Hello World!");
}
```
2. Consumer 1.
```py
using System.Text;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
var factory = new ConnectionFactory { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();
channel.QueueDeclare(queue: "self_exportation");
channel.QueueBind(queue: "self_exportation",
exchange: "delivery",
routingKey: string.Empty);
Console.WriteLine(" [*] Waiting for messages.");
var consumer = new EventingBasicConsumer(channel);
consumer.Received += async (model, ea) =>
{
byte[] body = ea.Body.ToArray();
var message = Encoding.UTF8.GetString(body);
string outputText = $"Клиент пришел сам и забрал заказ {message}";
Console.WriteLine($" [x] Done. {outputText}");
channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
};
channel.BasicConsume(queue: "self_exportation",
autoAck: false,
consumer: consumer);
Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();
```
3. Consumer 2.
```py
using System.Text;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
Random rand = new Random();
var factory = new ConnectionFactory { HostName = "localhost" };
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();
string queueName = $"courier{rand.Next()}";
channel.QueueDeclare(queue: queueName);
channel.QueueBind(queue: queueName,
exchange: "delivery",
routingKey: string.Empty);
Console.WriteLine(" [*] Waiting for messages.");
var consumer = new EventingBasicConsumer(channel);
consumer.Received += async (model, ea) =>
{
byte[] body = ea.Body.ToArray();
var message = Encoding.UTF8.GetString(body);
int waitTime = rand.Next(20, 90);
Thread.Sleep(waitTime * 100);
string outputText = $"Курьер потратил {waitTime} минут и отвез заказ {message}";
Console.WriteLine($" [x] Done. {outputText}");
channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
};
channel.BasicConsume(queue: queueName,
autoAck: false,
consumer: consumer);
Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();
```
## Результаты выполнения лабораторной работы
Выполнение с одним потребителем-курьером.
![](pic/3.png)
![](pic/4.png)
Очередь самовывоза обрабатывается моментально и несет минимальную нагрузку.
Очередь курьера довольно быстро загружается.
Для оптимизации работы курьера заменяем Thread.Sleep на await Task.Delay. Это позволит нам заняться следующей обработкой вместо синхронного ожидания. В примере это аналогично замене курьера на курьерскую службу и постоянным вызовом нового курьера.
![](pic/1.png)
![](pic/2.png)
Теперь очередь находится в примерно одинаковой загруженности все время.
Пример с двумя потребителями-курьерами
![](pic/7.png)
![](pic/8.png)
Очередь самовывоза не изменилась.
На очереди курьеров закономерно тратится в 2 раза больше времени
Аналогичный пример с асинхронным подходом
![](pic/5.png)
![](pic/6.png)
Такое же изменение в ~ 2 раза.
Итого : потребитель который требует более долгой обработки занимает больше ресурсов и времени и дольше остается в очереди брокера (как неождиданно). Асинхронный подход позволяет быстрее брать элементы из очереди, только это имеет мало смысла с cpu-bounds операциями