【字節青訓營-7】:初探 Kitex 字節微服務框架(使用ETCD進行服務注冊與發現)

本文目錄

  • 一、Kitex概述
  • 二、第一個Kitex應用
  • 三、IDL
  • 四、服務注冊與發現

一、Kitex概述

長話短說,就是字節跳動內部的 Golang 微服務 RPC 框架,具有高性能、強可擴展的特點,在字節內部已廣泛使用。

如果對微服務性能有要求,又希望定制擴展融入自己的治理體系,Kitex 會是一個不錯的選擇。

可以看到下面是Kitex的架構設計。

在這里插入圖片描述
這個框架有一些特點,比如:

  • 高性能

使用自研的高性能網絡庫 Netpoll,性能相較 go net 具有顯著優勢。

  • 擴展性

提供了較多的擴展接口以及默認擴展實現,使用者也可以根據需要自行定制擴展,具體見下面的框架擴展。

  • 多消息協議

RPC 消息協議默認支持 Thrift、Kitex Protobuf、gRPC。Thrift 支持 Buffered 和 Framed 二進制協議,與支持原生 Thrift 協議的多語言框架都能互通; Kitex Protobuf 是 Kitex 自定義的 Protobuf 消息協議,協議格式類似 Thrift;gRPC 是對 gRPC 消息協議的支持,可以與 gRPC 互通。除此之外,使用者也可以擴展自己的消息協議,目前社區也提供了 Dubbo 協議的支持,可以與 Dubbo 互通。

  • 多傳輸協議

傳輸協議封裝消息協議進行 RPC 互通,傳輸協議可以額外透傳元信息,用于服務治理,Kitex 支持的傳輸協議有 TTHeader、HTTP2。TTHeader 可以和 Thrift、Kitex Protobuf 結合使用;HTTP2 目前主要是結合 gRPC 協議使用,后續也會支持 Thrift。

  • 多種消息類型

支持 PingPong、Oneway、雙向 Streaming。其中 Oneway 目前只對 Thrift 協議支持,雙向 Streaming 只對 gRPC 支持,后續會考慮支持 Thrift 的雙向 Streaming。

  • 服務治理

支持服務注冊/發現、負載均衡、熔斷、限流、重試、監控、鏈路跟蹤、日志、診斷等服務治理模塊,大部分均已提供默認擴展,使用者可選擇集成。

  • 代碼生成

Kitex 內置代碼生成工具,可支持生成 Thrift、Protobuf 以及腳手架代碼。

二、第一個Kitex應用

首先我們創建一個新的Go項目,然后安裝對應的插件:kitexthriftgo

然后在終端輸入對應的安裝命令:

go install github.com/cloudwego/kitex/tool/cmd/kitex@latest
go install github.com/cloudwego/thriftgo@latest

然后等待對應的安裝即可。

在項目路徑下安裝新建thrift文件,然后輸入如下代碼:

在這里插入圖片描述

namespace go apistruct Request{1:string message
}struct Response{1:string message
}service Echo{Response echo(1:Request req)
}

簡單來說,這段代碼定義一個簡單的服務 Echo,它包含一個方法 echo。這個方法接收一個 Request 類型的對象作為輸入,處理后返回一個 Response 類型的對象。Request 和 Response 都包含一個字符串字段 message,分別用于傳遞請求消息和響應消息。這種定義方式使得 Thrift 可以生成不同語言的代碼(例如 Go、Java、Python 等),方便跨語言的服務調用。

然后在命令行輸入命令:

kitex -module exampleKitex -service exampleKitex echo.thrift

來生成基本的代碼。

在這里插入圖片描述
等待一會后,可以看到目錄已經更新了。

在這里插入圖片描述
在這里插入圖片描述
main.go中輸入如下代碼:

package mainimport (api "exampleKitex/kitex_gen/api/echo""log"
)
/*api.NewServer 是一個函數,用于創建一個新的服務實例。new(EchoImpl) 創建了一個 EchoImpl 類型的實例,并將其傳遞給 api.NewServer。調用 svr.Run() 方法啟動服務。
*/
func main() {svr := api.NewServer(new(EchoImpl))err := svr.Run()if err != nil {log.Println(err.Error())}
}

如果有報錯,可以輸入go mod tidy來補充對應需要的庫。

然后在handler.go中來輸入邏輯代碼。

(s *EchoImpl):這是方法的接收者,表示這個方法屬于 EchoImpl 類型的指針 s。
EchoImpl 是一個結構體類型,通常是由 Thrift 生成的接口的具體實現。
echo是方法名稱,對應 Thrift 定義中的 echo 方法。
ctx context.Context:這是方法的第一個參數,類型為 context.Context。
context 是 Go 標準庫中的一個包,用于在程序中傳遞上下文信息,例如超時、取消信號等。
req *api.Request:這是方法的第二個參數,類型為 *api.Request,表示這是一個指向 api.Request 類型的指針。
api.Request 是 Thrift 定義的 Request 結構體,通過 Thrift 生成的 Go 代碼中的 api 包來訪問。&api.Response{}:創建了一個 api.Response 類型的實例,并取其地址(返回一個指針)。
Message: req.Message:將 req 參數中的 Message 字段值賦給新創建的 Response 實例的 Message 字段。這是一個簡單的回顯服務,即客戶端發送一個消息,服務端原樣返回這個消息。
package mainimport ("context"api "exampleKitex/kitex_gen/api"
)// EchoImpl implements the last service interface defined in the IDL.
type EchoImpl struct{}// Echo implements the EchoImpl interface.
func (s *EchoImpl) Echo(ctx context.Context, req *api.Request) (resp *api.Response, err error) {// TODO: Your code here...return &api.Response{Message: req.Message}, nil
}

然后我們來啟動main.go和handler.go. 啟動之后會默認在監聽端口進行對應的監聽。

在這里插入圖片描述

然后我們新建一個客戶端,并且寫入對應的客戶端代碼。

package mainimport ("context""github.com/cloudwego/kitex/client/callopt""log""exampleKitex/kitex_gen/api""exampleKitex/kitex_gen/api/echo""time"
)import "github.com/cloudwego/kitex/client"func main() {//下面的destService對應服務名稱是我們在啟動kitex代碼生成工具命令中的service名稱// kitex -moudle exampleKitex -service exampleKitex(服務名稱) echo.thriftc, err := echo.NewClient("exampleKitex", client.WithHostPorts("0.0.0.0:8888"))if err != nil {log.Fatal(err)}req := &api.Request{Message: "my request"}resp, err := c.Echo(context.Background(), req, callopt.WithRPCTimeout(3*time.Second))if err != nil {log.Fatal(err)}log.Println(resp)
}

然后運行客戶端,新開一個終端,輸入命令go run .\client.go即可。

然后可以看到返回的Response如下:

在這里插入圖片描述

所以總結一下,就是,先在echo.thrift中編寫接口,定義發送什么樣的請求,請求里邊有什么樣的一個信息,然后就是繼續定義一個響應,以及服務的邏輯。

在這里插入圖片描述

三、IDL

IDL(Interface Definition Language,接口定義語言)是一種用于定義軟件組件之間交互接口的規范語言。它允許開發者以一種語言無關的方式描述服務接口、數據結構和通信協議,從而實現不同編程語言之間的互操作性。IDL 的核心目的是提供一種標準化的方式來定義服務的接口和數據結構,使得這些接口和數據結構可以在多種編程語言中被實現和使用。

IDL就是我們剛剛定義的這個thrift文件。

如果進行PRC,那么就需要知道對方的接口是什么,需要傳什么參數,也需要知道返回值是什么樣子的。這個時候就需要通過IDL來約定雙方的協議。就像調用某個函數,需要知道函數簽名一樣。

定義好thrift文件之后,就可以使用命令生成代碼了。
kitex -module example -service example echo.thrift生成代碼。

在這里插入圖片描述

服務是默認監聽8888端口的。

四、服務注冊與發現

目前Kitex的服務注冊與發現已經對接了主流的服務注冊與發現中心,如ETCD、Nacos、zookeeper、Eureka等。

接下來我們進行一個簡單的實戰。

首先我們下載etcd:https://github.com/etcd-io/etcd/releases,找到對應的電腦的版本。

在這里插入圖片描述

下載好之后找個文件夾進行解壓縮,然后打開,雙擊打開即可。

在這里插入圖片描述

運行起來之后可以看到對應的2380和2379兩個端口。

在這里插入圖片描述
到這一步,服務器已經啟用成功了。

接下來我們需要把服務注冊到etcd注冊中心去。修改handler.go的相關代碼。

簡單說明下作用:實現一個 Kitex 服務端程序,通過 ETCD 注冊中心將自身注冊為一個可發現的服務,并提供了一個簡單的 Echo 方法。程序的主要功能包括:

package mainimport ("context"api "exampleKitex/kitex_gen/api""exampleKitex/kitex_gen/api/echo""github.com/cloudwego/kitex/pkg/rpcinfo""github.com/cloudwego/kitex/server"etcd "github.com/kitex-contrib/registry-etcd""log"
)// EchoImpl implements the last service interface defined in the IDL.EchoImpl:定義了一個結構體,用于實現服務接口。
type EchoImpl struct{}// Echo implements the EchoImpl interface.
// ctx context.Context:上下文對象,用于傳遞超時和取消信號。
// req *api.Request:請求對象,包含客戶端發送的數據。
func (s *EchoImpl) Echo(ctx context.Context, req *api.Request) (resp *api.Response, err error) {// TODO: Your code here...return &api.Response{Message: req.Message}, nil}func main() {//etcd.NewEtcdRegistry:創建一個 ETCD 注冊中心實例。//參數 []string{"127.0.0.1:2379"} 指定了 ETCD 服務的地址。r, err := etcd.NewEtcdRegistry([]string{"127.0.0.1:2379"})if err != nil {log.Fatal(err)}//echo.NewServer:創建一個服務實例。//new(EchoImpl):創建一個 EchoImpl 實例,作為服務的具體實現。//server.WithRegistry(r):指定使用 ETCD 注冊中心實例 r,將服務注冊到 ETCD 中。//server.WithServerBasicInfo:設置服務的基本信息,例如服務名稱。ServiceName: "Hello":將服務名稱設置為 "Hello",客戶端可以通過這個名稱找到服務。server := echo.NewServer(new(EchoImpl), server.WithRegistry(r), server.WithServerBasicInfo(&rpcinfo.EndpointBasicInfo{ServiceName: "Hello",}))err = server.Run()if err != nil {log.Fatal(err)}}

同時我們修改client.go的代碼如下:

一句話概括下作用,就是:使用 Kitex 框架的客戶端程序,通過 ETCD 注冊中心動態發現服務,并調用名為 Hello 的服務的 Echo 方法。代碼的主要功能是定期發送請求到服務端,并打印響應結果。

package mainimport ("context""exampleKitex/kitex_gen/api""exampleKitex/kitex_gen/api/echo""github.com/cloudwego/kitex/client"etcd "github.com/kitex-contrib/registry-etcd""log""time"
)func main() {//etcd.NewEtcdResolver:創建一個 ETCD 解析器實例,用于從 ETCD 服務注冊中心獲取服務實例的地址。//參數 []string{"127.0.0.1:2379"} 指定了 ETCD 服務的地址。r, err := etcd.NewEtcdResolver([]string{"127.0.0.1:2379"})if err != nil {log.Fatal(err)}//echo.MustNewClient:創建一個服務客戶端實例。//"Hello" 是服務名稱,與服務端在 ETCD 中注冊的名稱一致。//client.WithResolver(r):指定使用 ETCD 解析器 r 來動態發現服務實例。這意味著客戶端會從 ETCD 中獲取服務實例的地址,而不是直接指定服務地址。client := echo.MustNewClient("Hello", client.WithResolver(r))//創建一個帶有超時時間的上下文,超時時間為 3 秒。for {ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)//調用服務端的 Echo 方法,傳遞一個請求對象,其中 Message 字段為 "hello"。resp, err := client.Echo(ctx, &api.Request{Message: "hello"})cancel() //調用 cancel() 釋放上下文資源。if err != nil {log.Fatal(err)}log.Println(resp)time.Sleep(time.Second)}
}

來捋順一下步驟:

實現一個 Kitex 客戶端程序,通過 ETCD 注冊中心動態發現服務,并調用名為 Hello 的服務的 Echo 方法:

創建 ETCD 解析器實例,用于從 ETCD 注冊中心獲取服務實例的地址。然后創建服務客戶端實例,指定使用 ETCD 解析器。并且在一個無限循環中,每隔 1 秒調用一次服務的 Echo 方法。打印服務端返回的響應。

這種設計適用于微服務架構,其中服務實例可能動態變化,通過 ETCD 注冊中心可以實現服務發現和負載均衡。

通過命令 go run .\handler.go來啟動服務端,會將我們的服務注冊到etcd里面去。

在這里插入圖片描述
然后運行client,會看到如下的消息。

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/894845.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/894845.shtml
英文地址,請注明出處:http://en.pswp.cn/news/894845.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【數學】矩陣、向量(內含矩陣乘法C++)

目錄 一、前置知識:向量(一列或一行的矩陣)、矩陣1. 行向量2. 列向量3. 向量其余基本概念4. 矩陣基本概念5. 關于它們的細節 二、運算1. 轉置(1)定義(2)性質 2. 矩陣(向量&#xff0…

TCP/IP 郵件

TCP/IP 郵件 引言 在互聯網技術飛速發展的今天,電子郵件(Email)已成為人們日常工作和生活中不可或缺的通信工具。TCP/IP協議作為互聯網通信的基礎,為電子郵件的傳輸提供了強大的技術支持。本文將詳細介紹TCP/IP在電子郵件傳輸過程中的作用,以及相關的協議和實現方式。 …

離線安裝Appium Server

1、問題概述? 安裝Appium通常有兩種方式: 第一種:下載exe安裝包,這種是Appium Server GUI安裝方式,缺點是通過命令啟動不方便。 第二種:通過cmd安裝appium server,可以通過命令方式啟動,比較方便。 問題:在沒有外網的情況下,無法通過命令在cmd中安裝appium server…

設計模式六大原則和單例模式

設計模式 目的 實現可重用解決方案,構筑易維護、可擴展的軟件系統。 六大原則 單一職責: 類的職責單一,一個方法做一件事。 開閉原則: 拓展開放,修改關閉。 里氏替換: 父類能出現的地方,子…

淺嘗yolo11全程記錄1-準備環境+官網模型推理(個人備份)

準備工作(虛擬環境、導入項目) 安裝Anaconda 主要是為了創建和管理虛擬環境,在pycharm里按照項目里的requirments.txt安裝依賴的時候,使用虛擬環境會好很多(我記得不用Anaconda也可以直接在pycharm的terminal里頭創建…

5.攻防世界 fileinclude

進入題目頁面如下 提示flag在flag.php ctrlu&#xff0c;查看源碼 給出了一段PHP代碼&#xff0c;進行代碼審計 <?php // 檢查是否開啟了錯誤顯示功能 if( !ini_get(display_errors) ) {// 如果沒有開啟&#xff0c;則將錯誤顯示功能設置為開啟狀態ini_set(display_error…

深入淺出 NRM:加速你的 npm 包管理之旅

文章目錄 前言一、NRM 是什么&#xff1f;二、為什么需要 NRM&#xff1f;三、NRM 的優勢四、NRM 的安裝與使用4.1 安裝 NRM4.2 查看可用的 npm 源4.3 切換 npm 源4.4 測試 npm 源速度4.5 添加自定義 npm 源4.6 刪除 npm 源 五、NRM 的進階使用六、總結 前言 作為一名 JavaScr…

《C#之集訓1-20121019c#基礎》

&#xfeff;&#xfeff; C#是微軟公司發布的一種面向對象的、運行于.NET Framework之上的高級程序設計語言。它是微軟公司研究員Anders Hejlsberg的最新成果。 C#曾經的它在我眼中是很高大上的&#xff0c;一直沒有目睹其風采&#xff0c;現在終于揭開了它神秘的面紗&#xf…

紅包雨項目前端部分

創建項目 pnpm i -g vue/cli vue create red_pakage pnpm i sass sass-locader -D pnpm i --save normalize.css pnpm i --save-dev postcss-px-to-viewportpnpm i vantlatest-v2 -S pnpm i babel-plugin-import -Dhttps://vant.pro/vant/v2/#/zh-CN/<van-button click&…

藍橋杯嵌入式備賽(三)—— LED +按鍵 + LCD

目錄 一、LED1、原理圖介紹2、程序代碼 二、按鍵1、原理圖介紹2、程序代碼 三、LCD1、原理圖介紹2、程序代碼 一、LED 1、原理圖介紹 如果所示&#xff0c;STM32G431RBT6中有八個LED&#xff0c;由八個GPIO控制&#xff0c;分別為PC8-15&#xff0c;當輸出為低電平時點亮。其中…

深入剖析 HTML5 新特性:語義化標簽和表單控件完全指南

系列文章目錄 01-從零開始學 HTML&#xff1a;構建網頁的基本框架與技巧 02-HTML常見文本標簽解析&#xff1a;從基礎到進階的全面指南 03-HTML從入門到精通&#xff1a;鏈接與圖像標簽全解析 04-HTML 列表標簽全解析&#xff1a;無序與有序列表的深度應用 05-HTML表格標簽全面…

[Java基礎]函數式編程

Lambda函數 JDK8新增的語法形式, 使用Lambda函數替代某些匿名內部類對象&#xff0c;從而讓程序代碼更簡潔&#xff0c;可讀性更好。 基本使用 lambda表達式只能簡化函數式接口的匿名內部類寫法 // 1.定義抽象類 abstract class Animal {public abstract void crt(); }publi…

Vue通過觸發與監聽事件進行數據傳遞: 子組件調用 $emit 方法來將數據傳遞給父組件。

文章目錄 引言I 組件事件事件參數defineEmits 宏聲明需要拋出的事件事件校驗例子:子組件告訴父組件放大所有博客文章的文字II 【詳細說明】 子組件通過觸發一個事件,將數據傳遞給父組件調用內建的 `$emit `方法傳入事件名稱來觸發一個事件子組件通過`this.$emit`來觸發一個事…

Vim 多窗口編輯及文件對比

水平分割 :split 默認使用水平分割的方式。 :split :sp 垂直分割 :vsplit :vs 帶文件的分割 :split 文件名 :sp 文件名 在光標所在的窗口&#xff0c;輸入分割窗口命令就會對那個窗口進行分割。 切換窗口 Ctrlw 切換正在編輯的窗口 快速分割窗口 Ctrlwn 快速分割當前…

“衛星-無人機-地面”遙感數據快速使用及地物含量計算的實現方法

在與上千學員交流過程中&#xff0c;發現科研、生產和應用多源遙感數據時&#xff0c;能快速上手&#xff0c;發揮數據的時效性&#xff0c;盡快出創新性成果&#xff0c;是目前的學員最迫切的需求。特別是按照“遙感數據獲取-處理-分析-計算-制圖”全流程的答疑解惑&#xff0…

二級C語言題解:十進制轉其他進制、非素數求和、重復數統計

目錄 一、程序填空&#x1f4dd; --- 十進制轉其他進制 題目&#x1f4c3; 分析&#x1f9d0; 二、程序修改&#x1f6e0;? --- 非素數求和 題目&#x1f4c3; 分析&#x1f9d0; 三、程序設計&#x1f4bb; --- 重復數統計 題目&#x1f4c3; 分析&#x1f9d0; 前言…

使用服務器部署DeepSeek-R1模型【詳細版】

文章目錄 引言deepseek-r1IDE或者終端工具算力平臺體驗deepseek-r1模型總結 引言 在現代的機器學習和深度學習應用中&#xff0c;模型部署和服務化是每個開發者面臨的重要任務。無論是用于智能推薦、自然語言處理還是圖像識別&#xff0c;如何高效、穩定地將深度學習模型部署到…

讓相機自己決定拍哪兒!——NeRF 三維重建的主動探索之路

我在 NeRF 中折騰自動探索式三維重建的心得 寫在前面&#xff1a; 最近我在研究三維重建方向&#xff0c;深切感受到 NeRF (Neural Radiance Fields) 在學術界和工業界都備受矚目。以往三維重建通常要依賴繁瑣的多視圖幾何管線&#xff08;比如特征匹配、深度估計、網格融合等&…

央行發布《貿易金融分布式賬本技術要求》,參考架構包括5部分

《銀行科技研究社》(作者 木子劍):2024年12月11日,中國人民銀行發布金融行業標準《貿易金融分布式賬本技術要求》(JR/T 0308-2024)(以下簡稱“《要求》”),當日實施。據悉,該文件的起草單位包括6大行和多家股份制銀行等。 《要求》規定了分布式賬本技術在貿易金融領域…

管理etcd的存儲空間配額

如何管理etcd的存儲空間配額 - 防止集群存儲耗盡指南 本文基于etcd v3.4官方文檔編寫 為什么需要空間配額&#xff1f; 在分布式系統中&#xff0c;etcd作為可靠的鍵值存儲&#xff0c;很容易成為系統瓶頸。當遇到以下情況時&#xff1a; 應用程序頻繁寫入大量數據未及時清理…