以前一篇文章到經過access key調用API的方式,這種調用方式不免會碰到一個問題,那就是,若是用戶不挺地高頻率調用API,服務器是否會過載,若是過載了,是否會影響內部服務。redis
有個作法,就是給access key設置調用配額(limit,duration),這個配額指的是在某個時間段內(duration),調用的次數不能超過limit指定的數額。若是超過了,則拒絕服務。這種能夠經過緩存來實現,利用緩存的expire時間,而且維持一個計數器,每當調用一次,則計數器減一。數據庫
def init(access_key, limit, duration): memcache.set(key=access_key, val=limit, expire=duration) def handle(access_key): count = memcache.get(key=access_key) if count == 0: return 'DENY' memcache.decr(key=access_key) return 'OK'
前面init函數作初始化,後面handle函數對請求作判斷,每掉用一次,就把計數器減一;若是當前計數器裏的值爲0,則拒絕服務。segmentfault
使用配額的目的是:對於一些高級客戶,能夠提升配額,以提升體驗。若是是內部服務調用,那麼這個配額,能夠提升些。後端
能夠提供不一樣優先級的隊列,針對不一樣的請求的優先級,把他們放到不一樣的隊列裏,先處理優先級高的隊列,而後優先級更低的隊列。(能夠用redis裏的有序隊列來實現?)若是有針對這個隊列的處理服務,這個服務可以合併請求,那麼則能夠減輕後端服務的負載。緩存
student: { 'name': 'ABC', 'age': 30, } requests: [0] {'action': 'ModifyItems', 'name': 'xiao ming'} [1] {'action': 'ModifyItems', 'age': 26} After handled new request: [0] {'action': 'ModifyItems', 'age': 26, 'name': 'xiao ming'}
如上,若是數據庫裏有一個對象student
,經過請求ModifyItems
能夠修改student屬性,請求隊列如requests所示,第一個請求修改了name
,第二個請求修改了age
,這個時候,能夠把這2個請求合併成一個,這個新的請求跟兩個請求最終達到的小姑都是同樣的,因此是可行的。服務器
若是一直優先處理高優先級的隊列,等這個隊列的請求處理完了,再處理優先級低一級的請求,那麼優先級低的隊列可能要等好久才能處理。函數
這個時候,能夠根據權重來處理,若是優先級隊列有2個,他們優先級分別是:2和1,數值越高,表示優先級更高,那麼根據優先級權重,服務器先處理優先級高的隊列裏的2個請求,而後再去處理優先級低隊列裏的1個請求,優先級低的隊列則不會被餓死。設計
參考:《彈力設計之「限流設計」》陳皓code