I have a asp.net application in a web farm (3 servers). Alongside that application I have a module that logs every request made of the website to a database. Currently the inserts are sychronous. I would like to change it so the inserts are sent to a queue which will insert them as it is able.
Would it be better to
-
Attempt to insert each request on a background thread (would too
many background threads get used up if the database hiccups?) -
Start an in-process queue on a single background thread that just
reads from queue and performs insert. - Create an out-of-process queue on the database server that each server sends page request logs to. Would the built in MSMQ be the thing to use for something like this? – or would that be overkill?
Option 2 sounds the best. Option 1 would definitely create way too many background threads, and option 3 sounds more complex than it needs to be.
You might try something like this.
Given this class:
Use this class to perform the logging:
I ran this with a simple command line test app without any database involvement (simulated a database call by sleeping for 10 ms) and it seemed to work great, but it should obviously be tested more before going into a production environment. Also, problems will of course arise if the requests come faster than you can save them to the database (which is unlikely but should be considered).
Update, February 2018: Looking at this now, I realize that you could end up with two
savingThreadinstances if you get unlucky with thread timing (which you should assume you will). Andnew Thread()is kind of an old way to do this kind of thing in C# now. I’ll leave modern, more thread-safe implementations of this as an exercise to the reader.