2018-12-14

細(xì)水長流 | 結(jié)合場景談服務(wù)發(fā)現(xiàn)和配置

原創(chuàng):?何煦

本文將圍繞“Where”力九,講述 Nacos 配置管理的三個(gè)典型的應(yīng)用場景:

數(shù)據(jù)庫連接信息

限流閾值和降級開關(guān)

流量的動(dòng)態(tài)調(diào)度


數(shù)據(jù)庫連接信息

曾經(jīng)有朋友跟我聊過一個(gè)問題,“業(yè)務(wù)飛速發(fā)展,團(tuán)隊(duì)越來越大尖阔,人員流動(dòng)也相對頻繁起來隙笆,怎么才能更好的保證數(shù)據(jù)的安全性吐限,不被泄露呢?”漂坏。他提到這樣一個(gè)場景,公司創(chuàng)立初期媒至,服務(wù)后端的代碼都是他一行一行碼出來的顶别,當(dāng)時(shí)只有他一個(gè)人,后端與數(shù)據(jù)庫的連接配置信息也就直接放置在項(xiàng)目的配置文件中拒啰。他使用的是 Spring Boot 框架驯绎,配置信息就是存放在? application.properties?中,使用 Spring 的 profile 屬性保證不同環(huán)境連接不同的數(shù)據(jù)庫谋旦。如下所示:

生產(chǎn)環(huán)境:application-prod.properties

spring.datasource.url=生產(chǎn)環(huán)境的數(shù)據(jù)庫連接地址

spring.datasource.username=生產(chǎn)環(huán)境的數(shù)據(jù)庫用戶賬號

spring.datasource.password=生產(chǎn)環(huán)境的數(shù)據(jù)庫用戶密碼

開發(fā)環(huán)境:application-dev.properties

spring.datasource.url=開發(fā)環(huán)境的數(shù)據(jù)庫連接地址

spring.datasource.username=開發(fā)環(huán)境的數(shù)據(jù)庫用戶賬號

spring.datasource.password=開發(fā)環(huán)境的數(shù)據(jù)庫用戶密碼

測試剩失、預(yù)發(fā)環(huán)境也是類似。這種將數(shù)據(jù)庫連接信息直接放置在配置文件中册着,跟著項(xiàng)目代碼一起通過 Git 管理拴孤,的確是有蠻大的數(shù)據(jù)泄露的風(fēng)險(xiǎn)。試想甲捏,一個(gè)新來不久的小伙伴演熟,他一當(dāng)要投入研發(fā)工作,有 Git Pull 代碼的權(quán)限之后司顿,代表他可能就擁有了直接操作線上數(shù)據(jù)庫的權(quán)限了芒粹。當(dāng)時(shí)的我給他建議可以通過以下幾個(gè)方面去降低數(shù)據(jù)風(fēng)險(xiǎn):

將數(shù)據(jù)庫連接信息等敏感配置從項(xiàng)目中剝離蚕冬;

數(shù)據(jù)庫增加 IP 白名單連接限制;

最小權(quán)限原則:每個(gè)賬號只配置所必需的權(quán)限是辕,避免刪表刪庫等高危操作囤热;

定期修改數(shù)據(jù)庫賬號、密碼获三。

回想起來旁蔼,我當(dāng)時(shí)給的建議并沒有完全解決他的問題,甚至還帶來了其他一些問題疙教。例如棺聊,上述的第一點(diǎn),“將敏感配置從項(xiàng)目剝離”贞谓,剝離出來的敏感配置存放到哪里限佩?怎么管理這些配置呢?也許裸弦,你會想到祟同,存放到應(yīng)用部署機(jī)器的環(huán)境變量或某個(gè)文件中。不理疙,一樣有風(fēng)險(xiǎn)晕城,說不定哪天開發(fā)同學(xué)必須得登錄上機(jī)器排查問題,就有泄露的風(fēng)險(xiǎn)窖贤,總之砖顷,得盡可能地做到在整個(gè)開發(fā)流程都不會有任何泄露的風(fēng)險(xiǎn)。應(yīng)用中可能不只是連接一個(gè)數(shù)據(jù)源赃梧,分庫分表的情況滤蝠,不同數(shù)據(jù)存儲(如 MySQL / Redis / Elasticsearch 等)的情況,還有授嘀,其他更多敏感配置項(xiàng)物咳,配置數(shù)據(jù)的增多會給管理帶來不便。

另外粤攒,“定期修改數(shù)據(jù)庫賬號所森、密碼”,修改后我能怎么方便快捷的下發(fā)到所有應(yīng)用程序中呢夯接?既然是敏感配置焕济,其變更也會帶來不少的風(fēng)險(xiǎn),我需要能先到小量的幾臺機(jī)器驗(yàn)證盔几,保證對業(yè)務(wù)無影響晴弃,我再全部下發(fā)到其他所有的機(jī)器上去,是否還得有“灰度發(fā)布”的功能呢?賬號密碼修改下發(fā)后上鞠,應(yīng)用出現(xiàn)異常际邻,影響到業(yè)務(wù)了,我要怎么快速地回滾呢芍阎?是否還得有“版本控制”世曾、“快速回滾”的功能呢?不是所有的開發(fā)同學(xué)都有權(quán)限能修改敏感配置信息谴咸,是否還需要有“權(quán)限管控”的功能轮听?對敏感配置的任何操作都應(yīng)該被記錄,是否還需要有“變更審計(jì)”的功能呢岭佳?

現(xiàn)在血巍,我有了更好的建議:使用 Nacos 配置管理模塊,將敏感配置信息都存放到 Nacos 中珊随。Nacos 配置管理述寡,其中一個(gè)立身之本就是為敏感配置保駕護(hù)航。它提供上述場景所需的功能叶洞,通過命名空間區(qū)分不同環(huán)境(開發(fā)鲫凶、測試、預(yù)發(fā)京办、生產(chǎn))掀序,通過“版本控制”保證變更可追溯,通過“快速回滾”保證錯(cuò)誤變更時(shí)影響最小惭婿,通過的“灰度發(fā)布”功能保障配置安全平穩(wěn)地變更,還有更多更全面功能(權(quán)限管控叶雹、變更審計(jì)等)即將支持财饥。

那么,怎么將敏感配置項(xiàng)目的配置文件中遷移到 Nacos 中呢折晦?下面以 Spring Boot 連接 MySQL 為例:

1. 添加依賴

<dependency>

? ?<groupId>com.alibaba.boot</groupId>

? ?<artifactId>nacos-config-spring-boot-starter</artifactId>

? ?<version>${latest.version}</version>

</dependency>

注意 Spring Boot 1.x 使用? nacos-config-spring-boot-starter 0.1.x 版本钥星,Spring Boot 2.x 使用 nacos-config-spring-boot-starter 0.2.x 版本。

2. 在application.properties ?中添加 Nacos 連接配置

nacos.config.server-addr=127.0.0.1:8848

這里是簡單的示例满着,在實(shí)際生產(chǎn)中谦炒,還需配置 Nacos 命名空間信息(區(qū)分環(huán)境)、鑒權(quán)信息(如 AccessKey风喇、SecretKey 等宁改,即將支持的權(quán)限訪問控制)。而 Nacos 配置模塊對應(yīng)的阿里云產(chǎn)品 ACM魂莫,借助于 ECS 實(shí)例 RAM 角色还蹲,最終能到達(dá)連 AccessKey、SecretKey 都不需要填寫的目的。

3. 添加 @NacosPropertySource 注解

@SpringBootApplication

@NacosPropertySource(dataId = "mysql.properties")

public class SpringBootMySQLApplication {

? ? public static void main(String[] args) {

? ? ? ? SpringApplication.run(Application.class, args);

? ? }

}

4. 在本地啟動(dòng)的 Nacos 控制臺上新增 dataId 為?mysql.properties?的配置谜喊,配置內(nèi)容為 MySQL 連接配置信息:

通過這四個(gè)簡單的步驟潭兽,就將 MySQL 連接信息從原來的 application.properties 遷移到 Nacos 的,讓 Nacos 將敏感配置管控起來斗遏,大大降低數(shù)據(jù)泄露的風(fēng)險(xiǎn)山卦。同時(shí),Nacos 配置管理提供的“統(tǒng)一管控”诵次、“版本控制”怒坯、“快速回滾”等強(qiáng)大的功能也為其運(yùn)維管理帶來極大的便利。

完整示例代碼請參看:https://github.com/nacos-group/nacos-examples/tree/master/nacos-spring-boot-example/nacos-spring-boot-config-mysql-example

限流閾值和降級開關(guān)

限流藻懒、降級剔猿,眾所周知,是在開發(fā)高并發(fā)系統(tǒng)過程中需要考慮的兩大關(guān)鍵點(diǎn)嬉荆,是運(yùn)行時(shí)保護(hù)系統(tǒng)的兩大利器归敬。限流閾值和降級開關(guān),最終是抽象為一個(gè)個(gè)的配置項(xiàng)鄙早,要想實(shí)現(xiàn)運(yùn)行時(shí)的動(dòng)態(tài)調(diào)整閾值和開關(guān)的啟停汪茧,將這些配置項(xiàng)存放到 Nacos 的配置模塊中最適合不過了。

在今年 8 月的時(shí)候限番,阿里巴巴開源了 Sentinel舱污,以流量為切入點(diǎn),從流量控制弥虐、熔斷降級扩灯、系統(tǒng)負(fù)載保護(hù)等多個(gè)維度保護(hù)服務(wù)的穩(wěn)定性。在阿里巴巴內(nèi)部霜瘪,Nacos 跟 Sentinel 就是多年攜手相伴珠插,砥礪前行的好機(jī)油,為雙 11 等各種大促立下了功勞颖对,也為剁手黨提供了良好的購物體驗(yàn)捻撑。

下面就以 Sentinel 流控為例,演示如果通過 Nacos 來做到運(yùn)行時(shí)的動(dòng)態(tài)控制流量:

1. 添加依賴

? <dependency>

? ? <groupId>com.alibaba.csp</groupId>

? ? <artifactId>sentinel-core</artifactId>

? ? <version>${latest.version}</version>

</dependency>

<dependency>

? ? <groupId>com.alibaba.csp</groupId>

? ? <artifactId>sentinel-datasource-extension</artifactId>

? ? <version>${latest.version}</version>

</dependency>

<dependency>

? ? <groupId>com.alibaba.csp</groupId>

? ? <artifactId>sentinel-datasource-nacos</artifactId>

? ? <version>${latest.version}</version>

</dependency>

<dependency>

? ? <groupId>com.alibaba</groupId>

? ? <artifactId>fastjson</artifactId>

? ? <version>${latest.version}</version>

</dependency>

2. 模擬并發(fā)請求

final class RunTask implements Runnable {

? ? @Override

? ? public void run() {

? ? ? ? while (!stop) {

? ? ? ? ? ? Entry entry = null;

? ? ? ? ? ? try {

? ? ? ? ? ? ? ? entry = SphU.entry(resourceName);

? ? ? ? ? ? ? ? // token acquired, means pass

? ? ? ? ? ? ? ? pass.addAndGet(1);

? ? ? ? ? ? } catch (BlockException e1) {

? ? ? ? ? ? ? ? block.incrementAndGet();

? ? ? ? ? ? } catch (Exception e2) {

? ? ? ? ? ? ? ? // biz exception

? ? ? ? ? ? } finally {

? ? ? ? ? ? ? ? total.incrementAndGet();

? ? ? ? ? ? ? ? if (entry != null) {

? ? ? ? ? ? ? ? ? ? entry.exit();

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? ? ? Random random2 = new Random();

? ? ? ? ? ? try {

? ? ? ? ? ? ? ? TimeUnit.MILLISECONDS.sleep(random2.nextInt(50));

? ? ? ? ? ? } catch (InterruptedException e) {

? ? ? ? ? ? ? ? // ignore

? ? ? ? ? ? }

? ? ? ? }

? ? }

}

3. 配置 Nacos 連接信息與 dataId 等缤底,并將其設(shè)置為 Sentinel 的數(shù)據(jù)源

public class NacosDynamicFlowDemo {

? ? private static final String KEY = "TestResource";

? ? public static void main(String[] args) {

? ? final String remoteAddress = "localhost";

? ? ? ? final String groupId = "DEFAULT_GROUP";

? ? ? ? final String dataId = "com.alibaba.nacos.demo.flow.rule";

? ? ? ? ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new NacosDataSource<>(remoteAddress, groupId, dataId,

? ? ? ? ? ? source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {}));

? ? ? ? FlowRuleManager.register2Property(flowRuleDataSource.getProperty());


? ? ? ? // Assume we config: resource is `TestResource`, initial QPS threshold is 5.

? ? ? ? FlowQpsRunner runner = new FlowQpsRunner(KEY, 1, 10000);

? ? ? ? runner.simulateTraffic();

? ? ? ? runner.tick();

? ? }

}

4. 在本地啟動(dòng)的 Nacos 控制臺中新建 dataId 為com.alibaba.nacos.demo.flow.rule?的流控配置

5. 運(yùn)行NacosDynamicFlowDemo顾患,你會看到如下標(biāo)準(zhǔn)輸出信息

6. 再到 Nacos 控制臺修改剛剛新建的流控配置,將限流閾值count 的值修改為1.0个唧,完整的標(biāo)準(zhǔn)輸出信息如下:

以上示例演示了如何通過 Nacos + Sentinel 實(shí)現(xiàn)動(dòng)態(tài)流量控制的能力江解,核心就是用到了 Nacos 配置模塊“動(dòng)態(tài)推送”的能力。原理是?sentinel-datasource-nacos?集成了?nacos-client?坑鱼,其與?nacos-server?維持著連接膘流,當(dāng)用戶在 Nacos 控制臺進(jìn)行配置變更時(shí)絮缅,nacos-server?會快速地將該配置的最新內(nèi)容推送到?nacos-client?中,Sentinel 一拿到最新的流控配置呼股,就轉(zhuǎn)換了流控策略耕魄,如示例將流控閾值調(diào)整為 1.0,限制為更少的流量進(jìn)入系統(tǒng)的業(yè)務(wù)處理流程彭谁。

完整示例代碼請參看:https://github.com/nacos-group/nacos-examples/tree/master/nacos-sentinel-example

流量的動(dòng)態(tài)調(diào)度

業(yè)務(wù)發(fā)展壯大到一定的規(guī)模吸奴,單一的集群已經(jīng)承載不了全部的用戶請求,需要將用戶的流量分流到不同的集群上缠局。當(dāng)然则奥,更進(jìn)一步的方案是:不同的集群位于不同的區(qū)域,這樣狭园,除了緩解業(yè)務(wù)處理的壓力读处,也給系統(tǒng)帶來容災(zāi)的能力。

比如唱矛,某電商系統(tǒng)有 1 億用戶量罚舱,將系統(tǒng)的流量按照用戶的 ID 進(jìn)行切分,ID 為 1-1000W 的用戶請求分發(fā)到區(qū)域 A 的集群 a 上绎谦,ID 為 10001W-2000W 的用戶請求流量分發(fā)到區(qū)域 B 的集群 b 上管闷,以此類推,最終將所有用戶的請求流量打散到 10 個(gè)不同區(qū)域的集群上窃肠,同時(shí)包个,每個(gè)集群冗余了一些系統(tǒng)資源。當(dāng)區(qū)域 A 的機(jī)房發(fā)生不可抗的災(zāi)難(如地震)時(shí)冤留,我們需要有動(dòng)態(tài)調(diào)度流量的能力碧囊,最好能秒級得將流量從區(qū)域 A 調(diào)度到另外可用的區(qū)域的集群上。

這正是 Nacos 配置管理大有作為的地方搀菩,將用戶 ID 的分片和對應(yīng)的路由規(guī)則存放在 Nacos 的中呕臂,配合統(tǒng)一接入層等的組件,就能將流量打散到各個(gè)集群上肪跋,進(jìn)而讓系統(tǒng)能承載更大的流量,以更好的支撐業(yè)務(wù)的發(fā)展土砂。另外州既,將其存放與 Nacos 中,也就具備了配置“動(dòng)態(tài)化”的能力萝映,一旦某區(qū)域出現(xiàn)基礎(chǔ)設(shè)施無法及時(shí)恢復(fù)的問題時(shí)吴叶,只需在 Nacos 的控制臺上修改 ID 分片的路由規(guī)則,就能將有問題的區(qū)域流量快速切換到其他可用的區(qū)域上序臂,保障對業(yè)務(wù)幾乎無損蚌卤。Nacos 在阿里內(nèi)部能做到秒級推送到十萬級別機(jī)器上的推送效率实束。

總結(jié)

除了以上三個(gè)場景,其實(shí)還有更多更大膽的應(yīng)用場景逊彭,如“大數(shù)據(jù)實(shí)時(shí)計(jì)算算法調(diào)整”咸灿、“異地容災(zāi)多活”、“應(yīng)用業(yè)務(wù)場景動(dòng)態(tài)推送”等等侮叮,可以參看 Nacos 的阿里云產(chǎn)品 ACM 的使用場景 避矢。Nacos 配置管理模塊,將敏感配置收攏管控起來囊榜,極大降低數(shù)據(jù)泄露等風(fēng)險(xiǎn)审胸,并且提供如“動(dòng)態(tài)推送”、“版本控制”卸勺、“快速回滾”等功能砂沛,保障了敏感配置的變更安全平穩(wěn)的執(zhí)行。

在限流與降級的場景曙求,通過一個(gè)示例碍庵,為大家演示了如何通過 Nacos + Sentinel 實(shí)現(xiàn)流量的動(dòng)態(tài)控制,這也是 Nacos 配置管理的一個(gè)十分典型的應(yīng)用場景圆到。降級也一樣怎抛,大促高峰期間將某個(gè)非關(guān)鍵的系統(tǒng)組件進(jìn)行關(guān)閉,在過了高峰期后再開啟芽淡,這個(gè)也是可以通過 Nacos 的“動(dòng)態(tài)推送”的功能來實(shí)現(xiàn)马绝。

總之,只要系統(tǒng)涉及到了“敏感的配置”挣菲、“動(dòng)態(tài)的配置”富稻,都應(yīng)該考慮將配置放入到 Nacos 中,讓 Nacos 管控起來白胀。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末椭赋,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子或杠,更是在濱河造成了極大的恐慌哪怔,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,222評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件向抢,死亡現(xiàn)場離奇詭異认境,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)挟鸠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,455評論 3 385
  • 文/潘曉璐 我一進(jìn)店門叉信,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人艘希,你說我怎么就攤上這事硼身」杓保” “怎么了?”我有些...
    開封第一講書人閱讀 157,720評論 0 348
  • 文/不壞的土叔 我叫張陵佳遂,是天一觀的道長营袜。 經(jīng)常有香客問我,道長讶迁,這世上最難降的妖魔是什么连茧? 我笑而不...
    開封第一講書人閱讀 56,568評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮巍糯,結(jié)果婚禮上啸驯,老公的妹妹穿的比我還像新娘。我一直安慰自己祟峦,他們只是感情好罚斗,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,696評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著宅楞,像睡著了一般针姿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上厌衙,一...
    開封第一講書人閱讀 49,879評論 1 290
  • 那天距淫,我揣著相機(jī)與錄音,去河邊找鬼婶希。 笑死榕暇,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的喻杈。 我是一名探鬼主播彤枢,決...
    沈念sama閱讀 39,028評論 3 409
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼筒饰!你這毒婦竟也來了缴啡?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,773評論 0 268
  • 序言:老撾萬榮一對情侶失蹤瓷们,失蹤者是張志新(化名)和其女友劉穎业栅,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體谬晕,經(jīng)...
    沈念sama閱讀 44,220評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡式镐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,550評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了固蚤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,697評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡歹茶,死狀恐怖夕玩,靈堂內(nèi)的尸體忽然破棺而出你弦,到底是詐尸還是另有隱情,我是刑警寧澤燎孟,帶...
    沈念sama閱讀 34,360評論 4 332
  • 正文 年R本政府宣布禽作,位于F島的核電站,受9級特大地震影響揩页,放射性物質(zhì)發(fā)生泄漏旷偿。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,002評論 3 315
  • 文/蒙蒙 一爆侣、第九天 我趴在偏房一處隱蔽的房頂上張望萍程。 院中可真熱鬧,春花似錦兔仰、人聲如沸茫负。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,782評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽忍法。三九已至,卻和暖如春榕吼,著一層夾襖步出監(jiān)牢的瞬間饿序,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,010評論 1 266
  • 我被黑心中介騙來泰國打工羹蚣, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留原探,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,433評論 2 360
  • 正文 我出身青樓度宦,卻偏偏與公主長得像踢匣,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子戈抄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,587評論 2 350

推薦閱讀更多精彩內(nèi)容