由于工作的契機,最近學習了下Gossip,以及go語言的實現版本HashiCorp/memberlist。網上有個最基本的memberlist使用的example,在下邊的鏈接中,感興趣可以按照文檔運行下感受感受。本文主要講解memberlist v0.1.5 的使用細節。

成都創新互聯專注于鎮遠網站建設服務及定制,我們擁有豐富的企業做網站經驗。 熱誠為您提供鎮遠營銷型網站建設,鎮遠網站制作、鎮遠網頁設計、鎮遠網站官網定制、重慶小程序開發公司服務,打造鎮遠網絡公司原創品牌,更為您提供鎮遠網站排名全網營銷落地服務。
Gossip是最終一致性協議,是目前性能最好,容錯性最好的分布式協議。目前Prometheus的告警組件alertmanager、redis、s3、區塊鏈等項目都有使用Gossip。本文不介紹Gossip原理,大家自行谷歌。
簡單的幾步即可搭建gossip集群
感謝已經有網友為我們實現了一個example(
)。
哪里有問題,還請大家多多指正
智能合約調用是實現一個 DApp 的關鍵,一個完整的 DApp 包括前端、后端、智能合約及區塊 鏈系統,智能合約的調用是連接區塊鏈與前后端的關鍵。
我們先來了解一下智能合約調用的基礎原理。智能合約運行在以太坊節點的 EVM 中。因此要 想調用合約必須要訪問某個節點。
以后端程序為例,后端服務若想連接節點有兩種可能,一種是雙 方在同一主機,此時后端連接節點可以采用 本地 IPC(Inter-Process Communication,進 程間通信)機制,也可以采用 RPC(Remote Procedure Call,遠程過程調用)機制;另 一種情況是雙方不在同一臺主機,此時只能采用 RPC 機制進行通信。
提到 RPC, 讀者應該對 Geth 啟動參數有點印象,Geth 啟動時可以選擇開啟 RPC 服務,對應的 默認服務端口是 8545。。
接著,我們來了解一下智能合約運行的過程。
智能合約的運行過程是后端服務連接某節點,將 智能合約的調用(交易)發送給節點,節點在驗證了交易的合法性后進行全網廣播,被礦工打包到 區塊中代表此交易得到確認,至此交易才算完成。
就像數據庫一樣,每個區塊鏈平臺都會提供主流 開發語言的 SDK(Software Development Kit,軟件開發工具包),由于 Geth 本身就是用 Go 語言 編寫的,因此若想使用 Go 語言連接節點、發交易,直接在工程內導入 go-ethereum(Geth 源碼) 包就可以了,剩下的問題就是流程和 API 的事情了。
總結一下,智能合約被調用的兩個關鍵點是節點和 SDK。
由于 IPC 要求后端與節點必須在同一主機,所以很多時候開發者都會采用 RPC 模式。除了 RPC,以太坊也為開發者提供了 json- rpc 接口,本文就不展開討論了。
接下來介紹如何使用 Go 語言,借助 go-ethereum 源碼庫來實現智能合約的調用。這是有固定 步驟的,我們先來說一下總體步驟,以下面的合約為例。
步驟 01:編譯合約,獲取合約 ABI(Application Binary Interface,應用二進制接口)。 單擊【ABI】按鈕拷貝合約 ABI 信息,將其粘貼到文件 calldemo.abi 中(可使用 Go 語言IDE 創建該文件,文件名可自定義,后綴最好使用 abi)。
最好能將 calldemo.abi 單獨保存在一個目錄下,輸入“ls”命令只能看到 calldemo.abi 文件,參 考效果如下:
步驟 02:獲得合約地址。注意要將合約部署到 Geth 節點。因此 Environment 選擇為 Web3 Provider。
在【Environment】選項框中選擇“Web3 Provider”,然后單擊【Deploy】按鈕。
部署后,獲得合約地址為:0xa09209c28AEf59a4653b905792a9a910E78E7407。
步驟 03:利用 abigen 工具(Geth 工具包內的可執行程序)編譯智能合約為 Go 代碼。abigen 工具的作用是將 abi 文件轉換為 Go 代碼,命令如下:
其中各參數的含義如下。 (1)abi:是指定傳入的 abi 文件。 (2)type:是指定輸出文件中的基本結構類型。 (3)pkg:指定輸出文件 package 名稱。 (4)out:指定輸出文件名。 執行后,將在代碼目錄下看到 funcdemo.go 文件,讀者可以打開該文件欣賞一下,注意不要修改它。
步驟 04:創建 main.go,填入如下代碼。 注意代碼中 HexToAddress 函數內要傳入該合約部署后的地址,此地址在步驟 01 中獲得。
步驟 04:設置 go mod,以便工程自動識別。
前面有所提及,若要使用 Go 語言調用智能合約,需要下載 go-ethereum 工程,可以使用下面 的指令:
該指令會自動將 go-ethereum 下載到“$GOPATH/src/github.com/ethereum/go-ethereum”,這樣還算 不錯。不過,Go 語言自 1.11 版本后,增加了 module 管理工程的模式。只要設置好了 go mod,下載 依賴工程的事情就不必關心了。
接下來設置 module 生效和 GOPROXY,命令如下:
在項目工程內,執行初始化,calldemo 可以自定義名稱。
步驟 05:運行代碼。執行代碼,將看到下面的效果,以及最終輸出的 2020。
上述輸出信息中,可以看到 Go 語言會自動下載依賴文件,這就是 go mod 的神奇之處。看到 2020,相信讀者也知道運行結果是正確的了。
三次握手:
1. 主動發起連接請求端(客戶端),發送 SYN 標志位,攜帶數據包、包號
2. 被動接收連接請求端(服務器),接收 SYN,回復 ACK,攜帶應答序列號。同時,發送SYN標志位,攜帶數據包、包號
3. 主動發起連接請求端(客戶端),接收SYN 標志位,回復 ACK。
被動端(服務器)接收 ACK —— 標志著 三次握手建立完成( Accept()/Dial() 返回 )
四次揮手:
1. 主動請求斷開連接端(客戶端), 發送 FIN標志,攜帶數據包
2. 被動接受斷開連接端(服務器), 發送 ACK標志,攜帶應答序列號。 —— 半關閉完成。
3. 被動接受斷開連接端(服務器), 發送 FIN標志,攜帶數據包
4. 主動請求斷開連接端(客戶端), 發送 最后一個 ACK標志,攜帶應答序列號。—— 發送完成,客戶端不會直接退出,等 2MSL時長。
等 2MSL待目的:確保服務器 收到最后一個ACK
滑動窗口:
通知對端本地存儲數據的 緩沖區容量。—— write 函數在對端 緩沖區滿時,有可能阻塞。
TCP狀態轉換:
1. 主動發起連接請求端:
CLOSED —— 發送SYN —— SYN_SENT(了解) —— 接收ACK、SYN,回發 ACK —— ESTABLISHED (數據通信)
2. 主動關閉連接請求端:
ESTABLISHED —— 發送FIN —— FIN_WAIT_1 —— 接收ACK —— FIN_WAIT_2 (半關閉、主動端)
—— 接收FIN、回復ACK —— TIME_WAIT (主動端) —— 等 2MSL 時長 —— CLOSED
3. 被動建立連接請求端:
CLOSED —— LISTEN —— 接收SYN、發送ACK、SYN —— SYN_RCVD —— 接收 ACK —— ESTABLISHED (數據通信)
4. 被動斷開連接請求端:
ESTABLISHED —— 接收 FIN、發送 ACK —— CLOSE_WAIT —— 發送 FIN —— LAST_ACK —— 接收ACK —— CLOSED
windows下查看TCP狀態轉換:
netstat -an | findstr? 端口號
Linux下查看TCP狀態轉換:
netstat -an | grep? 端口號
TCP和UDP對比:?
TCP: 面向連接的可靠的數據包傳遞。 針對不穩定的 網絡層,完全彌補。ACK
UDP:無連接不可靠的報文傳輸。 針對不穩定的 網絡層,完全不彌補。還原網絡真實狀態。
優點???????????????????????????????????????????????????????????? 缺點
TCP: 可靠、順序、穩定 ???????????????????????????????????? 系統資源消耗大,程序實現繁復、速度慢
UDP:系統資源消耗小,程序實現簡單、速度快 ???????????????????????? 不可靠、無序、不穩定
使用場景:
TCP:大文件、可靠數據傳輸。 對數據的 穩定性、準確性、一致性要求較高的場合。
UDP:應用于對數據時效性要求較高的場合。 網絡直播、電話會議、視頻直播、網絡游戲。
UDP-CS-Server實現流程:
1.? 創建 udp地址結構 ResolveUDPAddr(“協議”, “IP:port”) —— udpAddr 本質 struct{IP、port}
2.? 創建用于 數據通信的 socket ListenUDP(“協議”, udpAddr ) —— udpConn (socket)
3.? 從客戶端讀取數據,獲取對端的地址 udpConn.ReadFromUDP() —— 返回:n,clientAddr, err
4.? 發送數據包給 客戶端 udpConn.WriteToUDP("數據", clientAddr)
UDP-CS-Client實現流程:
1.? 創建用于通信的 socket。 net.Dial("udp", "服務器IP:port") —— udpConn (socket)
2.? 以后流程參見 TCP客戶端實現源碼。
UDPserver默認就支持并發!
------------------------------------
命令行參數: 在main函數啟動時,向整個程序傳參。 【重點】
語法: go run xxx.go ? argv1 argv2? argv3? argv4 。。。
xxx.exe:? 第 0 個參數。
argv1 :第 1 個參數。
argv2 :第 2 個參數。
argv3 :第 3 個參數。
argv4 :第 4 個參數。
使用: list := os.Args? 提取所有命令行參數。
獲取文件屬性函數:
os.stat(文件訪問絕對路徑) —— fileInfo 接口
fileInfo 包含 兩個接口。
Name() 獲取文件名。 不帶訪問路徑
Size() 獲取文件大小。
網絡文件傳輸 —— 發送端(客戶端)
1.? 獲取命令行參數,得到文件名(帶路徑)filePath list := os.Args
2.? 使用 os.stat() 獲取 文件名(不帶路徑)fileName
3.? 創建 用于數據傳輸的 socket? net.Dial("tcp", “服務器IP+port”) —— conn
4.? 發送文件名(不帶路徑)? 給接收端, conn.write()
5.? 讀取 接收端回發“ok”,判斷無誤。封裝函數 sendFile(filePath, conn) 發送文件內容
6.? 實現 sendFile(filePath,? conn)
1) 只讀打開文件 os.Open(filePath)
for {
2) 從文件中讀數據? f.Read(buf)
3) 將讀到的數據寫到socket中? conn.write(buf[:n])
4)判斷讀取文件的 結尾。 io.EOF. 跳出循環
}
網絡文件傳輸 —— 接收端(服務器)
1. 創建用于監聽的 socket net.Listen() —— listener
2. 借助listener 創建用于 通信的 socket listener.Accpet()? —— conn
3. 讀取 conn.read() 發送端的 文件名, 保存至本地。
4. 回發 “ok”應答 發送端。
5. 封裝函數,接收文件內容 recvFile(文件路徑)
1) f = os.Create(帶有路徑的文件名)
for {
2)從 socket中讀取發送端發送的 文件內容 。 conn.read(buf)
3)? 將讀到的數據 保存至本地文件 f.Write(buf[:n])
4)? 判斷 讀取conn 結束, 代表文件傳輸完成。 n == 0? break
}
學完了 net/http 和 fasthttp 兩個HTTP協議接口的客戶端實現,接下來就要開始Server的開發,不學不知道一學嚇一跳,居然這兩個庫還支持Server的開發,太方便了。
相比于Java的HTTPServer開發基本上都是使用Spring或者Springboot框架,總是要配置各種配置類,各種 handle 對象。Golang的Server開發顯得非常簡單,就是因為特別簡單,或者說沒有形成特別統一的規范或者框架,我發現了很多實現方式,HTTP協議基于還是 net/http 和 fasthttp ,但是 handle 語法就多種多樣了。
先復習一下: Golang語言HTTP客戶端實踐 、 Golang fasthttp實踐 。
在Golang語言方面,實現某個功能的庫可能會比較多,有機會還是要多跟同行交流,指不定就發現了更好用的庫。下面我分享我學到的六種Server開發的實現Demo。
基于 net/http 實現,這是一種比較基礎的,對于接口和 handle 映射關系處理并不優雅,不推薦使用。
第二種也是基于 net/http ,這種編寫語法可以很好地解決第一種的問題,handle和path有了類似配置的語法,可讀性提高了很多。
第三個基于 net/http 和 github.com/labstack/echo ,后者主要提供了 Echo 對象用來處理各類配置包括接口和handle映射,功能很豐富,可讀性最佳。
第四種依然基于 net/http 實現,引入了 github.com/gin-gonic/gin 的路由,看起來接口和 handle 映射關系比較明晰了。
第五種基于 fasthttp 開發,使用都是 fasthttp 提供的API,可讀性尚可,handle配置倒是更像Java了。
第六種依然基于 fasthttp ,用到了 github.com/buaazp/fasthttprouter ,有點奇怪兩個居然不在一個GitHub倉庫里。使用語法跟第三種方式有點類似,比較有條理,有利于閱讀。
近幾年誕生了很多微服務框架,比如JAVA的Spring Cloud、Dubbo;Golang的GoKit和GoMicro以及NodeJs的Seneca。幾乎每種主流語言都有其對應的微服務框架。
Go在微服務框架中有其獨特的優勢,至于優勢在哪,自行google。
1、GoKit框架
這是一個工具包的集合,可以幫助攻城獅構建強大、可靠和可維護的微服務。提供了用于實現系統監控和彈性模式組件的庫,例如日志、跟蹤、限流、熔斷等。
基于這個框架的應用程序架構由三個主要的部分組成:
傳輸層:用于網絡通信,服務通常使用HTTP或者gRPC等網絡傳輸協議,或者使用NATS等發布訂閱系統相互通信。
接口層:是服務器和客戶端的基本構建塊。每個對外提供的接口方法都會定義為一個Endpoint,一遍在服務器和客戶端之間進行網絡通信,每個端點使用傳輸層通過HTTP或gRPC等具體通信模式對外提供服務
服務成:具體的業務邏輯實現
2、GoMicro框架
這是一個基于Go語言實現的插件化RPC微服務框架。提供了服務發現、負載均衡、同步傳輸、異步通信以及事件驅動等機制,嘗試簡化分布式系統之間的通信,讓開發者更專注于自身業務邏輯的開發。
GoMicro的設計哲學是可插拔的架構理念,提供了可快速構建系統的組件,并且可以根據自身的需求對GoMicro提供的默認實現進行定制。所有插件都可在倉庫github.com/micro/go-plugins 中找到。
新聞名稱:go語言實現通信協議的簡單介紹
地址分享:http://www.yijiale78.com/article8/dodohip.html
成都網站建設公司_創新互聯,為您提供自適應網站、搜索引擎優化、網站設計公司、定制開發、建站公司、靜態網站
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯