Делает ли DB Queries Verus Хранение предметов в коллекции? - PullRequest
7 голосов
/ 10 мая 2011

Я пытаюсь создать систему напоминаний и использую кварц для планирования.Однако я придумываю несколько возможных способов сделать то, что мне нужно, но я не уверен, что лучший способ и как его протестировать.

В основном у меня есть система напоминаний, которую пользователи могут устанавливать напоминания,Это как Календарь Google.Вы устанавливаете дату и время вашего мероприятия, а затем устанавливаете напоминание, говоря: «Напомните мне за 15 минут до»

Таким образом, вы можете провести мероприятие 10 мая 2011 года в 9:59, и вы можете сказать напоминаниея "за 15 минут до"

Так что это будет 10 мая, 10:44 утра.

Я буду в размещенной среде.(Мой сайт и расписание будут работать в одной и той же среде и даже в одном и том же решении. Поэтому это не может сильно замедлить просмотр пользователями моего сайта.)

Я также использую nhibernate и свободно говорюnhibernate, чтобы сделать запрос базы данных.Я использую asp.net mvc 3 для своего веб-сайта.

Вариант 1.

Каждую минуту выполняйте запрос к базе данных и получайте все напоминания, которые следует отправлять вв ту минутуЭто, конечно, будет означать запрос к базе данных каждую минуту и, вероятно, слишком интенсивный для общей среды.

Вариант 2.

Выполнять запрос к базе данных каждые 5 минут и захватывать всенапоминания, которые должны быть отправлены в этом 5-минутном блоке, и сохранить их в коллекции (таким образом, в памяти), а затем каждую минуту проверять, какие из них необходимо отправить.

Это, конечно, уменьшает количество выполненных запросов, ноне уверен, что это потребует слишком большого объема памяти.

Вариант 3

То же, что и в Варианте 2, но отправляйте запрос каждые 15 минут и сохраняйте в коллекции.

Это, конечно, означает меньше запросов к базе данных, но больше хранится в памяти.

Опция 4

Выполняйте запрос к базе данных каждые 15 минут и получайте все напоминания.немедленно блокируйте и запускайте их.

Это означает, что они не будут храниться в памяти очень долго и уменьшат количество запросов.Однако, в зависимости от того, когда пользователь настроен на напоминание, электронная почта может прийти намного раньше, чем он установил.

Например, они сказали, что напомните мне в 10:44Мой планировщик запустится в 10:00, и он будет работать с 10:00 до 10:15, а затем с 10:15 до 10:30, затем с 10:30 до 10:45.

Так что электронная почта будетна самом деле прибыть на 14 минут раньше, чем предполагалось.

Ответы [ 2 ]

1 голос
/ 10 мая 2011

Вот как бы я решил эту проблему.

  • На уровне БД я бы создал простую очередь. Этот список сообщений также будет включать время отправки. При запросе этот список будет иметь следующий элемент в верхней части.

  • Агент сообщений будет запрашивать этот список и действовать на верхнем элементе или спать, пока не наступит срок для верхнего элемента в списке.

Одним из преимуществ этого метода является то, что у вас нет действующего агента, применяющего бизнес-правила для проверки очереди. Если вы хотите, чтобы он просыпался каждую минуту (например, чтобы проверить, есть ли новые сообщения, которые необходимо отправить), то просто убедитесь, что в этой очереди всегда есть событие каждую минуту (это событие может иметь тип, который не отправляет сообщение, сообщение «проснуться» не имеет целей). Агент проснется и выполнит проверку. Тогда, если вы хотите применить более сложные правила планирования, они просты. Вам не нужно перекодировать агента, вам просто нужно изменить, какие сообщения помещаются в очередь. (Например, проверяйте каждые 10 минут, когда система активно используется, и каждые 20 минут, когда она используется мало, и прекращайте проверку во время ночного резервного копирования). Все это может быть сделано (и изменено) без изменения кода вашего агента.


Простой пример из реального мира

QueueTable
----------
ID int
deliverTime datetime
nagCount int
expireTime datetime
active bool
processed datetime (null)
' maybe some audit stuf...
' content of the message -- or external link
' etc

START: агент делает такой звонок

SELECT TOP 1 * 
FROM QueueTable
WHERE active = true and processed is null
ORDER BY deliverTime DESC

Затем агент проверяет время доставки:

  • Если он прошел или в следующей нечеткой границе (1 секунда?), Он отправляет сообщение, затем устанавливает обработанное время на текущий момент в БД и возвращается к START:

  • Если это в будущем, то он спит до того времени поставки DeliveryTime или устанавливает событие, чтобы разбудить его в это время (зависит от платформы).

Первоначально я обработал как логическое значение, но если вы используете нулевое значение равным не обработанному, то оно может удваиваться как поле аудита.


Пример проверки каждые 10 минут, несмотря ни на что.

Как это работает: Поскольку результаты отсортированы по времени, самый быстрый из них появится вверху. Что мы делаем, так это добавляем элемент через 10 минут в набор результатов. Таким образом, верхний предмет никогда не будет дольше 10 минут от текущего времени.

SELECT TOP 1 * 
FROM QueueTable
WHERE active = true and processed is null
UNION ALL
SELECT NULL, DATEADD(min,GETDATE(),10), null, null, false, null, ...
ORDER BY deliverTime DESC

Обратите внимание, что активный столбец используется здесь как флаг, чтобы показать, что никаких действий не будет выполнено. Эта запись - всего лишь маркер, чтобы разбудить агента. Этот метод может также регулировать это в зависимости от других правил (например, времени суток, потому что ночью вам не нужно проверять так часто и т. Д.)

0 голосов
/ 10 мая 2011

Я бы, вероятно, сразу отказался от варианта 4, если он не соответствует вашим требованиям.

Другие опции действительно зависят от профиля вашей системы (Сколько людей его используют? Сколько напоминаний влюбой заданный 5/15 минутный период?) Это вопросы, на которые вам нужно будет ответить.Кроме того, сколько активности уже происходит на сервере?Если он еще не находится под сильным стрессом, то запрос каждую минуту - это совсем немного.

Наконец, имейте в виду, что если вы делаете запрос только каждые 5/15 минут, вы можете пропустить изменение / добавление / удаление вграфик, если это происходит после того, как вы запросили, и напоминание должно появиться в этом 5/15 минутном окне.Опять же, это сводится к требованиям приложения относительно того, является ли это приемлемым.

...