This is the seventh day of my participation in the August More text Challenge. For details, see:August is more challenging

The message queue

asynchronous

For example, now there is an order system, the order is basically completed in one method (deduct the balance, create the order can be done) and then the product added a demand. When the user clicks on the order, send an APP to notify the other party. Then, still need to occupy goods ah, settlement duck…

In short, the current code after the transformation of very slow. It used to take a second to place an order. Now it takes four to five seconds to place an order.

Uh huh… We can only do this asynchronously, now when the user orders again, we first go through the previous process, and then throw the time-consuming operation into the queue… The customers in the queue will be processed slowly (it will be processed anyway 🤣).

The decoupling

After the launch of the order system, as our messaging services are centralized on one item, the day. The parameters of one of the SMS messages need to be changed. It’s done. It’s out. It’s easy… Five minutes later, small X ah, in the just that message parameters in the change back…

This is not good, frequent releases of projects can lead to a decline in user experience… You ponder. Hey, you can use queue to solve this problem, every time you send a message is only sent to the queue, even if you need to update the item message content can also be stored, after going online to continue to send unfinished SMS… Nice duck

Queue

Before we get familiar with message queues, let’s look at queues in C# :

public record ChatMsg(string Content, string UserId);
public static void Main()
{
    Queue<ChatMsg> chatMsgs = new Queue<ChatMsg>();
    chatMsgs.Enqueue(new ChatMsg("hello wrold...".$" user{new Random().Next(1.10)}"));
    chatMsgs.Enqueue(new ChatMsg("hello C#".$" user{new Random().Next(2.20)}"));

    Task.Factory.StartNew(() =>
    {
        while (chatMsgs.TryDequeue(out var chat))
        {
            Console.WriteLine("Said {0} {1}", chat.UserId, chat.Content); }}); Console.WriteLine("Do something else...");
    Console.ReadKey();
    
    //output:
    // Do something else...
    // User 5 says: hello word...
    User 14 says: hello C#
}
Copy the code

Wuhu, it feels ok. Start a new thread in the Queue if new messages are added to the Queue. He can still operate

RabbitMQ

The simple way to understand RabbitMQ is to add a store to a Queue. So that the consumer (who gets the message) can read the message correctly (without losing the message)

📢 3.1 Use RabbitMQ through EasyNetQ(NuGet package)

PM> Install-Package EasyNetQ
Copy the code

Configure middleware:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();

    using var bus = RabbitHutch.CreateBus(Configuration.GetConnectionString("MQ"));
    var subscriber = new AutoSubscriber(bus, "appId");
    subscriber.SubscribeAsync(new[] { Assembly.GetExecutingAssembly() });
    services.AddSingleton(bus);
}
Copy the code

Message entity:


public record ChatMsg(string Content, string UserId);
Copy the code

Consumer:

public class ChatMsgConsumer : IConsumeAsync<ChatMsg>
{
    private readonly ILogger<ChatMsgConsumer> _logger;

    public ChatMsgConsumer(ILogger<ChatMsgConsumer> logger)
    {
        _logger = logger;
    }
    [AutoSubscriberConsumer(SubscriptionId = "message.consumer")]
    public Task ConsumeAsync(ChatMsg message, CancellationToken cancellationToken = default)
    {
        _logger.LogInformation("User {0} says: {1}", message.UserId, message.Content);
        returnTask.CompletedTask; }}Copy the code

Publisher:

[ApiController]
[Route("[controller]/[action]")]
public class HomeController : ControllerBase
{
    private readonly IBus _bus;
    public HomeController(IBus bus)
    {
        _bus = bus;
    }

    [HttpGet]
    public bool SendMessage()
    {
        _bus.PubSub.Publish(new ChatMsg("hello rabbitmq"."Customer Zhang SAN"));
        return true; }}Copy the code