简体   繁体   中英

How async nlog works with webapi hosted in IIS?

I have web api hosted in IIS which write every request logs to database with nlog . It works as expected. Our db is shared with other projects, and lately seeing some contention in db - which was causing some of our web api calls to take longer time or timeout. (current time out is 20 seconds, and increasing timeout is not an option)

I am thinking of using nlog's async functionality which help write logs asynchronously on separate thread.

How would IIS handles these kind of long running process after returning the call to client? Any kind of insight would be helpful.

First, let's put aside IIS and only discuss the use of asynchronous between application(not only webapi) and SQL. Whatever you use NLog's asynchrony or any other, its working principle remains the same.

  • When user clicks on a button and application writes log to database. This requires multiple smaller tasks like reading and populating data in internal object, establing connection with SQL and saving it.

  • As SQL runs on another machine in network and runs under different process, it could be time consuming and may take bit longer.

  • So, if the application runs on a single thread then the screen will be in hanged state till all the tasks completes which is a very bad user experience.

It has been seen that while executing a request, around 70-80% of the time gets wasted while waiting for the dependent tasks. So, it can be maximum utilized by asynchronous programming where once the task is passed to another process (say SQL), current thread saves the state and available to take another task. When the SQL task completes any thread which is free, can take it up further.

Now, let's discusss how IIS deal with asynchronous. IIS doesnot own any thread pool itself instead uses CLR thread pool. When a request is received by IIS, it takes a thread from CLR thread pool and assigns to it which further processes the request. So IIS just assign thread and the CLR thread pool determines when threads are to be added or taken away.

The CLR thread pool contains work threads and the I/O completion port or IOCP threads. When you make asynchronous I/O calls in your application, or your application accesses the file system, databases, web services, etc., then the runtime uses IOCP threads.

With NLog AsyncWrapper then the application-thread will only have the overhead of NLog automatically capturing relevant thread-context (based on destination NLog Targets, ex. ${threadid} ), and pushing to a ConcurrentQueue. Thus the application-thread will not be affected by database-timeouts of 20 secs (or more).

The NLog AsyncWrapper uses background-thread from the CLR ThreadPool (triggered by Timer) for writing pending LogEvents on its ConcurrentQueue. If the application-threads are logging very fast and the background-thread cannot keep up (because of database timeouts), then it will by default start to discard LogEvents (Avoid out-of-memory-issue or blocking the application-threads).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM