摘要: Nacos 是阿里巴巴今年7月份開源的項目,如其名, Naming Configuration Service ,專一於服務發現和配置管理領域。本系列文章,將從 5W1H(What、Where、When、Who、Why、How)全面剖析 Nacos,給你們安利一下 Nacos。spring
Nacos 是阿里巴巴今年7月份開源的項目,如其名, Naming Configuration Service ,專一於服務發現和配置管理領域。本系列文章,將從 5W1H(What、Where、When、Who、Why、How)全面剖析 Nacos,給你們安利一下 Nacos。本文做爲 Nacos 系列文章的開篇,也就從 「What」 開始。咱們開始關注一個開源項目的時候,一般最早冒出的 2 個問題是:數據庫
它是什麼?
它幫咱們解決什麼問題?
Nacos 是什麼?上面已經大概介紹了,更多詳細內容能夠從 官網 或 Github 瞭解。app
Nacos 能幫咱們解決什麼問題?本文圍繞其「配置管理」功能來解答。運維
配置,做爲代碼如影隨形的小夥伴,伴隨着應用的整個生命週期,咱們固然對它也很是的熟悉,想一想配置通常都經過哪幾種形式存在?this
硬編碼
配置文件
DB 配置表
硬編碼
配置項做爲類字段的形式存在,如:阿里雲
public class AppConfig {編碼
private int connectTimeoutInMills = 5000; public int getConnectTimeoutInMills() { return connectTimeoutInMills; } public void setConnectTimeoutInMills(int connectTimeoutInMills) { this.connectTimeoutInMills = connectTimeoutInMills; }
}
這種形式主要有三個問題:加密
若是配置是須要動態修改的話,須要當前應用去暴露管理該配置項的接口,至因而 Controller 的 API 接口,仍是 JMX ,都是能夠作到。code
另外,配置變動都是發生在內存中,並無持久化。所以,在修改配置以後重啓應用,配置又會變回代碼中的默認值了,這是一個坑啊,筆者就曾經掉進去過,爬了好一會才上岸。server
最後一個問題,就是當你有多臺機器的時候,要修改一個配置,每一臺都得去操做一遍,運維成本可想而知,極其蛋疼。
配置文件
Spring 中常見的 properties、yml 文件,或其餘自定義的,如,「conf」後綴等:
connectTimeoutInMills=5000
相比「硬編碼」的形式,它解決了第二個問題,持久化了配置。可是,另外兩個問題並無解決,運維成本依舊仍是很高的。
配置動態變動,能夠是經過相似「硬編碼」暴露管理接口的方式,這時,代碼中會多一步持久化新配置到文件的邏輯。或者,簡單粗暴點,直接登陸機器上去修改配置文件,再重啓應用,讓配置生效。固然,你也能夠在代碼中增長一個定時任務,如每隔 10s 讀取配置文件內容,讓最新的配置可以及時在應用中生效,這樣也就免去了重啓應用這個「較重」的運維操做。
經過增長「持久化邏輯」、「定時任務」讓「配置文件」的形式比「硬編碼」前進了一小步。
DB 配置表
這裏的 DB 能夠是 MySQL 等的關係型數據庫,也能夠是 Redis 等的非關係型數據庫。數據表如:
CREATE TABLE config
(id
bigint(20) unsigned NOT NULL AUTO_INCREMENT,key
varchar(50) NOT NULL DEFAULT '' COMMENT '配置項',value
varchar(50) NOT NULL DEFAULT '' COMMENT '配置內容',updated_time
timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,created_time
timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id
),
UNIQUE KEY idx_key
(key
)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='配置信息';
INSERT INTO config
(key
, value
, updated_time
, created_time
) VALUES ('connectTimeoutInMills', '5000', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
它相對於前二者,更進一步,將配置從應用中抽離出來,集中管理,能較大的下降運維成本。
那麼,它能怎麼解決動態更新配置的問題呢?據我所知,有兩種方式。
其一,如同以前同樣,經過暴露管理接口去解決,固然,也同樣得增長持久化的邏輯,只不過,以前是寫文件,如今是將最新配置寫入數據庫。不過,程序中還須要有定時從數據庫讀取最新配置的任務,這樣,才能作到只需調用其中一臺機器的管理配置接口,就能把最新的配置下發到整個應用集羣全部的機器上,真正達到下降運維成本的目的。
其二,直接修改數據庫,程序中經過定時任務從數據庫讀取最新的配置內容。
「DB 配置表」的形式解決了主要的問題,可是它不夠優雅,帶來了一些「累贅」。
Nacos 配置管理
Nacos 真正將配置從應用中剝離出來,統一管理,優雅的解決了配置的動態變動、持久化、運維成本等問題。
應用自身既不須要去添加管理配置接口,也不須要本身去實現配置的持久化,更不須要引入「定時任務」以便下降運維成本。Nacos 提供的配置管理功能,將配置相關的全部邏輯都收攏,而且提供簡單易用的 SDK,讓應用的配置能夠很是方便被 Nacos 管理起來。
若是是在 Spring 中使用 Nacos,只需三個步驟便可:
添加依賴
<dependency>
<groupId>com.alibaba.nacos</groupId> <artifactId>nacos-spring-context</artifactId> <version>${latest.version}</version>
</dependency>
添加 @EnableNacosConfig 註解啓用 Nacos Spring 的配置管理服務。如下示例中,咱們使用 @NacosPropertySource 加載了 dataId 爲 example 的配置源,並開啓自動更新:
@Configuration
@EnableNacosConfig(globalProperties = @NacosProperties(serverAddr = "127.0.0.1:8848"))
@NacosPropertySource(dataId = "example", autoRefreshed = true)
public class NacosConfiguration {
}
經過 Spring 的 @Value 註解設置屬性值。
注意:須要同時有 Setter方法才能在配置變動的時候自動更新。
public class AppConfig {
@Value("${connectTimeoutInMills:5000}") private int connectTimeoutInMills; public int getConnectTimeoutInMills() { return connectTimeoutInMills; } public void setConnectTimeoutInMills(int connectTimeoutInMills) { this.connectTimeoutInMills = connectTimeoutInMills; }
}
以上的三個步驟,對應用自己幾乎沒有任何的侵入,1 個依賴 2 註解,寥寥數行,就把配置經過 Nacos 管理起來了。
關於配置的動態更新,對 Nacos Spring 的用戶來講,在自身應用中就只是設置 「autoRefreshed」 的一個布爾值。而後在須要修改配置的時候,調用 Nacos 修改配置的接口,或使用 Nacos 的控制檯去修改,配置發生變動後, Nacos 就會把最新的配置推送到該應用的全部機器上,簡單而高效。
想一想以前,爲了實現此功能,寫了多少冤枉代碼,作了多少冤枉的運維工做。要是早一點認識 Nacos,該有多好呀!
總結
本文做爲 Nacos 5W1H 系列文章的開篇,從「What」 講述了 Nacos 配置管理能幫咱們解決的問題:以簡單、優雅、高效的方式管理配置,實現配置的動態變動,大大下降運維成本,讓開發同窗早點下班。
固然,Nacos 的配置管理,不僅僅只有上述的那些功能,還有諸如「灰度發佈」、「版本管理」、「快速回滾」、「監聽查詢」、「推送軌跡」、「權限控制」、「敏感配置(如,數據庫鏈接配置)的加密存儲」等等,這些有的已經在 Nacos 中開源實現了,有的在 Nacos 配置管理的阿里雲免費產品 ACM 中提供了,固然,後續也會慢慢開源到 Nacos 中,敬請期待。