АРХИТЕКТУРА MSMQ С ВЫДЕЛЕННЫМИ ПРОЦЕССОРАМИ НА БАЗУ ДАННЫХ - PullRequest
0 голосов
/ 18 апреля 2020

У меня есть веб-приложение в ASP. NET MVC, C#, и у меня есть конкретный c вариант использования, для обработки которого требуется много времени, и пользователям приходится ждать, пока процесс не завершится. Я хочу использовать MSMQ и передать тяжелую работу выделенным процессорам. Наше приложение имеет несколько клиентов, и каждый клиент имеет свою собственную базу данных SQL. Допустим, 100 клиентов составляют 100 отдельных SQL баз данных. Реальная задача, которую я имею, состоит в том, чтобы ускорить процесс с помощью MSMQ, но задача одного клиента не должна влиять на производительность других. Поэтому у меня есть 2 решения:

Вариант-1: Уникальная частная очередь MSMQ для каждой базы данных, поэтому в моем случае это будет 100 очередей и будет расти. 1 выделенное ASP. NET консольное приложение, которое слушает выделенный MSMQ, поэтому в моем случае это будет 100 процессоров или консольных приложений.

Option-2: 1 большое личное MSMQ очередь для всех баз данных A: 1 выделенный процессор на базу данных, поэтому 100 процессоров B: 1 процессор, который слушает большой MSMQ

Я хочу придерживаться Варианта-1, но я хотел бы знать, возможно ли это и для предприятия? Тип решения?

1 Ответ

1 голос
/ 19 апреля 2020

На самом деле у вас есть два вопроса


  1. Во-первых, как вы allocate a resources affinity to a processor до SQL Server.

    Выберите базу данных в Sql Управление Studio, щелкните правой кнопкой мыши и следуйте этому ..

    enter image description here


Регулярно очищайте вашу базу данных

DBCC FREEPROCCACHE;

DBCC DROPCLEANBUFFERS;


MSMQ, включите [journaling][2], но также рассмотрите другой процесс организации очередей RabbitMQ et c или напишите простой для enquque заданий образец отсюда

public class MultiThreadQueue
{
BlockingCollection<string> _jobs = new BlockingCollection<string>();

public MultiThreadQueue(int numThreads)
{
    for (int i = 0; i < numThreads; i++)
    {
        var thread = new Thread(OnHandlerStart)
            { IsBackground = true };//Mark 'false' if you want to prevent program exit until jobs finish
        thread.Start();
    }
}

public void Enqueue(string job)
{
    if (!_jobs.IsAddingCompleted)
    {
        _jobs.Add(job);
    }
}

public void Stop()
{
    //This will cause '_jobs.GetConsumingEnumerable' to stop blocking and exit when it's empty
    _jobs.CompleteAdding();
}

private void OnHandlerStart()
{
    foreach (var job in _jobs.GetConsumingEnumerable(CancellationToken.None))
    {
        Console.WriteLine(job);
        Thread.Sleep(10);
    }
 }
}

Надеюсь, это поможет:)


Вопрос был перефразирован, он имел в виду кое-что еще, когда сказал "Процессоры".


Обновление добавило шаблон потребителя с помощью onPeek:

Вам действительно нужно опубликовать некоторый код!

Рассмотрите возможность использования метода OnPeekCompleted. Если есть ошибка, вы можете оставить сообщение в очереди

Если у вас есть какой-то заголовок, который идентифицирует сообщение, вы можете переключиться на другой выделенный / поток.

    private static void OnPeekCompleted(Object sourceQueue, PeekCompletedEventArgs asyncResult)
    {
        // Set up and connect to the queue.
        MessageQueue mq = (MessageQueue)sourceQueue;

        // gets a new transaction going
        using (var txn = new MessageQueueTransaction())
        {
            try
            {
                // retrieve message and process
                txn.Begin();
                // End the asynchronous peek operation.
                var message = mq.Receive(txn);

            #if DEBUG
                // Display message information on the screen.
                if (message != null)
                {
                    Console.WriteLine("{0}: {1}", message.Label, (string)message.Body);
                }
            #endif
                // message will be removed on txn.Commit.
                txn.Commit();
            }
            catch (Exception ex)
            {
                // If there is an error you can leave the message on the queue, don't remove message from queue
                Console.WriteLine(ex.ToString());
                txn.Abort();
            }
        }

        // Restart the asynchronous peek operation.
        mq.BeginPeek();
    }

Вы также можно использовать сервисный брокер

...