Nacos 1.0.1是GA之後的第一個版本,除了修複1.0.0一些bug以外,還在社群回報的基礎上,吸收了大量的社群共建PR。這個版本中除了原有的貢獻者外,新增了13名社群的貢獻者,總計合入了43個PR。這一次,社群一起定義Nacos。或許你覺得Nacos很多槽點,或許你覺得Nacos應該支援某些牛逼的功能,此時請不要隐藏你的才華,貢獻你在Nacos的第一PR吧。
Nacos 1.0.1主要新增特性介紹
服務發現SDK新增服務的運維接口
@chuntaojun
Nacos的服務模式是由服務-叢集-執行個體組成的三層模型,和以往的Eureka、Consul等注冊中心有所差別,這樣雖然增加了對更多場景的支援,但是目前隻能通過控制台去操作服務和叢集的配置,包括建立、更新和删除服務。為了能讓使用者更加友善的使用Nacos的資料模型,我們在1.0.1版本支援了SDK側的服務的編輯操作,包含的接口可以參考代碼NamingMaintainService:
這個類的使用方法也很簡單,與NamingService的使用類似,如下:
NamingMaintainService namingMaintainService = NamingMaintainFactory.createMaintainService(serverAddr);
Service preService = new Service();
preService.setName(serviceName);
preService.setGroupName(Constants.DEFAULT_GROUP);
preService.setProtectThreshold(1.0f);
Map<String, String> metadata = new HashMap<String, String>();
metadata.put(serviceName, "this is a register metadata");
preService.setMetadata(metadata);
ExpressionSelector selector = new ExpressionSelector();
selector.setExpression("CONSUMER.label.A=PROVIDER.label.A &CONSUMER.label.B=PROVIDER.label.B");
System.out.println("service info : " + preService);
namingMaintainService.createService(preService, selector);
更多詳細的用法,可以參考
代碼。
健康檢查插件
@xcxcxcxcx
1.0.0版本及以前Nacos支援mysql、tcp、http三種健康檢查方式,并且允許關閉健康檢查。
為了友善使用者使用多樣化的健康檢查方式,例如使用者可能使用了Spring Cloud元件來建構微服務應用,想要對接Spring Cloud Actuator健康檢查endpoint,那麼就需要給Nacos健康檢查做出自定義的實作,在1.0.1版本新增了插件式的可擴充的健康檢查。
功能介紹:基于SPI機制,使用者通過實作特定的接口和繼承特定的抽象類來建構使用者自定義的健康檢查插件,并通過jvm指令引入插件包,此時Nacos啟動後,使用者可以在前端頁面看到使用者自定義的健康檢查選項,友善靈活的定制化Nacos健康檢查方式。
擴充流程:
- 建立一個maven工程,并引入依賴
//Please correspond to the version currently in use
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-naming</artifactId>
<version>${nacos.version}</version>
</dependency>
- 繼承AbstractHealthChecker抽象類,構造自定義心跳實體類,getType()方法傳回的是自定義心跳的類型名,必須全局唯一
- 實作HealthCheckProcessor接口,構造自定義心跳處理器類,getType()方法傳回的是自定義心跳的類型名,必須全局唯一,且需要與上一步驟的心跳實體類的type相同。
- 使用指令
将maven工程打包為jar,并将jar移至%NACOS_HOME%/plugins/health路徑下,%NACOS_HOME%表示下載下傳的nacos根路徑mvn clean package
- 啟動Nacos,插件自動生效,Nacos提供的運作腳本中已将%NACOS_HOME%/plugins/health中的插件包加入到JVM運作環境
驗證和使用:
- 檢視目前生效的健康檢查實體類
- 請求接口:/v1/ns/health/checkers
- 請求類型:GET
- 請求參數樣例:[空]
- 傳回值樣例:{"TCP":{"type":"tcp"}, "HTTP":{"type":"http", "path":"xxxx"},"TEST":{"type":"test"}}
- 給服務指定健康檢查類型
- 請求接口:/v1/ns/cluster
- 請求類型:PUT
- 請求參數樣例:serviceName=DEFAULT_GROUP%40%40appName&clusterName=DEFAULT&metadata=&checkPort=80&useInstancePort4Check=true&healthChecker=%7B%22type%22%3A%22TCP%22%7D&namespaceId=3767dfeb-ec5f-4611-97bb-ee530d19ef89
- 傳回值樣例:ok
這裡的例子表示給組名DEFAULT_GROUP中的服務名為appName的cluster為DEFAULT的應用執行個體們指定健康檢查類型為HTTP,檢查端口為80,并且心跳實體類的JSON為{"type":"HTTP","path":"1","headers":"2"}
詳細流程及更多注意事項請參考demo工程:
nacos-health-plugin-example控制台叢集狀态顯示
@universefeeler
在叢集機器比較多的時候,不友善通過Log來确定目前叢集各節點的狀态,通過控制可以檢視目前叢集所有節點狀态,可由此判斷服務運作情況。隻需打開控制台,點選左側欄 叢集管理->節點清單 就可以看到目前叢集所處的狀态,示例圖如下:
服務發現控制台示例代碼
@yongchao9
Nacos 支援幾乎所有主流類型的“服務”的發現、配置和管理,服務提供者使用 原生SDK、OpenAPI注冊 Service 後,服務消費者可以使用HTTP&API查找和發現服務。為了能讓使用者更加友善的使用,我們在Nacos1.0.1版本中新增了服務使用示例代碼,支援在服務清單控制台中直接進行檢視,能夠讓新手快速使,大幅降低新手使用門檻。目前,我們提供基于Java、Spring、Spring Boot、Spring Cloud的使用示例代碼,後期我們将逐漸完善其餘使用場景示例代碼。如下圖所示:
曆史配置保留天數可配置
@rushsky518
曆史配置檔案保留天數預設是 30 天,現在可以通過 nacos.config.retention.days 參數進行設定,調整保留的天數。
Config用戶端重連機制優化
Nacos Config子產品通過一個長輪詢任務
LongPollingRunnable
不斷向 Config Server詢問自己感興趣的配置是否更新,無論本次任務執行成功還是出現異常,都是直接再次放回Executor中再次執行;是以如果當 Config Server 出現無法服務時,會導緻
LongPollingRunnable
列印大量的錯誤日志。
為了改善 Config 用戶端與 Config Server 出現連接配接異常時的大量錯誤日志列印以及頻繁的請求重試,我們在1.0.1版本對 Config 用戶端重連機制做了兩方面的優化,第一個優化是當任務
LongPollingRunnable
在執行時出現異常,将對任務采取延遲執行的懲罰政策,推遲該任務的下一次被排程執行的時間,主要邏輯代碼如下
class LongPollingRunnable implements Runnable {
private int taskId;
public LongPollingRunnable(int taskId) {
this.taskId = taskId;
}
@Override
public void run() {
List<CacheData> cacheDatas = new ArrayList<CacheData>();
List<String> inInitializingCacheList = new ArrayList<String>();
try {
...
// check server config
List<String> changedGroupKeys = checkUpdateDataIds(cacheDatas, inInitializingCacheList);
...
inInitializingCacheList.clear();
executorService.execute(this);
} catch (Throwable e) {
// If the rotation training task is abnormal, the next execution time of the task will be punished
LOGGER.error("longPolling error : ", e);
executorService.schedule(this, taskPenaltyTime, TimeUnit.MILLISECONDS);
}
}
}
第二個優化是
ServerHttpAgent
中執行 Http 請求的重試機制優化,在1.0.1版本中,加入了 Config Server 位址清單輪訓次數的限制;在1.0.1版本之前,認為 Http 請求遇到
ConnectException
或者
SocketTimeoutException
時,應在 timeout 時間内進行重試;但是可能會導緻一個問題,如果 Config Server 不可用(當機或者無法響應用戶端請求),會導緻在 timeout 時間内Config用戶端因為重試發送大量的請求給 Config Server,但是這些請求其實都是無法成功的;是以為了避免此情況,加入了 Config Server 輪訓次數限制,如果對 Config Server 位址清單輪訓次數達到
maxRetry
,則預設請求失敗,抛出異常,主要邏輯代碼如下
@Override
public HttpResult httpPost(String path, List<String> headers, List<String> paramValues, String encoding, long readTimeoutMs) throws IOException {
final long endTime = System.currentTimeMillis() + readTimeoutMs;
boolean isSSL = false;
String currentServerAddr = serverListMgr.getCurrentServerAddr();
int maxRetry = this.maxRetry;
do {
try {
List<String> newHeaders = getSpasHeaders(paramValues);
if (headers != null) {
newHeaders.addAll(headers);
}
...
} else {
// Update the currently available server addr
serverListMgr.updateCurrentServerAddr(currentServerAddr);
return result;
}
} catch (ConnectException ce) {
LOGGER.error("[NACOS ConnectException httpPost] currentServerAddr: {}", currentServerAddr);
} catch (SocketTimeoutException stoe) {
LOGGER.error("[NACOS SocketTimeoutException httpPost] currentServerAddr: {}, err : {}", currentServerAddr, stoe.getMessage());
} catch (IOException ioe) {
LOGGER.error("[NACOS IOException httpPost] currentServerAddr: " + currentServerAddr, ioe);
throw ioe;
}
if (serverListMgr.getIterator().hasNext()) {
currentServerAddr = serverListMgr.getIterator().next();
} else {
maxRetry --;
if (maxRetry < 0) {
throw new ConnectException("[NACOS HTTP-POST] The maximum number of tolerable server reconnection errors has been reached");
}
serverListMgr.refreshCurrentServerAddr();
}
} while (System.currentTimeMillis() <= endTime);
...
}
同時,為了友善使用者,以上優化點涉及的幾個參數:
taskPenaltyTime
——任務懲罰執行時間、
timeout
——請求逾時時間、
maxRetry
——最大重試次數,都可以有使用者自行設定,配置的方法很簡單,代碼如下
Properties properties = new Properties();
properties.put(PropertyKeyConst.SERVER_ADDR, "127.0.0.1:" + port);
// 設定長輪詢請求逾時時間(最小為10s)
properties.put(PropertyKeyConst.CONFIG_LONG_POLL_TIMEOUT, "20000");
// 設定任務懲罰時間
properties.put(PropertyKeyConst.CONFIG_RETRY_TIME, 3000);
// 設定最大重試次數
properties.put(PropertyKeyConst.MAX_RETRY, 5);
configService = NacosFactory.createConfigService(properties);
具體的優化效果可以參考
如何共建
為了實作這一目标,你需要積極參與Nacos社群。如果您在文檔中發現拼寫錯誤,在代碼中發現錯誤,或想要新功能或想要提供建議,您可以
在GitHub上建立一個issues如果您想開始着手,可以選擇github倉庫中有以下标簽的issues。
- good first issue :對于新手來說是非常好的入門issues。
- contribution welcome :非常需要解決的問題和非常重要的子產品,但目前缺少貢獻者,歡迎貢獻者來貢獻。
蓬勃發展的 Nacos 社群
DISS is cheap, show me your hand
比吐槽更重要的是搭把手,參與社群一起發展Nacos
- 作為使用者關注和加入 Nacos 社群
Nacos 社群正在蓬勃發展,截止到發文為止,Nacos 已經有 9 個微信群,其中 7 個已滿員,1個QQ群,1個釘釘群,關注 Nacos 的社群人數已經近5000人,在 Nacos 群裡跟 “道(基)友” 切磋技術,交流經驗,招聘交友,搶搶紅包...不亦樂乎。
- 作為代碼貢獻者加入 Nacos 社群
為了能夠與代碼貢獻者更友善的交流,我們組建了釘釘群“Nacos社群核心貢獻小組(23335652)”,這個群裡都是都是對Nacos貢獻非常感興趣的小夥伴,如果你也想成為Nacos貢獻者,甚至成為Committer,歡迎加入這個群和群裡的小夥伴一起切磋!
在Nacos官網
nacos.io中,已經添加
團隊介紹頁,裡面包括Nacos的開發者角色定義及職責劃分,同時包含了Naocs的開發者們介紹和靓照哦,歡迎大家加入Nacos社群,貢獻社群。用Apache的話說,“社群高于代碼”!
新人時刻 - "什麼是Nacos?"
還不知道什麼是Nacos? 沒關系,在github上star一下跟程式猿兄弟打個招呼吧!!Nacos
是阿裡巴巴于2018年7月份新開源的項目,Nacos的主要願景是期望通過提供易用的
動态服務發現
、
服務配置管理
服務共享與管理
的基礎設施,幫助使用者在雲原生時代更好的建構、傳遞、管理自己的微服務平台。
github項目位址在
這裡