聊一聊和Nacos 2.0.0对接那些事
前言
nacos 2.0.0 已經(jīng)發(fā)布了 alpha1, alpha2 和 beta 三個版本了,部分測試報告也已經(jīng)出來了。
Nacos2.0.0-ALPHA2 服務(wù)發(fā)現(xiàn)性能測試報告
Nacos 2.0.0-ALPHA2 配置性能測試報告
還是比較值得期待的。
前段時間也一直在完善 nacos-sdk-csharp 這個項目。
主要就是對接 Nacos 2.0.0 這一塊,也考慮到之前主要是針對Open API封裝,同時參考JAVA的SDK進行功能疊加。
這一次就索性全部重新來過了,也對齊 JAVA SDK 提供的方法。
這其中最為重要的應(yīng)該是底層協(xié)議由 HTTP 換成 gRPC,也是長輪詢到長連接的一個跨越。
現(xiàn)在就和大家簡單梳理一下老黃在對接中認為要注意的地方。
這里以 nacos 2.0.0 beta 版本為準,后續(xù)版本可能會有變化。
端口
nacos 的默認端口是 8848,也是之前 HTTP 協(xié)議對接時的請求端口,那么我們是不是通過 8848 這個端口進行 gRPC 的交互呢?
答案是否定的!
nacos 里面做了一個約定,把 gRPC 的服務(wù)端口設(shè)置成 nacos 啟動的端口加 1000。
也就是說,nacos 的端口是 8848 的話,那么 gRPC 服務(wù)端口就是 9848
所以這里是第一個注意的點。
proto 文件
下面是 nacos 提供的 proto 文件,這個是SDK和Server交互的基礎(chǔ)。
syntax = "proto3";import "google/protobuf/any.proto"; import "google/protobuf/timestamp.proto";option java_multiple_files = true; option java_package = "com.alibaba.nacos.api.grpc.auto";message Metadata {string type = 3;map<string, string> headers = 7; }message Payload {Metadata metadata = 2;google.protobuf.Any body = 3; }service RequestStream {// build a streamRequestrpc requestStream (Payload) returns (stream Payload) {} }service Request {// Sends a commonRequestrpc request (Payload) returns (Payload) {} }service BiRequestStream {// Sends a commonRequestrpc requestBiStream (stream Payload) returns (stream Payload) {} }這里有 3 個 service,其中 RequestStream 這個在實際對接中是沒有使用到的。所以只介紹其他兩個。
Request 這個是通用請求,發(fā)布配置,注冊服務(wù)之類的請求都是通過這個方法來交互的。
BiRequestStream 這個是雙向流,主要是用來注冊連接,和一些監(jiān)聽回調(diào)。
Nacos 1.x 里面, 配置的監(jiān)聽回調(diào)是基于長輪詢機制,服務(wù)的監(jiān)聽回調(diào)是基于udp機制。
再來看看 service 的參數(shù)和響應(yīng)。
Payload 的設(shè)計是有兩個部分, 一個是自定義類型的 metadata, 一個是 Any 類型的 body。
metadata 里面有一個 type 字段,這個字段代表的是客戶端和服務(wù)端交互的 RPC 語義。好比說,我要發(fā)布配置,就是通過這個 type 告訴服務(wù)端,當前請求是要做什么。
body 這個在交互時需要做一下轉(zhuǎn)換,拿到一個 object 對象,序列化成一個 JSON 字符串,最后在轉(zhuǎn)化成 Any 類型的 value。
下面是一個簡單的示例:
var?body?=?new?Google.Protobuf.WellKnownTypes.Any {//?convert?the?request?paramter?to?a?json?string,?as?the?bodyValue?=?Google.Protobuf.ByteString.CopyFromUtf8(request.ToJsonString()) };這里有一個要注意的地方,在生成 C# 代碼后,會因為參數(shù)名和方法名一樣造成編譯不過,所以這里要修改一下生成代碼的參數(shù)名。
對接
知道了服務(wù)端的端口, proto 文件也有了,接下來就可以和服務(wù)端對接了。
想要和服務(wù)端對接上,成功獲取到正確的數(shù)據(jù),其實還有不少內(nèi)容的。
下面老黃拆成 3 個小節(jié)來說。
建立連接
Step 1:
與 gRPC 服務(wù)端進行交互,首先就是要創(chuàng)建一個 Channel ,這里用的是 Insecure 的方式,不需要提供額外的證書信息。
Step 2:
創(chuàng)建 Request 請求客戶端,并發(fā)起 ServerCheckRequest 請求,檢查服務(wù)是否可用,不可用就直接關(guān)閉這個 Channel 了。
Step 3:
創(chuàng)建 BiRequestStream 請求客戶端,注冊處理服務(wù)端推送的相關(guān)操作,主要是配置和服務(wù)的變更。
注冊完成后,還要發(fā)送 ConnectionSetupRequest 請求和 server 端建立真正意義上的連接。
這一步至關(guān)重要,因為這一步過后,服務(wù)端會把這個連接維護到客戶端的連接管理里面,后續(xù)的請求會通過這個來判斷是不是合法的請求。可以理解成拿到了大門的鑰匙。
這一步完成之后,就可以通過 Request 發(fā)送請求了。
請求與響應(yīng)
這里的請求,指的是通過 Request 發(fā)起的。
前面有提到,body 參數(shù)這一塊,是對一個 JSON 字符串進行轉(zhuǎn)化后的值。
這個 JSON 字符串大概成下面這樣。
{"headers":?{"h1":?"v1","h2":?"v2"},"requestId":?"xxxx","biz-prop-1":?"value-1","biz-prop-2":?"value-2","biz-prop-n":?"value-n", }其中, headers 和 requestId 這兩個是通用參數(shù),每個接口都應(yīng)該帶上,其他的就是各個接口需要什么就加什么。
響應(yīng)的話會有正常和異常。
正常的話,返回的 type 是和請求的 type 相對應(yīng)的。
好比 ConfigPublishRequest 就會對應(yīng) ConfigPublishResponse。
如果服務(wù)端處理異常了,就會返 ErrorResponse
這里的異常可以分為兩類。
請求沒有注冊
出現(xiàn)這種情況后,客戶端這邊是要重新和服務(wù)端進行連接,不然所有的請求都會是這個返回。
可能的原因有:
在請求之前沒有提前在雙向流里面發(fā)起建立連接的請求。
客戶端與服務(wù)端斷開過連接
請求處理失敗
這個一般就是服務(wù)端處理出現(xiàn)了異常。
重新連接
如果響應(yīng)告訴客戶端請求沒有注冊,這個時候要及時觸發(fā)重新連接,這樣才不會讓業(yè)務(wù)受到影響。
觸發(fā)重連操作后,會有一個 SwitchServer 的操作,可以簡單理解成換了一個服務(wù)地址,然后重復(fù)連接里面的幾個步驟。
到這里其實對接相關(guān)的內(nèi)容基本差不多了,剩下的就是對接具體的請求和其他操作了。
也附上一張老黃之前畫的粗糙的圖。
寫在最后
老黃參與的 nacos-sdk-csharp 目前已經(jīng)基本適配好了 nacos 2.0.0 beta 版本,但是還有許多細節(jié)需要慢慢的調(diào)整和改進。
希望有感興趣的大佬一起參與到這個項目來。
nacos-sdk-csharp 的地址 :https://github.com/nacos-group/nacos-sdk-csharp
總結(jié)
以上是生活随笔為你收集整理的聊一聊和Nacos 2.0.0对接那些事的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Mock 框架 Moq 的使用
- 下一篇: ElasticSearch+NLog实现