服務(wù)升降級之開關(guān)功能控制

首先講一下開關(guān)的由來,例如東京在6月18日做店慶促銷活動,在交易下單環(huán)節(jié),可能需要調(diào)用A、B、C三個接口來完成,但是其實A和B是必須的,C只是附加的功能(例如在下單的時候做一下推薦),可有可無,在平時系統(tǒng)沒有壓力,容量充足的情況下,調(diào)用下沒問題,但是在類似店慶之類的大促環(huán)節(jié),系統(tǒng)已經(jīng)滿負荷了,這時候其實完全可以不去調(diào)用C接口,怎么實現(xiàn)這個呢?改代碼?no,no,no,這樣太不敏捷,此時開關(guān)誕生了,開發(fā)人員只要簡單執(zhí)行一下命令或者點一下頁面,就可以關(guān)掉對于C接口的調(diào)用,在大促過去之后,再把開關(guān)恢復(fù)回去即可。

??????問題一:在單個java系統(tǒng)中如何實現(xiàn)開關(guān)功能

??????其實對于開關(guān)來說,對應(yīng)Java中的類型,很好映射,就是一個boolean值,在需要做開關(guān)操作的地方,調(diào)用這個屬性,判斷狀態(tài),然后走相應(yīng)的邏輯即可。這個類是一個單例,保證全局唯一(代碼就不寫了,單例模式一般是學(xué)習(xí)設(shè)計模式中最開始接觸的呵呵)。

??????問題二:單個java系統(tǒng)中,如何實現(xiàn)開關(guān)值變更的操作呢?

??????在單機系統(tǒng)中,改變開關(guān)的狀態(tài)很簡單(留一個口子,外部可以改變屬性的值,例如改為true或者false),這時候,可以是頁面來維護開關(guān),通過頁面的點擊類改變這個全局唯一的屬性,從而實現(xiàn)開關(guān)動作的觸發(fā)。

??????問題三:多個同構(gòu)java系統(tǒng),如何實現(xiàn)開關(guān)狀態(tài)的同步呢?

??????通過一和二的介紹,在單機情況下,開關(guān)的變更可以了,但是在多個同構(gòu)(這里的同構(gòu),值得是部署的同一套代碼,邏輯完全相同,類似Master和Slaver的模式)系統(tǒng)中,如何保持一致呢?單例模式,開關(guān)屬性是被加載到本地緩存,就是說java一直持有的對象,在FullGC的時候回收不走的那種。這個時候,如果要保持各個系統(tǒng)中開關(guān)屬性狀態(tài)的一致,就需要從第三方外部系統(tǒng)中加載這個數(shù)據(jù)。

??????什么系統(tǒng)能充當(dāng)?shù)谌酵獠肯到y(tǒng)呢?可以是一個數(shù)據(jù)庫訪問系統(tǒng),我們暫且稱之為MetaServer,開關(guān)的屬性防止在DB中,然后MetaServer提供頁面來修改數(shù)據(jù),同時提供接口讀取開關(guān)的數(shù)據(jù),在應(yīng)用啟動的時候,通過MetaServer來讀取數(shù)據(jù),加載到本地緩存中。這時候就有個問題,就是我通過MetaServer的頁面改變了值,各個應(yīng)用如何知道我改變了屬性呢?這個時候就需要通過一些辦法(辦法很多,可以是消息系統(tǒng),可以是zookeeper,可以是頁面觸發(fā))來清理一下開關(guān)屬性的緩存,讓緩存重新加載一下,從而實現(xiàn)最新的狀態(tài)獲取。

??????總體思路就是:metaServer維護開關(guān)數(shù)據(jù)–應(yīng)用讀取DB中的數(shù)據(jù)到本地緩存–DB中數(shù)據(jù)變更–觸發(fā)開關(guān)屬性緩存重新加載。

??????這個是不是有點復(fù)雜,有沒有更加簡單的辦法?當(dāng)然有了,之前淘寶開源了一個系統(tǒng)diamond(持久化配置管理系統(tǒng),http://code.taobao.org/p/diamond/wiki/index/),其實可以理解為“配置信息的偽推送服務(wù)”,例如我變更了一個開關(guān)的屬性,不再需要做清理緩存的事情,diamond幫你做掉了(原理很簡單,例如系統(tǒng)A訂閱了在diamond中的開關(guān)信息,這時候A會啟動一個線程,每隔一段時間來輪循diamond的服務(wù)端,看看開關(guān)屬性的數(shù)據(jù)有沒有變更,如果有變更,在diamond服務(wù)端來加載最新的數(shù)據(jù))。

??????總體思路是:在diamond中維護配置信息–系統(tǒng)訂閱開關(guān)屬性–系統(tǒng)輪循配置是否有變更,有變更直接就變掉了。

??????????問題四:開關(guān)設(shè)計的幾個坑

??????有時候,我們?yōu)榱朔奖?,沒有借助問題三種的MetaServer或者diamond的方式,就是留了一個HTTP的接口來觸發(fā)修改開關(guān)(多臺機器的話,可以寫批量腳本),這時候其實需要我們在apache或者nginx中,把這個URL的訪問禁止掉,防止惡意用戶在外部拼湊鏈接來進行開關(guān)的變動,這時候只能在服務(wù)器上通過linux的curl來觸發(fā)操作了。

??????還有一個,就是如果通過HTTP的形式來修改開關(guān)的屬性,有個是需要注意的,就是開關(guān)的執(zhí)行要冪等操作,這樣方便操作,避免出現(xiàn)集群中數(shù)據(jù)不一致的狀態(tài)(就是執(zhí)行開,開關(guān)就是開,不能第一次執(zhí)行是開,第二次執(zhí)行是關(guān))。

??????????問題五:開關(guān)組合情況下怎么搞?

??????上面的幾種情況,僅僅是執(zhí)行單個開關(guān),應(yīng)該比較簡單。但是我同時又A、B、C三個開關(guān),在不同的業(yè)務(wù)場景下,可能需要關(guān)閉A和B開關(guān),在另外一個場景下,可能需要關(guān)閉A和C開關(guān),這時候認為操作有可能會有遺漏或者疏忽,怎么搞呢?在單獨屬性開關(guān)的基礎(chǔ)上做封裝,例如A和B上面增加一層屬性,暫且叫“AB”,修改AB的值,對應(yīng)的系統(tǒng)修改A和B的值,這樣就避免人肉記住一些組合。

??????????問題六:如何實現(xiàn)自動升降級?

??????上面的情況,都是在提起可以預(yù)知的情況下,我們做一些人為的操作,這個能不能自動化?當(dāng)然可以,就是這一小節(jié)討論的自動升降級。

??????舉例子,現(xiàn)在東京和作的外部物流公司有多家,會調(diào)用它們的系統(tǒng)或者物流節(jié)點的狀態(tài),這個時候,物流公司系統(tǒng)是不穩(wěn)定的,如果掛了或者響應(yīng)時間慢了,對于自身的系統(tǒng)會影響比較大,比較理想的辦法是,在物流公司系統(tǒng)出現(xiàn)問題的時候,這塊邏輯自動降級處理,然后等物流公司系統(tǒng)好了之后,再把這部分邏輯自動升級,整個過程沒有人為參與,自動保持系統(tǒng)穩(wěn)定性。這里說一下總體思路:

??????第一步:搞一個計數(shù)器,記錄接口,暫定A的調(diào)用成功次數(shù)、失敗次數(shù)以及響應(yīng)時間;

??????第二步:將這些信息放入隊列中,同時設(shè)置閥值(例如RT超過5秒就降級,1秒就升級)以及閥值觸發(fā)改動的開關(guān);

??????第三部:異步啟動一個線程,掃描隊列,達到我們的條件,就觸發(fā)做變更(有個問題,就是加入業(yè)務(wù)降級了,這時候就沒有調(diào)用量,也就沒有了自動升級的條件了,怎么搞呢?這時候業(yè)務(wù)降級,并不是完全100%的停掉,可以預(yù)留一部分流量繼續(xù)調(diào)用A,把A調(diào)用的信息放入隊列中,根據(jù)這些信息,就能實現(xiàn)升級了);

??????總結(jié):

??????上面這些是在陸續(xù)的系統(tǒng)維護中嘗試或者看到的處理辦法,通過開關(guān)的方式,實現(xiàn)系統(tǒng)的升降級,從而更好的保護系統(tǒng)。這篇文章只是闡述了大體的思路,沒有涉及到具體的代碼,希望能夠達到拋磚引玉的作用。

轉(zhuǎn)載請注明原文出處:Harries Blog????服務(wù)升降級之開關(guān)功能控制

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1、通過CocoaPods安裝項目名稱項目信息 AFNetworking網(wǎng)絡(luò)請求組件 FMDB本地數(shù)據(jù)庫組件 SD...
    陽明AI閱讀 16,210評論 3 119
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,578評論 19 139
  • 想去看大千世界 褪去浮華 聆聽自然的耳語 我仰望著星空 那星是深藍浩瀚夜空里的一粒塵 渺小至極 伸手不見五指的夜色...
    布衣阿靖閱讀 270評論 0 1
  • 最近在給高二學(xué)生上哲學(xué)課講意識起源。講解這一目時特意把時間跨度拉大到整個人類發(fā)展史,這時會發(fā)現(xiàn)人類所有認識的...
    想飛翔的蝸牛閱讀 234評論 0 0
  • 5.9 說實話疼得七葷八素的時候看什麼都煩啊!誰到了抓著藥就往嘴裡塞的滋味也不好受!今天吃了一堆藥 喝了幾瓶子中藥...
    愛新覺羅新雪閱讀 199評論 0 0

友情鏈接更多精彩內(nèi)容