Request Volume throttling Method-log current request volume with local cache [pit]

Source: Internet
Author: User
Tags httpcontext

There is a need to limit the number of times each account requests a server (this can be configured in a Db,xml file or other). Unit: X times/minute.   If the number of times in 1 minutes <=x is allowed access, 1 minutes >x no longer allowed access. This kind of demand is very common, such as the request Baidu Map API Service interface, there are such restrictions, but the unit is different.

In general, the interface requests on the server side will be recorded, such as in DB, record accounts, request time, request information, request operation, server response information and so on. Therefore, it is logically possible to obtain the requested amount of the current time period (the count () operation of the execution record, in db, Sql:select count (*) from the requestrecordtable where account =. and Reqtime. )。 But this is not realistic: for such a small function should also be time-consuming to calculate, completely wasted computing resources, memory resources, once the request volume, record number of large increase, then performance is certainly very poor.

So I think of the cache: 1. Put the maximum amount of requests for the account in the cache and never expire.  2. Put the amount of requests for this account for 1 minutes in the cache, and the 1-minute expiration is automatically released. 3. For each request, the current request volume is +1, and after the maximum request volume of the account, <= allows,> to exceed the number of times. For the sake of simplicity, use the. Net local cache. See the code (the maximum number of requests for this account has been obtained, if the acquisition fails the read configuration:

1  /// <summary>2         ///Verify that the current request volume for this account exceeds the limit3         /// </summary>4         /// <param name= "Account" >Account</param>5         /// <param name= "Maxnumlimit" >Maximum request amount, acquired to</param>6         /// <returns>true-over, false-not more than</returns>7          Public BOOLVerifymaxnumlimit (stringAccountintmaxnumlimit)8         {9             stringCurrentsendnumcachekey =string. Format ("Syscode_{0}_currentsendnum", account);Ten             ObjectCurrentsendnumobj =Httpcontext.current.cache[currentsendnumcachekey]; One             intCurrentsendnum =0; A             if(Currentsendnumobj! =NULL)//Cache exists -             { -Currentsendnum = (int) Currentsendnumobj; thecurrentsendnum++; -Httpcontext.current.cache[currentsendnumcachekey] =Currentsendnum; -             } -             Else   //cache failure, expired, or cache issue. Re-write: Current number of requests 1 times, expiry time 1 minutes +             { -Currentsendnum =1; +HttpContext.Current.Cache.Insert (Currentsendnumcachekey,1,NULL, DateTime.Now.AddMinutes (1), cache.noslidingexpiration); A             } at  -             returnCurrentsendnum >Maxnumlimit; -}

At first glance, there is no problem at all. However, when you test yourself locally, it turns out that the calling interface, which did not exceed the limit number of times before, is successful, but once the volume of the request is exceeded, it cannot be requested even after 5 minutes. The reason: Verifymaxnumlimit has since returned true=> 1 minutes after the cache is not cleared and still exists.

What is the ultimate reason??

1. Is 15 lines: httpcontext.current.cache[currentsendnumcachekey] = currentsendnum;

This code seems to just modify the cache value. In fact, this code is equivalent to:HttpContext.Current.Cache.Insert (Currentsendnumcachekey, Currentsendnum)! That is, overwrite the cache and set the cache to never expire (unless IIS application pool recycles, or external conditions such as insufficient memory) = "cache not invalidated =" The current request volume is constant + +, so return currentsendnum > Maxnumlimit has been true .

2. Even if the 1 is solved, there is a bug that is not easy to find, it is difficult to see that multiple threads use and modify the unified resource = "evoked concurrency problem: When the same account request 1 and request 2 come simultaneously, may request 1 of line 16 and request 2 LINE21 is executed successively. There was a dirty read and write.

So, need to solve: 1. Find a way to modify the cache value without modifying the cache expiration time (local cache HttpContext.Current.Cache does not seem to be implemented, discarded, 2. Lock or make a single case.

My company happens to have a Redis component that meets the above and is thread-safe when it is packaged. So I finally used Redis to record the current amount of my account request. The code is actually similar to the code snippet above, except that all the places related to HttpContext.Current.Cache are changed to Redis related statements.

At this end, the request volume limit is fulfilled.

Experience: With regard to HttpContext.Current.Cache, some of the code seems dull but the interior has an unclear role.

In the future, we should write more code, accumulate more experience, encounter more pits, will a fall into your wit.   Of course, if you can get expert guidance or other places before you see the relevant introduction of this pit, then can avoid better, less detours save time. As for, multiple requests at the same time, concurrency, shared resources to be careful, the best locking (lock will lead to inefficient), this is also the design to consider good, or out of the bug is difficult to debug reproduce.

Request Volume throttling Method-log current request volume with local cache [pit]

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.