Answer the question
In order to leave comments, you need to log in
Architecturally correct sending of a large number of email/sms from an asp.net site
Dear habrazhiteli, there is a site that allows you to send a chain of sms/email via api/interface. And I have a question about the architecture of such a service. How to properly organize the algorithm for sending multiple items on the server.
As an option, the following solutions came to my mind:
1)
- We put in the database what we want to send with all the necessary data
- Service (win service?/quartz.net? or maybe another solution?) goes through each record with the status !inProgress ( Roughly speaking), opens a new thread on the server (is it advisable?), then sets the status inProgress=true, tries to send, processing errors / responses, and so on.
- the thread ends, and before that the corresponding status is set
2)
- We are trying to execute immediately after the user's request in a separate thread according to the mechanism described above, bypassing the "pickup" by winservice at the first stage, which saves time, but it is not clear what to do with the number of threads, because it is assumed that api will be pulled very often.
I assume that there are so-called best practices for this, but unfortunately I didn’t find it on my own, and I want to read live advice. Thank you for your attention.
Answer the question
In order to leave comments, you need to log in
I can’t say anything about ready-made solutions, but as for logic, performance context and high load, it should be something like this:
There is a database, there is a program (as I understand it, your task is to implement such a program).
1. The program receives a number of new requests. If there are enough OPs, we put them in the OP, otherwise we swap them in the database.
2. There is a multiplexer, each iteration of the loop - it receives responses to send requests, and sends N new requests. All multiplexer outputs should be checked by algorithms for processing SMS and EMail transmission protocols. If a confirmation of sending has arrived, we will write it to the sent buffer, otherwise we will write it to the send retry buffer. As soon as these buffers are full, or n times the multiplexer does not produce anything new, we write the information from the buffers to the database.
3. If there is a free OP, we read a number of new queries from the database.
The essence of all this is this: it is important to have the number of threads / processes, which does not depend on the number of requests (otherwise the server will die); queries to the database - only 1000-2000 records (not one at a time, otherwise the server will die); make the most of the available OP;
I will offer my own version, taking into account the options that you suggested.
But I’ll start with comments about threads: I had a project where a thread was created for each sneeze, as a result, no server could cope with the load - there simply wasn’t enough RAM. As I recall, each thread ate 8 MB.
From this experience, I see the picture as follows:
Each item must be placed in a queue, from which it can be taken and sent in one or more threads, depending on the situation (settings, let's say App.config).
Upon successful sending, write to the database immediately in a batch.
From all this it follows that you need to think about the sending queue with a pool of threads (or maybe even one thread is enough), and splitting the queue into packs.
Benefit:
1) Splitting into packs reduces the load on the SQL server.
2) A separate thread is not created for each item from the queue, which saves RAM.
I would just use WinService, adding a console to it that allows you to configure the queue, the number of threads, and other things that you need.
Hope it helps, good luck!
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question