<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          接口限流:限制接口的訪問(wèn)頻率

          共 2769字,需瀏覽 6分鐘

           ·

          2020-08-02 13:41

          限流,顧名思義,就是限制對(duì) API 的調(diào)用頻率。每一次 API 調(diào)用,都要花費(fèi)服務(wù)器的資源,因此很多 API 不會(huì)對(duì)用戶無(wú)限次地開放,請(qǐng)求達(dá)到某個(gè)次數(shù)后就不再允許訪問(wèn)了,或者一段時(shí)間內(nèi),最多只允許訪問(wèn) API 指定次數(shù)。

          目前,我們的接口是沒(méi)有任何限流措施的,只要用戶調(diào)用接口,服務(wù)器就會(huì)處理并返回?cái)?shù)據(jù)。為了防止接口被惡意用戶刷爆,我們來(lái)給接口限流。

          上一篇中我們已經(jīng)整理了接口并加入了緩存,我們的限流政策可以根據(jù)緩存的設(shè)置情況來(lái)制定。對(duì)于緩存時(shí)間較長(zhǎng)的接口,可以適當(dāng)放寬限制,而對(duì)于可能需要訪問(wèn)數(shù)據(jù)庫(kù)的接口,則進(jìn)行嚴(yán)格的限制。

          django-rest-framework 為我們提供了 2 個(gè)常用的限流功能輔助類,分別是 AnonRateThrottleUserRateThrottle。AnonRateThrottle ?用于限制未認(rèn)證用戶的訪問(wèn)頻率,限制依據(jù)是用戶的 ip。UserRateThrottle 用于限定認(rèn)證用戶,即網(wǎng)站的注冊(cè)用戶(目前我們博客不支持用戶登錄注冊(cè),所以這個(gè)類沒(méi)什么用)。兩個(gè)類可以用于同一 API,以便對(duì)不同類型的用戶實(shí)施不同的限流政策。

          這兩個(gè)輔助類限制頻率的指定格式為 "最大訪問(wèn)次數(shù)/時(shí)間間隔",例如設(shè)置為 10/min,則只允許一分鐘內(nèi)最多調(diào)用接口 10 次。超過(guò)限定次數(shù)的調(diào)用將拋出 exceptions.Throttled 異常,客戶端收到 429 狀態(tài)碼(too many requests)的響應(yīng)。

          再次根據(jù)已有 API 列表和緩存情況來(lái)分析一下我們的限流政策:

          接口名URL限流
          文章列表/api/posts/10/min
          文章詳情/api/posts/:id/10/min
          分類列表/categories/10/min
          標(biāo)簽列表/tags/10/min
          歸檔日期列表/posts/archive/dates/10/min
          評(píng)論列表/api/posts/:id/comments/10/min
          文章搜索結(jié)果/api/search/5/min

          補(bǔ)充說(shuō)明:

          1. 首頁(yè)文章列表 API:有緩存,正常用戶不會(huì)訪問(wèn)太頻繁,限定 10/min
          2. 文章詳情 API:有緩存,正常用戶不會(huì)訪問(wèn)太頻繁,限定 10/min
          3. 分類、標(biāo)簽、歸檔日期列表,有緩存,正常用戶不會(huì)訪問(wèn)太頻繁,限定 10/min
          4. 評(píng)論列表,有緩存,正常用戶不會(huì)訪問(wèn)太頻繁,限定 10/min
          5. 搜索接口,正常用戶不會(huì)訪問(wèn)太頻繁,限定 5/min

          接口限流規(guī)則制定好后,接下來(lái)就設(shè)置限流輔助類就可以了。

          啟用限流有 2 種方式,一是全局設(shè)置,二是單個(gè)視圖設(shè)置,單個(gè)視圖的設(shè)置會(huì)覆蓋全局設(shè)置。因?yàn)閹缀跛薪涌诙际菍?duì)匿名用戶限流,因此先來(lái)進(jìn)行全局設(shè)置。在項(xiàng)目配置文件 common.py 中找到 REST_FRAMEWORK 配置項(xiàng),加入如下配置:

          #?filename="common.py"
          REST_FRAMEWORK?=?{
          ????'DEFAULT_THROTTLE_CLASSES':?[
          ????????'rest_framework.throttling.AnonRateThrottle',
          ????],
          ????'DEFAULT_THROTTLE_RATES':?{
          ????????'anon':?'10/min',
          ????}
          }

          這樣,所有接口訪問(wèn)頻率均被設(shè)置為 10/min。

          對(duì)于搜索接口,我們制定的限流規(guī)則是 5/min,因此我們對(duì)這個(gè)視圖集的限流類進(jìn)行單獨(dú)設(shè)置。

          因?yàn)槿峙渲弥?,默認(rèn)設(shè)置的限流頻率為 10/min,為了將限流類的默認(rèn)頻率設(shè)置為 5/min,我們需要繼承原限流類覆蓋它的 THROTTLE_RATES 屬性,代碼非常簡(jiǎn)單:

          #?filename="blog/views.py"
          from?rest_framework.throttling?import?AnonRateThrottle

          class?PostSearchAnonRateThrottle(AnonRateThrottle):
          ????THROTTLE_RATES?=?{"anon":?"5/min"}

          接著在搜索接口的視圖集中通過(guò) throttle_classes 指定這個(gè)限流類:

          #?filename="blog/views.py"
          class?PostSearchView(HaystackViewSet):
          ????index_models?=?[Post]
          ????serializer_class?=?PostHaystackSerializer
          ????throttle_classes?=?[PostSearchAnonRateThrottle]

          我們來(lái)測(cè)試一下,限流是否真的起了作用。

          首先來(lái)測(cè)試 10/min 訪問(wèn)限制的接口,以文章列表接口 api/v1/posts/ 為例,在連續(xù)訪問(wèn) 10 次后,接口返回了如下結(jié)果:

          HTTP 429 Too Many Requests Allow: GET, HEAD, OPTIONS Content-Type: application/json Retry-After: 52 Vary: Accept

          { "detail": "請(qǐng)求超過(guò)了限速。Expected available in 52 seconds." }

          一分鐘后重新訪問(wèn)又恢復(fù)了正常。

          再來(lái)測(cè)試一下搜索接口,訪問(wèn) /api/v1/search/?text=markdown,在連續(xù)刷新 5 次后,接口返回如下結(jié)果:

          HTTP 429 Too Many Requests Allow: GET, HEAD, OPTIONS Content-Type: application/json Retry-After: 26 Vary: Accept

          { "detail": "請(qǐng)求超過(guò)了限速。Expected available in 26 seconds." }

          一分鐘后重新訪問(wèn)又恢復(fù)了正常。



          !!! note "注意"

          因?yàn)樗阉鞴δ芤蕾?Elasticsearch 服務(wù),因此測(cè)試接口時(shí)需要運(yùn)行 Docker 容器,可參考《基于 drf-haystack 實(shí)現(xiàn)文章搜索接口》這篇文章。

          https://www.zmrenwu.com/courses/django-rest-framework-tutorial/materials/101/

          參考資料

          [1]

          HelloGitHub-追夢(mèng)人物:?https://www.zmrenwu.com






          點(diǎn)個(gè)“在看”支持一下?
          瀏覽 29
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  伊人国产综合视频在线 | www.99超碰 | 国产一区二区无码午夜久久久豆花av | 在线免费看黄视频 | 欧美三级台湾三级少妇 |