本文系投稿,作者:廖春濤(春少)
https://www.yuque.com/docs/share/17664885-e0d8-40fd-a208-f1b58794d544
經過一年多發展,1.2.0版本已經從安全上解決上生產的最后疑慮,解決用戶主要訴求。
經過社區討論,從1.3.0版本開始修煉內功,聚焦“簡單”、“性能”、“高可用”這核心的三個點進一步提升Nacos核心競爭力。今天很高興能代表社區向大家介紹1.3.0的核心特性
-
內嵌關系型分布式數據庫,簡化集群部署模式
-
集群管理下沉統一,提供全新集群管理能力
-
一致性協議抽象升級,提供更高的性能
-
安全升級,解決Fastjson和越權風險
下面我們逐個介紹一下這些能力
輕量級的內嵌關系型分布式數據庫
為什么只是用服務發現模塊也要我部署MySQL?MySQL集群搭建的成本有多高?不能把集群部署簡單一點,像Consul、Etcd那樣子?
這不,為了解決這個問題,Nacos 1.3.0 借鑒了 Etcd 的通過Raft協議將單機KV存儲轉變為分布式的KV存儲的設計思想,基於SOFA-JRaft以及Apache Derby構建了一個輕量級的分布式關系型數據庫,同時保留了使用外置數據源的能力,用戶可以根據自己的實際業務情況選擇其中一種數據存儲方案。
從Nacos 1.3.0版本開始集群部署可以不依賴MySQL的這個特性,不僅降低中小用戶的集群運維部署成本,也簡化了其集群部署的操作以及省去了部署一套數據庫集群的操作。
新特性的開啟命令為
./startup.sh -p embedded
然后查看啟動日志是否有出現以下信息:Nacos started successfully in cluster mode. use embedded storage
同時,為了方便用戶查詢本機節點的數據同步情況,Nacos 1.3.0 配置模塊開放了新的運維 Open-API,供其查詢當前節點本地數據存儲情況,並且該Open-API只能執行select語句,其他DML語句一概不支持,其使用方式如下
GET /nacos/v1/cs/ops/derby?sql=select * from config_info
使用該命令時,最好加上分頁查詢,避免一次查處大量的數據影響Nacos的正常對外業務工作,如果沒有加上分頁查詢,則會自動添加分頁查詢語句,默認查詢最開始的1k條數據。其分頁查詢的SQL的例子如下。
select * from config_info OFFSET 0 ROWS FETCH NEXT 1000 ROWS ONLY
其數據返回結果如下
{ "code":200, "message":null, "data":\\\[ { "ID":242149783664332800, "DATA\\\_ID":"application.properties", "GROUP\\\_ID":"DEFAULT\\\_GROUP", "TENANT\\\_ID":"", "APP\\\_NAME":"", "CONTENT":"this.is.test=liaochuntao", "MD5":"bedbfd7069e999edf2adf9d8a1af3083", "GMT\\\_CREATE":"2020-06-03T05:30:47.345+0000", "GMT\\\_MODIFIED":"2020-06-03T05:30:47.345+0000", "SRC\\\_USER":null, "SRC\\\_IP":"127.0.0.1", "C\\\_DESC":null, "C\\\_USE":null, "EFFECT":null, "TYPE":"properties", "C\\\_SCHEMA":null } \\\]}
Nacos 1.3.0 構建的輕量級的分布式關系型存儲,其已滿足事務ACID性質。后面我們會在這基礎之上進一步優化該存儲的性能。
注意事項
分布式ID——Snowflake
Nacos 1.3.0的分布式存儲,其數據的主鍵依賴雪花ID算法進行生成,雪花算法ID需要_DataCenterId_、_WorkerId,默認情況下,WorkerId不需要進行設置,會根據InetAddress.getLocalHost()進行計算生成。如果需要自己指定,則在application.properties進行如下配置設置
# set the dataCenterID manuallynacos.core.snowflake.data-center=Number### set the WorkerID manuallynacos.core.snowflake.worker-id=Number
數據遷移
由於Nacos 1.3.0新增的內嵌存儲模式是全新的數據存儲模式,因此在進行Nacos-Server升級時,如果是需要使用這種新能力,需要另外部署一個Nacos 1.3.0集群,然后進行數據遷移,由於Nacos 1.3.0 新增的內嵌存儲模式,還無法自動的將原本MySQL的數據直接一鍵進行數據遷移,因此用戶只能使用控制台的數據導出導入的方式進行(會丟失配置歷史數據),更加完備的數據遷移功能會在后面的版本進行開放。
全新的集群管理
提供全新集群管理頁面
Nacos 1.3.0版本開始,對集群節點管理進行了統一,將原有配置模塊以及服務模塊的集群節點管理統一下沉到內核模塊,並且優化了集群節點信息展示,使得其更貼近Nacos集群節點的數據信息展示,其顯示的內容包括如下幾個方面
-
服務發現模塊舊的Raft協議的元數據數據
-
配置管理模塊使用新Raft協議的元數據
-
Nacos節點自身的元數據信息
-
新Raft協議的RPC端口
-
節點的版本信息
-
節點的權重信息(該權重的功能暫未提供,以后服務端節點的負載均衡使用)
-
節點元數據信息上次刷新時間
新的集群尋址模式設置
Nacos 1.3.0版本開始,對集群節點的尋址模式做了統一,將原本分散的節點尋址模式整合並抽象,方便將來可以擴寬Nacos的集群發現機制,用戶可以通過如下設置自己選擇需要使用哪一種尋址模式作為集群節點的管理
文件尋址模式
nacos.core.member.lookup.type=file(默認值)
地址服務尋址模式
nacos.core.member.lookup.type=address-server
全新的一致性協議
Nacos 1.3.0版本開始,將對現有的一致性協議層進行統一抽象以及下沉。在Raft的選型上,使用了SOFA-JRaf作為CP協議的Backend,並且將其與配置管理模塊進行了對接。用戶可以通過調整下面的參數對Raft協議進行調整。
# Sets the Raft cluster election timeout, default value is 5 second# 設置Raft群集選舉超時,默認值為5秒nacos.core.protocol.raft.data.election\\\_timeout\\\_ms=5000# Sets the amount of time the Raft snapshot will execute periodically, default is 30 minute# 設置Raft快照定期執行的時間,默認值為30分鍾nacos.core.protocol.raft.data.snapshot\\\_interval\\\_secs=30# Raft internal worker threads# Raft 內部工作線程數量nacos.core.protocol.raft.data.core\\\_thread\\\_num=8# Number of threads required for raft business request processing# Raft 業務請求處理所需的線程數nacos.core.protocol.raft.data.cli\\\_service\\\_thread\\\_num=4# raft 線性讀取策略,默認為ReadOnlySafe,可以選擇ReadOnlyLeaseBasednacos.core.protocol.raft.data.read\\\_index\\\_type=ReadOnlySafe### rpc請求超時,默認5秒nacos.core.protocol.raft.data.rpc\\\_request\\\_timeout\\\_ms=5000
線性讀參數解析
-
ReadOnlySafe
-
該線性讀模式,每次Follower進行讀請求時,需要和Leader同步日志提交位點信息,而Leader,需要向過半的Follower發起證明自己是Leader的輕量的RPC請求,相當於一個Follower讀,至少需要1 + (n/2)+ 1 次的RPC請求。
-
ReadOnlyLeaseBased
-
該線性讀模式,每次Follower進行讀請求時,Leader只需要判斷自己的Leader租約是否過期了,如果沒有過期,直接可以回復Follower自己是Leader,但是該機制對於機器時鍾要求很嚴格,如果有做時鍾同步的話,可以考慮使用該線性讀模式。
如果說對於配置的發布、修改操作比較頻繁,可以將Raft快照的時間適當的進行調整,避免新節點加入或者節點重啟時,由於Raft日志回放操作數太多導致節點可開始對外服務的時間過長。
JRaft
同時,為了方便運維對新的Raft協議能夠進行一些簡單的運維操作,Nacos 1.3.0 內核模塊開放了相關一致性協議運維的 Open-API,供其對Raft進行一些運維操作,其相關的運維操作如下
切換某一個Raft Group的Leader節點
POST /nacos/v1/core/ops/raft{ "groupId": "xxx", "command": "transferLeader" "value": "ip:{raft\\\_port} or ip:{raft\\\_port},ip:{raft\\\_port},ip:{raft\\\_port}"}
重置某一個Raft Group的集群成員
POST /nacos/v1/core/ops/raft{ "groupId": "xxx", "command": "resetRaftCluster", "value": "ip:{raft\\\_port},ip:{raft\\\_port},ip:{raft\\\_port},ip:{raft\\\_port}"}
注意,該操作是一個高危操作,僅僅當Raft集群的 n/2 + 1節點crash之后無法滿足過半投票的要求才可以使用該運維命令,用於快速讓當前剩余的節點重組Raft集群,對外提供服務,但是這個操作很大程度會造成數據的丟失
觸發某一個Raft Group執行快照操作
POST /nacos/v1/core/ops/raft{ "groupId": "xxx", "command": "doSnapshot", "value": "ip:{raft_port}"}
移除某一個Raft Group中的某一成員
POST /nacos/v1/core/ops/raft{ "groupId": "xxx", "command": "removePeer", "value": "ip:{raft_port}"}
批量移除某一個Raft Group中的多個成員
POST /nacos/v1/core/ops/raft{ "groupId": "xxx", "command": "removePeers", "value": "ip:{raft\\\_port},ip:{raft\\\_port},ip:{raft_port},..."}
后續
目前一致性協議層只是將CP協議具體實現了,后面會再將AP協議——Distro下沉到一致性協議層中,並且調整Distro的實現,其協議內部的通信將使用gRPC,以配合Nacos對於整個通信通道的規划。同時真正實現對整個一致性協議使用方式的收攏。
安全升級
-
修復fastjson安全漏洞
-
修復tenant越權漏洞
貢獻者
Nacos 1.3.0 版本的開發中,社區同學貢獻了很大的力量,在此表示感謝,他們是(排序不分先后):@KomachiSion @zongtanghu @wangweizZZ @Maijh97 @jintonghuoya @jzdayz @yfh0918@wolfgangzhu @ObserverYu @langghaha @jiangcaijun @wfnuser @TsingLiang @showkawa @yanlinly @chuntaojun
關注公眾號Java技術棧回復"面試"獲取我整理的2020最全面試題及答案。
推薦去我的博客閱讀更多:
2.Spring MVC、Spring Boot、Spring Cloud 系列教程
3.Maven、Git、Eclipse、Intellij IDEA 系列工具教程
覺得不錯,別忘了點贊+轉發哦!