Nginx+KV db進行AB灰度測試
之前聽過淘寶用nginx的一些場景,其中AB的灰度測試可能適用場景會比較普遍,當(dāng)然大會上,并沒有詳細討論實現(xiàn)。
大概需求是: 網(wǎng)站類業(yè)務(wù)在更新new feature時,并不想讓全量用戶看到,可以針對地區(qū)性用戶開放此feature。大概構(gòu)思了一個方式,使用 nginx+redis/memcache+IP庫實現(xiàn),簡單的流程圖如下:

當(dāng)然其中的new feature server和normal server不必要一定得是物理上的服務(wù)器,可以是任意邏輯上分開的服務(wù)和http URI
所用的模塊是 ngx-lua-module, 以及一個基于ngx-lua寫的lib: lua-resty-memcached或lua-resty-redis, 這里假設(shè)使用memcached作為ip數(shù)據(jù)的存儲,cache內(nèi)保存以ip作為key,以true(1)或false(0)作為value的數(shù)據(jù),nginx在請求到來時,從cache內(nèi)以remote_addr(如果是用XFF頭,則對XFF做一次處理后獲取到real ip)作為key從cache內(nèi)做一次get,判斷此req應(yīng)該的轉(zhuǎn)發(fā);
這里有一個問題是:cache內(nèi)是保存具體的IP形式的方式,還是以CIDR的超網(wǎng)形勢存儲,若直接使用IP作為key,數(shù)據(jù)量不容小視,而且IP信息的準(zhǔn)確度得有一定的保證才行;若使用CIDR的方式,則在nginx端又會增加一次IP轉(zhuǎn)換CIDR以及對get到的CIDR做比較(具體實現(xiàn)方法還沒想到), 復(fù)雜度會有所增加,個人偏向直接使用IP作為key,只要保證了IP的一定準(zhǔn)確性,數(shù)據(jù)大小問題不大,現(xiàn)在遍地都是32G,64G內(nèi)存的緩存。
若使用ip作為key,一個折中的辦法是每次進行ABtest的時候,flush緩存,只保存指定地區(qū)的ip數(shù)據(jù)即可,ngx在做get的時候,如果沒有返回,則認為此req是到normal server的.
管理平臺方面,只需要做個簡單的批量set緩存的功能就可以了,至于UI么,就看你給誰用了,自己用嘛,UI丑陋點就丑陋點了
性能和可用性方面:
增加了一次緩存的連接和get操作,理論上此開銷應(yīng)該是很小的,ngx-lua實現(xiàn)的lua-resty-memcached有不少人做過測試,性能非??捎^.
可用性方面會增加一個當(dāng)緩存斷線的風(fēng)險點,通過settimeout,將緩存超時限制到一個較小的時間,影響較小,另外ABtest的方案也不應(yīng)該常年累月的在線上,只有在有需求時,才需要這套系統(tǒng)吧,因此可用性方面對全局影響應(yīng)該是較小的,相比新的feature上線時影響全部用戶的風(fēng)險,這個冒險還是值得的。
上述暫時只是個人的思路,而且也還沒上線使用,實現(xiàn)方面只完成了nginx獲取key來判斷req轉(zhuǎn)發(fā)的驗證,針對此方式也未做過詳細壓力測試,拋磚引玉,有好的方式歡迎討論.
原文地址:Nginx+KV db進行AB灰度測試



























