成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

[登錄那些事] 郵件發(fā)送,限流,漏桶與令牌桶

wpw / 2663人閱讀

摘要:關(guān)于如何限速,有兩個(gè)比較出名的算法,漏桶算法與令牌桶算法,這里對其簡單介紹一下,最后再實(shí)踐在我發(fā)郵件的中以下是發(fā)送郵件的,已限制為一分鐘兩次,你可以通過修改進(jìn)行試驗(yàn)。

前段時(shí)間,我使用了 jwt 來實(shí)現(xiàn)郵箱驗(yàn)證碼的校驗(yàn)與用戶認(rèn)證與登錄,還特別寫了一篇文章作為總結(jié)。

在那篇文章中,提到了一個(gè)點(diǎn),如何限速。

在短信驗(yàn)證碼和郵箱驗(yàn)證碼,如果不限速,被惡意攻擊造成大量的 QPS,不僅拖垮了服務(wù),也會(huì)心疼如水的資費(fèi)。鑒于君子固窮的原則,在我的郵箱服務(wù)里加上限速。

關(guān)于如何限速,有兩個(gè)比較出名的算法,漏桶算法與令牌桶算法,這里對其簡單介紹一下,最后再實(shí)踐在我發(fā)郵件的API中

以下是發(fā)送郵件的 API,已限制為一分鐘兩次,你可以通過修改 email 進(jìn)行試驗(yàn)。你也可以在我的站點(diǎn)直接試驗(yàn)

curl "https://graphql.xiange.tech/graphql" -H "Content-Type: application/json" --data-binary "{"query":"mutation SEND($email: String!) {
  sendEmailVerifyCode (email: $email)
}","variables":{"email":"[email protected]"}}"

以下是我關(guān)于登錄實(shí)踐的系列文章

【登錄那些事】實(shí)現(xiàn) Material Design 的登錄樣式

【登錄那些事】使用 jwt 登錄與校驗(yàn)驗(yàn)證碼

【登錄那些事】郵件發(fā)送,限流,漏桶與令牌桶

本文地址:https://shanyue.tech/post/rat...

Leaky Bucket (漏桶算法)

漏桶算法表示水滴(請求)先進(jìn)入到漏桶里,漏桶(bucket)以一定的速度出水,當(dāng)漏桶中水滿時(shí),無法再加水。

維護(hù)一個(gè)計(jì)數(shù)器作為 bucket,計(jì)數(shù)器的上限為 bucket 的大小

計(jì)數(shù)器滿時(shí)拒絕請求

每隔一段時(shí)間清空計(jì)數(shù)器

option 代表在 option.window 的窗口時(shí)間內(nèi)最多可以通過 option.max 次請求

以下是使用 redis 的計(jì)數(shù)器實(shí)現(xiàn)限流的偽代碼

const option = {
  max: 10,        // window 時(shí)間內(nèi)限速10個(gè)請求
  window: 1000    // 1s
}

function access(req) {
  // 根據(jù)請求生成唯一標(biāo)志
  const key = identity(req)
  // 計(jì)數(shù)器自增
  const counter = redis.incr(key)
  if (counter === 1) {
    // 如果是當(dāng)前時(shí)間窗口的第一個(gè)請求,設(shè)置過期時(shí)間
    redis.expire(key, window) 
  }
  if (counter > option.window) {
    return false
  }
  return true
}
這里有 Redis 官方使用 INCR 實(shí)現(xiàn)限流的文檔 https://redis.io/commands/INCR

此時(shí)有一個(gè)不算問題的問題,就是它的時(shí)間窗口并不是滑動(dòng)窗口那樣在桶里出去一個(gè)球,就可以再進(jìn)來一個(gè)球。而更像是一個(gè)固定時(shí)間窗口,從桶里出去一群球,再開始進(jìn)球。正因?yàn)槿绱?,它可能在固定窗口的后一半時(shí)間收到 max-1 次請求,又在下一個(gè)固定窗口內(nèi)打來 max 次請求,此時(shí)在一個(gè)隨機(jī)的窗口時(shí)間內(nèi)最多會(huì)有 2 * max - 1 次請求。

另外還有一個(gè)redis的 INCREXPIRE 的原子性問題,容易造成 Race Condition,可以通過 SETNX 來解決

redis.set(key, 0, "EX", option.window, "NX")

另外也可以通過一個(gè) LUA 腳本來搞定,顯然還是 SETNX 簡單些

local current
current = redis.call("incr",KEYS[1])
if tonumber(current) == 1 then
    redis.call("expire",KEYS[1],1)
end

為了解決 2N 的問題,可以由維護(hù)一個(gè)計(jì)數(shù)器,更改為維護(hù)一個(gè)隊(duì)列。代價(jià)是內(nèi)存占用空間過高,且更難解決 Race Condition

以下是使用 redis 的 set/get string 實(shí)現(xiàn)的限流

const option = {
  max: 10,        // window 時(shí)間內(nèi)限速10個(gè)請求
  window: 1000    // 1s
}

function access(req) {
  // 根據(jù)請求生成唯一標(biāo)志
  const key = identity(req)
  const current = Date.now()
  // cache 視為緩存對象
  // 篩選出當(dāng)前時(shí)間窗口的請求個(gè)數(shù),每個(gè)請求標(biāo)志為時(shí)間戳的格式
  // 為了簡單這里不做 json 的序列化和反序列化了...
  const timestamps = [current].concat(redis.get("timestamps")).filter(ts => ts + option.window > current)
  if (timestamps.length > option.max) {
    return false 
  }
  // 此時(shí)讀寫不同步,會(huì)有 Race Condition 問題
  redis.set("timestamps", timestamps, "EX", option.window)
  return true
}

這里再使用一個(gè) LUA 腳本解決 Race Condition 的問題

TODO

Token Bucket (令牌桶算法)

由圖先看一看令牌桶與漏桶的不同

令牌桶初始狀態(tài) bucket 是滿的,漏桶初始狀態(tài) bucket 是空的

令牌桶在 bucket 空的時(shí)候拒絕新的請求,漏桶在 bucket 滿的時(shí)候拒絕新的請求

當(dāng)一個(gè)請求來臨時(shí),假設(shè)一個(gè)請求消耗一個(gè)token,令牌桶的 bucket 減少一個(gè) token,漏桶增加一個(gè) token

以下使用 redis 實(shí)現(xiàn)令牌桶

TODO

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/104139.html

相關(guān)文章

  • 接口限流的常用算法匯總

    摘要:接口限流的常用算法計(jì)數(shù)器法計(jì)數(shù)器法是限流算法里最簡單也是最容易實(shí)現(xiàn)的一種算法。由此可見,當(dāng)滑動(dòng)窗口的格子劃分的越多,那么滑動(dòng)窗口的滾動(dòng)就越平滑,限流的統(tǒng)計(jì)就會(huì)越精確。漏桶算法漏桶算法,又稱。 接口限流 什么是接口限流 那么什么是限流呢?顧名思義,限流就是限制流量,包括并發(fā)的流量和一定時(shí)間內(nèi)的總流量,就像你寬帶包了1個(gè)G的流量,用完了就沒了,所以控制你的使用頻率和單次使用的總消耗。通過限...

    gyl_coder 評論0 收藏0
  • 限流器及Guava實(shí)現(xiàn)分析

    摘要:計(jì)數(shù)限流算法無論固定窗口還是滑動(dòng)窗口核心均是對請求進(jìn)行計(jì)數(shù),區(qū)別僅僅在于對于計(jì)數(shù)時(shí)間區(qū)間的處理。令牌桶限流實(shí)現(xiàn)原理令牌桶限流的實(shí)現(xiàn)原理在有詳細(xì)說明。因此由此為入口進(jìn)行分析。目前可返回的實(shí)現(xiàn)子類包括及兩種,具體不同下文詳細(xì)分析。 限流 限流一詞常用于計(jì)算機(jī)網(wǎng)絡(luò)之中,定義如下: In computer networks, rate limiting is used to control t...

    xcc3641 評論0 收藏0
  • 幾種限流技術(shù)

    摘要:下面是幾種常見的限流技術(shù)一限流算法常用的限流算法有令牌桶,漏桶令牌桶令牌桶算法是網(wǎng)絡(luò)流量整形和速率限制中最常使用的一種算法。 就秒殺接口來說,當(dāng)訪問頻率或者并發(fā)請求超過其承受范圍的時(shí)候,這時(shí)候我們就要考慮限流來保證接口的可用性,以防止非預(yù)期的請求對系統(tǒng)壓力過大而引起的系統(tǒng)癱瘓。通常的策略就是拒絕多余的訪問,或者讓多余的訪問排隊(duì)等待服務(wù)。下面是幾種常見的限流技術(shù) 一、限流算法常用的限流算...

    Warren 評論0 收藏0
  • 接口限流算法:算法&令牌算法

    摘要:令牌桶算法漏桶算法漏桶漏桶的出水速度是恒定的,那么意味著如果瞬時(shí)大流量的話,將有大部分請求被丟棄掉也就是所謂的溢出。 工作中對外提供的API 接口設(shè)計(jì)都要考慮限流,如果不考慮限流,會(huì)成系統(tǒng)的連鎖反應(yīng),輕者響應(yīng)緩慢,重者系統(tǒng)宕機(jī),整個(gè)業(yè)務(wù)線崩潰,如何應(yīng)對這種情況呢,我們可以對請求進(jìn)行引流或者直接拒絕等操作,保持系統(tǒng)的可用性和穩(wěn)定性,防止因流量暴增而導(dǎo)致的系統(tǒng)運(yùn)行緩慢或宕機(jī)。 在開發(fā)高并發(fā)...

    dendoink 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<