2015-11-04 40 views
0

我有一個Web應用程序,它具有多個同質Web前端(特別是,我在App Engine上運行)。我需要設計一個短期配額系統,以便在客戶的突發請求率超過配額時拒絕流量。需要支持的客戶數量在數萬個範圍內。我想衡量這些配額的時間範圍將在「分鐘」範圍內;最多一小時。測量/強制執行客戶Web請求配額的技術

E.g.如果時間範圍是10分鐘,並且客戶X請求的方式高於他們的配額,那麼我很滿意系統爲他們的請求提供所有,直到他們用盡每10分鐘允許的請求數量,然後拒絕所有他們要求剩餘的10分鐘窗口,然後開始處理下一個10分鐘窗口。我已經考慮

半烤成的解決方案:

  • 獲取仡Redis的盒子。對於客戶X的每個請求(或者其中一些固定的百分比,例如1比10,以減輕負載),請將GET設置爲X變量的計數。如果它>每10分鐘的配額,請拒絕該請求。否則,將INCR設置爲X變量的計數併爲請求提供服務。每隔10分鐘,將所有客戶的計數設置爲0.

  • 與上面類似,除了使用memcache,因爲該服務內置於應用程序引擎中,所以我不需要運行我自己的盒子。如果memcache值丟失,那麼哦 - 我們可能不會在那個時間窗口內節流(只要時間窗口足夠短,我們可能不會太在意)。

  • 每個網絡服務器存儲全球每個客戶的計數器,用於新請求 - 我看到的和請求 - 全局看到的。每個網絡服務器每隔一秒(或更多)都會將其新請求(每個客戶)的價值推送給一些集中的類似pub-sub的服務,該服務會將該值重新分配給所有網絡服務器(它們添加到他們的請求中) - 全球價值)。 Web服務器使用他們的請求 - 全局值(總是稍微陳舊)來決定是否服務或拒絕請求。

+0

有多少流量?大多數人可以簡單地將計數器保存在數據庫中並且沒問題。如果您預計每分鐘有數百萬的請求,那麼您可能需要做一些更智能的... – btilly

+0

呃 - 對不起。很明顯的一點就是忽略。對於我在這裏關注的特定類型的請求,我們預計一些客戶將產生高達50 /秒的時間。對於應用程序引擎數據存儲區(對於單個實體只支持大約5次寫入/秒的速率),這對於Redis或Cassandra來說肯定是可管理的。 –

+1

然後我會使用memcache。它會工作得很好。如果Redis或memcache是​​一種偶然的選擇,我會選擇Redis,但一個更容易。選項#3適合嚴重的規模。 您沒有考慮的選項是讓負載平衡器將用戶綁定到服務器。這簡化了這一點,因爲現在服務器應該知道所有的用戶請求。並且可以保持其他類型的用戶狀態。 – btilly

回答

1

Memcache對這種方案工作正常,但使用原子增量和提取。

但是請注意,10分鐘窗口的限制對保護系統免受過載影響不大。至少,您應該在整個窗口期間的不同時間(隨機或謹慎選擇)重新設置客戶數量,以免您的所有客戶一次超負荷。如果您有足夠的客戶,這將確保負載分佈均勻。