Golang 語言怎么使用 go-micro 和 gin 開發(fā)微服務(wù)?
01 介紹
Go Micro 是一個分布式系統(tǒng)開發(fā)框架。Go Micro 提供了分布式系統(tǒng)開發(fā)的核心需求,包括 RPC 和事件驅(qū)動的通信。Gin 是一個用 Golang 編寫的 web 框架。本文首先介紹怎么使用 go-micro 和 go-grpc 構(gòu)建微服務(wù),然后再介紹怎么集成 gin 和 go-micro。我們使用的 go-micro 版本是 v1.18.0,golang 版本是 v1.13,gin 版本是 v1.7.2。
02 使用 go-micro 和 go-grpc 構(gòu)建微服務(wù)
在我們開始使用 go-micro 之前,我們還需要提前做一些準(zhǔn)備工作。安裝 protoc、protoc-gen-go 和 protoc-gen-micro,關(guān)于如何安裝,讀者朋友們可以參閱官方文檔,我們在之前的文章中也介紹過,限于篇幅,本文不再贅述。
其實,我們可以使用 Go Micro 工具集以命令的方式快速生成模板文件,但是因為本文我們不準(zhǔn)備介紹工具集的相關(guān)內(nèi)容,所以我們使用手動創(chuàng)建文件的方式。
下面我們正式開始介紹如何構(gòu)建服務(wù),包括服務(wù)端服務(wù)和客戶端服務(wù)。
服務(wù)端
服務(wù)端代碼目錄:
- ├── go.mod
- ├── go.sum
- ├── handler
- │ └── user
- │ └── user.go
- ├── main.go
- └── proto
- └── user
- ├── user.pb.go
- ├── user.pb.micro.go
- └── user.proto
構(gòu)建服務(wù)端服務(wù),分為以下幾個步驟:
-
編寫 protobuf 文件
第一步是編寫 protobuf 文件,一般會將不同 package 的 protobuf 文件存放在單獨的文件目錄中。
文件路徑:
proto/user/user.proto
- syntax = "proto3";
- package user;
- service User {
- rpc Login(LoginRequest) returns (LoginResponse) {}
- }
- message LoginRequest {
- string email = 1;
- string password = 2;
- }
- message LoginResponse {
- string username = 1;
- }
閱讀上面這段代碼,我們在定義的
user.proto
文件中,創(chuàng)建了一個 rpc 服務(wù)。 -
生成文件
第二步是生成文件,使用命令:
- protoc --proto_path=. --micro_out=. --go_out=. user.proto
執(zhí)行以上命令,將會自動生成兩個文件,分別是
user.pb.go
和user.micro.go
。閱讀
user.micro.go
文件,可以發(fā)現(xiàn)在該文件中已經(jīng)自動生成了客戶端和服務(wù)端的代碼。 -
編寫 handler
第三步是編寫服務(wù)端的 handler 代碼。
文件路徑:
handler/user/user.go
- type User struct{}
- func (u *User) Login(ctx context.Context, req *protoUser.LoginRequest, rsp *protoUser.LoginResponse) error {
- if req.Email != "gopher@88.com" || req.Password != "123456" {
- rsp.Username = "Sorry " + req.Email
- return nil
- }
- rsp.Username = "Welcome " + req.Email
- return nil
- }
-
定義服務(wù)端服務(wù)
第四步是定義服務(wù)端服務(wù),需要注意的是,這里使用的是 grpc。在
main.go
文件中編寫如下代碼:文件路徑:
main.go
- func main() {
- // 創(chuàng)建服務(wù)
- service := grpc.NewService(
- micro.Name("go.micro.srv.demo"),
- micro.Version("v0.0.0"),
- micro.RegisterTTL(time.Second * 10),
- micro.RegisterInterval(time.Second * 5),
- )
- // 注冊處理器
- err := protoUser.RegisterUserHandler(service.Server(), new(user.User))
- if err !=nil {
- log.Fatal(err)
- }
- // 運行服務(wù)
- if err = service.Run(); err != nil {
- log.Fatal(err)
- }
- }
完成以上 4 個步驟,我們就已經(jīng)實現(xiàn)了服務(wù)端 rpc 服務(wù),接下來,我們開始編寫客戶端代碼。
客戶端
客戶端代碼目錄:
- ├── go.mod
- ├── go.sum
- ├── main.go
- ├── proto
- │ └── user
- │ ├── user.pb.go
- │ ├── user.pb.micro.go
- │ └── user.proto
- └── router
- ├── router.go
- └── v1
- └── user.go
構(gòu)建客戶端服務(wù),分為以下幾個步驟:
-
拷貝 proto 文件和生成文件
第一步是拷貝服務(wù)端的 proto 文件和生成文件,目的是為了保證服務(wù)端和客戶端的類型一致性。
-
定義客戶端服務(wù)
第二步是定義客戶端:
文件路徑:
router/v1/user.go
- func NewUserClient() protoUser.UserService {
- // 創(chuàng)建服務(wù)
- service := grpc.NewService()
- // 創(chuàng)建客戶端
- userClient := protoUser.NewUserService("go.micro.srv.demo", service.Client())
- return userClient
- }
-
rpc 調(diào)用遠(yuǎn)程服務(wù)的方法
第三步是 rpc 調(diào)用遠(yuǎn)程服務(wù)的方法:
文件路徑:
router/v1/user.go
- client := NewUserClient()
- // rpc 調(diào)用遠(yuǎn)程服務(wù)的方法
- resp, err := client.Login(context.TODO(), &protoUser.LoginRequest{Email: param.Email, Password: param.Password})
- if err != nil {
- fmt.Println(err)
- }
完成以上 3 步,我們就已經(jīng)基本編寫完客戶端的代碼。
03 gin 和 go-micro 集成
接下來,我們介紹如何集成 gin 和 go-micro,該部分代碼也是在客戶端中,共需要兩個步驟。
-
創(chuàng)建路由
文件路徑:
router/router.go
- func NewRouter() *gin.Engine {
- r := gin.New()
- userControllerV1 := new(v1.User)
- // 路由分組
- v1 := r.Group("/v1")
- {
- v1.Use(gin.Logger(), gin.Recovery())
- userV1 := v1.Group("/user")
- {
- userV1.POST("/login", userControllerV1.Login)
- }
- }
- return r
- }
-
啟動(監(jiān)聽)服務(wù)
文件路徑:
main.go
- func main() {
- r := router.NewRouter()
- server := &http.Server{
- Addr: ":8080",
- Handler: r,
- ReadTimeout: time.Second * 10,
- WriteTimeout: time.Second * 10,
- MaxHeaderBytes: 1 << 20,
- }
- if err := server.ListenAndServe(); err != nil {
- log.Fatal(err)
- }
- }
至此,我們已經(jīng)完成了集成 gin 和 go-micro,啟動服務(wù)端服務(wù)和客戶端服務(wù)后,我們就可以使用以下命令進行 cURL 測試:
- curl --location --request POST 'http://127.0.0.1:8080/v1/user/login' \
- --header 'Content-Type: application/json' \
- --data-raw '{
- "email": "gopher@88.com",
- "password": "123456"
- }'
04 總結(jié)
本文我們主要介紹怎么使用 go-micro 和 go-grpc 構(gòu)建微服務(wù),和怎么集成 gin 和 go-micro,并沒有介紹 gin 和 go-micro 的使用方法,如果讀者朋友們還不了解 gin 和 go-micro,建議先閱讀 gin 和 go-micro 官方文檔,也可以參考公眾號之前推送的關(guān)于 gin 的文章。