Considere el clásico esquema de diseño de canalización de mensajes RabbitMQ que consta de elementos Productor, Intercambio, Cola y Consumidor.

La tarea es organizar el monitoreo de lo que sucede en la cola y no afectar el software principal (software), agregar la capacidad flexible para crear informes y al mismo tiempo evitar costos adicionales. El diseño final debería permitirle generar rápidamente informes para analizar el flujo de datos en la tubería sin usar las capacidades del servidor principal (lo que evitará una carga adicional) y el software principal. El enfoque debería ser fácilmente portátil para una arquitectura más compleja.
En primer lugar, organizaremos un stand de demostración, para ello realizaremos los siguientes cambios en el funcionamiento del transportador:

Inicialmente, se configuró la siguiente configuración para Exchange (faust), que no cambia en el ejemplo considerado durante la modificación:

Una configuración importante es el tipo fanaut, que le permite crear dos colas peer-to-peer y duplicar todo el flujo de mensajes en la nueva cola de estadísticas:


sin ninguna interferencia con el proceso principal en la cola de registros. Comencemos a procesar el flujo de mensajes. En primer lugar, creamos una tabla en el servidor MS SQL para almacenar información estadística. Puede usar cualquier otro enfoque, por ejemplo, guardar mensajes en un archivo en formato xml o de cualquier otra manera, en este ejemplo, se selecciona el servidor SQL para evitar programación adicional
create table RabbitMsg( id int PRIMARY KEY IDENTITY(1000,1), [Message] nvarchar(1000) DEFAULT '', RegDate datetime default GETDATE())
Como puede ver en la consulta SQL, esta es una tabla con un número de registro, algo de texto y la fecha en que el registro se insertó en la tabla.
Creemos un cliente que se comunicará con RabbitMQ en la cola de estadísticas, recopilará los datos recibidos y los transferirá a la tabla RabbitMsg
using System; using RabbitMQ.Client; using RabbitMQ.Client.Events; using System.Text; using System.Data.SqlClient; namespace Getter { class Program { static void Main(string[] args) { var factory = new ConnectionFactory() { HostName = "192.168.1.241", Port = 30672, UserName = "robotics01", Password = "" }; using (var connection = factory.CreateConnection()) using (var channel = connection.CreateModel()) { channel.ExchangeDeclare(exchange: "faust", type: "fanout", durable: true); var queueName = "Statistics"; channel.QueueBind(queue: queueName, exchange: "faust", routingKey: ""); Console.WriteLine(" [*] Waiting for logs."); var consumer = new EventingBasicConsumer(channel); consumer.Received += (model, ea) => { var body = ea.Body; var message = Encoding.UTF8.GetString(body); Console.WriteLine(" [x] {0}", message); SqlConnection sqlconnection = new SqlConnection("Server=tcp:fastreportsql,1433;Initial Catalog=FastReportSQL;Persist Security Info=False;User ID=ufocombat;Password=;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"); sqlconnection.Open(); SqlCommand cmd = new SqlCommand($"INSERT INTO RabbitMsg(Message) VALUES (@msg)", sqlconnection); cmd.Parameters.AddWithValue("msg", message); cmd.ExecuteNonQuery(); sqlconnection.Close(); }; channel.BasicConsume(queue: queueName, autoAck: false, consumer: consumer); Console.WriteLine(" Press [enter] to exit."); Console.ReadLine(); } Console.WriteLine("Hello World!"); } } }
Veamos cómo funciona en tiempo real.
Mientras tanto, en MS SQL Server

Cree un informe basado en la cola de estadísticas
Esto es lo que sucedió:

Conclusión
El ejemplo considerado muestra cómo recopilar estadísticas rápidamente e incluso crear un informe que se puede guardar en PDF y enviar por correo de acuerdo con la canalización RabbitMQ y una cola adicional. Es fácil encontrar ejemplos de tareas cuando se recopila información sobre cualquier proceso e informes sin desarrollar el lado del servidor. Dado que FastReports ofrece una versión de código abierto, es posible reducir significativamente los costos de desarrollo sin costo adicional. El transportador en sí también es fácilmente reconfigurable y puede adaptarse para tareas más complejas.