Nigrimmist
@Nigrimmist
Asp.net senior developer

Архитектурно-правильная отсылка большого количества email/sms с asp.net сайта

Уважаемые хабражители, есть сайт, который позволяет отправить через api/интерфейс цепочку смс/email. И у меня есть вопрос по архитектуре такого сервиса. Как правильно организовать алгоритм отсылки множества итемов на сервере.

Как вариант, мне на ум пришли следующие решения:
1)
— Кладём в базу то что хотим отослать со всеми нужными данными
— Сервис (win service?/quartz.net? или может другое решение?) проходится по каждой записи со статусом !inProgress (грубо говоря), открывает новый поток на сервере (целесообразно ли?), далее заносит статус inProgress=true пытается отослать, обрабатывая ошибки/ответы и тд.
— поток завершается, а перед этим выставляется соответствующий статус

2)
— Пытаемся выполнить сразу же после запроса пользователя в отдельном потоке по вышеописанному механизму минуя на первом этапе «подхват» winservice'ом, что экономит время, но не понятно что делать с количеством потоков, потому что подразумевается, что api будут дёргать очень часто.

Я предполагаю, что есть так называемые best practice для подобного, но самостоятельно к сожалению не нашёл, да и хочется живые советы почитать. Спасибо за внимание.
  • Вопрос задан
  • 3417 просмотров
Пригласить эксперта
Ответы на вопрос 2
TheHorse
@TheHorse
Я ничего не могу сказать на тему готовых решений, но что касается логики, контекста быстродействия и высокой нагрузки — должно быть как-то так:

Есть БД, есть программа (я так понимаю, задача у вас — реализация такой программы).
1. На прогу поступает ряд новых запросов. Если ОП достаточно — помещаем их в ОП, иначе свапаем в БД.
2. Есть мультиплексор, каждую итерацию цикла — он принимает ответы на запросы об отправке, и отправляет N новых запросов. Все выходы мультиплексора следует проверять алгоритмами обработки протоколов передачи СМС, EMail. Если пришло подтверждение отправки — записуем в буфер отправленных, иначе записуем в буфер повтора отправки. Как только эти буферы заполнены, либо n раз мультиплексор не выдаёт ничего нового — записуем инфу с буферов в БД.
3. Если есть свободная ОП, считываем ряд новых запросов с БД.

Суть всего этого такова: важно иметь количество потоков / процессов, что не зависит от количества запросов (а то сервер помрет); запросы к БД — только по 1000-2000 записей (не по одной, а то помрет сервер); по максимуму использовать доступную ОП;
Ответ написан
Комментировать
FinDK
@FinDK
Предложу свой вариант с учетом тех вариантов, что предложили Вы.
Но начну с замечаний по поводу потоков: был у меня проект, где на каждый чих создавался поток, в итоге никакой сервер не справлялся с нагрузкой — просто не хватало оперативной памяти. Как мне помнится, каждый поток отжирал 8 МБ.
Из этого опыта я вижу картинку следующим образом:
Каждый айтем надо класть в очередь, из которой брать и отправлять в одном или несколькими потоках, в зависимости от ситуации (настроек скажем App.config).
При успешном отправлении записывать в БД сразу пачкой.

Из всего этого следует, что нужно продумать очередь отправки с пулом потоков (а может даже и одного потока хватит), и разбитие очереди на пачки.
Выгода:
1) Разбиение на пачки снижает нагрузку на SQL сервер.
2) На каждый айтем из очереди не создается отдельного потока, что экономит оперативную память.

Использовал бы я как раз WinService, дописав к ней консоль, позволяющая настраивать очередь, количество потоков, и прочее, что понадобится.

Надеюсь помог, удачи!
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы