Alibaba-技術專區-開源項目之Nacos功能特性


一、背景

  先來說說大背景,現在,很明顯的一個趨勢就是:微服務。

  這個趨勢的底層驅動力就來源於分布式系統的普及,而微服務的各個特性是如今大大小小的企業無法拒絕的誘惑。

  然后,用上了微服務的架構風格,用Spring Cloud,或者Dubbo搭了一套腳手架,就開始干起來了。

  接下來,一眾小公司畫完了大餅之后,發現自己根本吃不下。這就是典型的落后勞動力與先進生產力的尖銳矛盾。這個時候,返璞歸真的想法是不能有了,重構代價太大。

  當然,哪里有問題,哪里就有商機。各大XX雲廠商經過一系列包裝之后,用“雲原生(Cloud Native)”的新概念粉墨登場

  Spring Cloud Alibaba就是其中之一。

  這個概念的一個核心價值就是:平滑上雲,賦能運維。最明顯的業務表象就是,會提供一套Open API,甚至是貼心的提供一個可視化控制台,傻瓜式的那種。

二、從NACOS說起

  NACOS解決兩個核心問題:動態配置管理,服務注冊發現。

  兼容性方面,除了支持自家的Dubbo,還對Spring Cloud,Kubernetes,Istio有所兼容

  至此,不說道說道Eureka,都有點過意不去了。

  我用下來的體驗是:NACOS完全可以替代Eureka了。

  江山代有才人出,這是必然的結果。

  在“雲原生”的大背景之下,NACOS順利成章的推出了Console,將觸角進一步延伸至服務的精細化管理。

  當然,不排除Eureka也在憋大招。

  再說說動態配置的特性。

  當然,NACOS略勝一籌,可替代Spring Cloud Config了。

  原先在Git/SVN上托管的配置項,都可以在Console上統一管理了。

  如果想先睹為快,可以接下着往下讀。如果想再多了解一些,可以直接跳過這部分,閱讀下一個小節。

  可以把NACOS理解成是一個中心化的服務,這在阿里系的架構中屢見不鮮。所以,必須得先啟動這個服務。

  有兩個辦法:其一是直接clone源碼,使用maven打包。第二個辦法是直接下載GitHub release出來的壓縮包。

推薦后者。

方法1:主要運行以下命令:

git clone https://github.com/alibaba/nacos.git cd nacos/ mvn -Prelease-nacos clean install -U

  經過一段時間的構建過程,在./distribution/target目錄下有我們想要的壓縮包。

方法2:進入https://github.com/alibaba/nacos/releases,找到壓縮包,下載。

為了演示,我們先用單機模式啟動。

Windows環境下:

startup.cmd -m standalone

一切就緒的話,訪問http://127.0.0.1:8848/nacos/index.html,使用nacos/nacos登錄。

接下來,隨便逛逛。
圖片描述

三、重要的概念

  為了避免在Console中迷失自我,有必要先闡述幾個重要的概念。
圖片描述

  這張圖很重要。表述了namespace、group和service/dataId的包含關系。

  NACOS給的最佳實踐表明,最外層的namespace是可以用於區分部署環境的,比如test,uat,product等。同時,也有一個商業利用價值:多租戶。以namespace為單位,給用戶開辟使用空間。

  其它兩個領域模型不用多解釋了,見名知意。其目的也非常明顯,就是為了能夠邏輯上區分兩個目標對象。

默認情況下,namespace=public,group=DEFAULT_GROUP。

  明白了這個數據模型后,可以稍微玩轉一下Console了,比如新建若干個namespace:

  namespace順利創建成功后,會在每個一級頁面看到由namespace組成的TAB,可以任意切換namespace,對其下的數據進行操作。比如下圖的配置列表:圖片描述

  當然,還有眾多的領域模型,但是跟這一講的關系不大了,下一講深入源碼的時候再進行剖析。接下來會創建一個Demo工程,用於構建基於NACOS的config server和discovery server。

  在進行下一章節之前,強烈建議先創建一個Spring Boot樣板工程,可以不做任何配置,不添加任何一段代碼。

  當然,為了讓這一講的內容更具實戰意義,我不會照搬官網的Demo,本文所作的Demo工程也可以從GitHub上克隆得到。請提前准備好,接下來的內容只會挑重點講解,側重點不會在如何搭建工程。

四、使用NACOS的搭建工程

工程名稱為:nacos-example,在各個pom.xml文件中相關依賴管理就不再贅述了。

現在來介紹一下,這個demo工程干了一件什么事:用戶在下單的時候,需要校驗用戶的狀態,商品是否上架以及購買的數量上限。

為了體現動態配置,用戶狀態和購買的數量上限做成配置項。而這兩者的配置在不同的namespace下是有所不同的。

為了體現服務間的調用,下單入口在order模塊,經由user模塊進行校驗。
圖片描述

根據上述,NACOS服務啟動好了后,我們分別創建dev,product兩個namespace,在寫spring boot配置的時候,填寫的不是test,product這些namespace名稱,而是ID,此ID會在namespace成功創建后,由系統自動分配,目前的生成規則就是隨機的UUID函數。

這樣的配置規則會存在很大的爭議,本文不做討論。

user模塊需要動態配置,所以可以看作是一個config client。又因為需要接受order模塊的調用,所以也是一個service provider。

同樣的,order模塊需要動態配置,所以也是一個config client。

至此,讀者會發現一些NACOS帶來的“弊病”,最顯現的問題就是“多重角色”帶來的侵入性。因為是中心化的架構,如果沒有做到很好的解耦,出現這個問題也不足為奇了。

特別是在遠程調用的角色分配上,NACOS嚴格遵從了“生產者-消費者”模型,在實際業務場景下,難免會有服務既是生產者,又是消費者,而Eureka是沒有這種區分的。

接下來把目光轉向配置。

阿里系的開源產品大多建議是用properties文件,由於個人習慣,我使用的是yml,達到的效果是一樣的。

值得注意的是,因為需要更高優先級的加載順序,所以配置文件必須使用bootstrap.yml。

user模塊的配置文件,區分了環境,為了增加辨識度,也定義了group進行隔離。如下:

server:  port: 8100 spring:  application:  name: user  cloud:  nacos:  config:  server-addr: 127.0.0.1:8848  file-extension: yaml  namespace: 7d3e5f19-a102-471a-b6e0-67bd7d1d35f3  group: USER_GROUP  discovery:  server-addr: 127.0.0.1:8848  namespace: 7d3e5f19-a102-471a-b6e0-67bd7d1d35f3 --- spring:  profiles: prod  cloud:  nacos:  config:  server-addr: 11.162.196.16:8848  namespace: c4c81555-91e1-4ef5-8b57-77c5407b3481  discovery:  server-addr: 11.162.196.16:8848  namespace: c4c81555-91e1-4ef5-8b57-77c5407b3481 --- spring:  profiles:  active: dev

  order模塊的配置文件類似,不再贅述。

  然后對自定義配置參數進行封裝。如果只有單個參數,可以不用JavaBean的形式,但是絕大多數情況下都是多參數配置的,本文給出了JavaBean形式的封裝。

user模塊使用到的配置參數:

import lombok.Getter; import lombok.Setter; import org.springframework.boot.context.properties.ConfigurationProperties; @Getter @Setter @ConfigurationProperties(prefix = "user") public class UserConfig { /** * 用戶狀態:enable-啟用,disable-禁用 */ private String status;
}

  order模塊使用到的配置參數:

import lombok.Getter; import lombok.Setter; import org.springframework.boot.context.properties.ConfigurationProperties; @Getter @Setter @ConfigurationProperties(prefix = "order") public class OrderConfig { /** * 最大購買數量 */ private int maxNum = Integer.MAX_VALUE; /** * 是否上架 */ private boolean onSale = true; }

  然后就是編寫功能實現代碼,主要入口在order模塊中的OrderController:

@RefreshScope @RestController @RequestMapping public class OrderController { @Autowired private OrderConfig config; @Autowired private UserRpcService userRpcService; @PostMapping(value = "/order") public String placeOrder(@RequestParam(name = "num", defaultValue = "1") Integer num) { if (!"enable".equals(userRpcService.getUserStatus())) 
      return "該用戶已被禁用,暫不能下單"; if (num <= 0) return "購買數量有誤"; if (!config.isOnSale()) return "商品未上架"; if (num > config.getMaxNum()) return "購買數量超限"; return "OK"; } }

  一些列的下單校驗,第一個校驗是判斷用戶狀態,使用了基於Feign的遠程調用。當然,必須在user模塊中提供對應的Controller實現:

@RefreshScope @RestController @RequestMapping(value = "/user") public class UserController { @Autowired private UserConfig config; @GetMapping(value = "/status") public String getUserStatus() { return config.getStatus(); } }

  Controller中的@RefreshScope注解就是用來實現配置自動更新的。

  整個工程准備就緒之后,先別急着run,還需要在Console中添加配置,用以測試動態配置是否生效。

  添加配置的過程不再贅述,需要注意的是Data Id的填寫規范。dataId的完整格式由三部分組成:

  ${prefix}-${spring.profile.active}.${file-extension}

    prefix,默認使用${spring.application.name},也可以通過spring.cloud.nacos.config.prefix來配置。

   spring.profile.active,即為當前環境對應的 profile,詳情可以參考 Spring Boot文檔。 注意:當 spring.profile.active 為空時,對應的連接符 - 也將不存在,dataId 的拼接格式變成 ${prefix}.${file-extension}

  file-exetension,為配置內容的數據格式,可以通過配置項 spring.cloud.nacos.config.file-extension 來配置。目前只支持 properties 和 yaml 類型。
圖片描述

接下來就是分別啟動order和user兩個模塊,隨便玩玩。

五、其他功能簡介

NACOS會記錄配置文件的歷史版本,保留30天,同時還貼心的提供了一鍵回滾功能,回滾操作將會觸發配置更新。
圖片描述

    NACOS提供了配置監聽的Open-API。注冊監聽采用的是異步 Servlet 技術。注冊監聽本質就是帶着配置和配置值的 MD5 值和后台對比。如果 MD5 值不一致,就立即返回不一致的配置。如果值一致,就等待一定時間段,返回空值。

   最后就是優雅上/下線功能,算是NACOS的一大亮點。在每個服務詳情里面,可以有多個實例(instance),通過Console可以控制每個實例的上/下線。如果是重新上線的話,會有一段時間的注冊過程,並不是點擊“上線”按鈕之后就能立馬訪問到該實例。  

六、NACOS的進階功能

如果決定要將NACOS大規模投產,上述功能還遠遠滿足不了條件。在這一章節,將會講解若干個進階功能,為你的NACOS服務保駕護航。

1、集群模式

只啟動一個NACOS服務實例未免有些勢單力薄了,前述內容都是在單機部署的前提下,這一小節教你如何部署一個NACOS集群。

找到conf/cluster.conf文件,如果沒有,就新建。編輯里面的內容,僅需指定機器的ip和port,最好是3個或者3個以上。如果沒有這么多機器資源,可以直接在一台機器上部署,區分端口號即可。如下:

# ip:port 192.168.0.88:8848 192.168.0.88:8849 192.168.0.88:8840

請注意,在集群模式下就不能用127.0.0.1或者localhost了,當前版本對於網卡解析存在bug。

這個問題是因為Nacos獲取本機IP時,沒有獲取到正確的外部IP,需要保證InetAddress.getLocalHost().getHostAddress()或者hostname -i的結果是與cluster.conf里配置的IP是一致的。

找到conf/application.properties,如果沒有,說明有問題。編輯里面的內容,主要目的是啟用MySQL作為存儲層(目前僅支持MySQL)。在該文件末尾追加:

spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=123456

然后新建一個名為nacos的數據庫,運行conf/nacos-mysql.sql腳本文件。

以上,就是運行NACOS集群模式所需的配置內容。

因為要在一台機器上模擬多個NACOS服務,可以將配置好的工程復制出兩份,然后在conf/application.properties中修改端口號即可。
圖片描述

然后,分別在三個命令窗口啟動NACOS:

startup -m cluster

分別使用對應的端口號訪問Console,如果能順利打開,說明部署成功了。

最后,在上述搭建的demo工程中,修改server-addr的值,把其他NACOS訪問地址也加上去:

server: port: 8200 spring: application: name: order cloud: nacos: config: server-addr: 192.168.0.88:8848,192.168.0.88:8849,192.168.0.88:8840 file-extension: yaml namespace: 7d3e5f19-a102-471a-b6e0-67bd7d1d35f3 group: ORDER_GROUP discovery: server-addr: 192.168.0.88:8848,192.168.0.88:8849,192.168.0.88:8840 namespace: 7d3e5f19-a102-471a-b6e0-67bd7d1d35f3

2、安全措施

很遺憾,NACOS的官網並沒有就安全性進行詳細的介紹。唯一看到的accessKey和secretKey兩項疑似安全的配置項,卻是為了配合阿里雲的ACM而設立的。

讓我最為關注的配置文件加密功能也暫未release出來,以下是官方原話:

Nacos計划在1.X版本提供加密的能力,目前還不支持加密,只能靠sdk做好了加密再存到nacos中。
NACOS Console的安全性同樣很糟糕,密碼無法修改,用戶不能創建,也沒有角色、權限的概念。

NACOS的服務注冊與發現基於HttpURLConnection進行遠程調用,這個地方是提供了HTTPS的啟用開關,JVM參數名是:com.alibaba.nacos.client.naming.tls.enable。

除此之外,目前只能在NACOS的外圍做一些安全措施了。

3、一些有用的配置

nacos.home,這個是NACOS服務的啟動參數,以JVM參數的形式傳入。但是很遺憾,使用這個參數並不是很方便,需要修改啟動腳本,大概是在startup.sh文件中的104行:

JAVA_OPT="${JAVA_OPT} -Dnacos.home=${BASE_DIR}"

更為徹底的方法是修改BASE_DIR的值(默認為startup.sh文件的父目錄),大概在startup.sh文件中的71行:

export BASE_DIR=`cd $(dirname $0)/..; pwd`

nacos.logging.path,日志是一個系統運行最寶貴的附加產物,有的時候為了便於管理,需要自定義日志目錄。如果需要指定,同樣需要修改startup.sh腳本。大概在104行后追加一行:

JAVA_OPT="${JAVA_OPT} -Dnacos.logging.path=指定的目錄"

當然,日志級別也能指定,分別通過com.alibaba.nacos.naming.log.level和com.alibaba.nacos.config.log.level這兩個JVM參數指定。

不過,還需要特別說明一下,並非所有日志都是有價值的,可以根據實際情況進行刪減,否則會對服務器造成不必要的負擔,相關日志配置可以在conf/nacos-logback.xml文件中修改。

4、endpoint

在上述配置文件中所涉及的serverAddr參數是窮舉了所有可用的NACOS服務,在大規模應用場景下,這種配置方式顯然是不合理的。endpoint相當於一個DNS服務,可以代理所有NACOS服務,只需要指定一個訪問域名。

這篇文章是對endpoint的一個最佳實踐,並且給出了環境隔離的有效手段。

七、總結

本文是對Spring Cloud Alibaba Nacos的功能性介紹。

如果研發能力強勁的隊伍,可以現在嘗嘗這只“螃蟹”,順帶還能貢獻不少的PR。

個人建議先觀望一段時間,大概在v1.2.0版本之后,就可以逐漸引入到公司的技術棧內了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM