Golang 語言怎麼使用 go-micro 和 gin 開發微服務?

大家好,我是 frank。
歡迎大家點擊上方藍色文字「Golang 語言開發棧」關注公衆號。
設爲星標,第一時間接收推送文章。
文末掃碼,和大家一起學 Golang 語言。

01 

介紹

Go Micro 是一個分佈式系統開發框架。Go Micro 提供了分佈式系統開發的核心需求,包括 RPC 和事件驅動的通信。Gin 是一個用 Golang 編寫的 web 框架。本文首先介紹怎麼使用 go-micro 和 go-grpc 構建微服務,然後再介紹怎麼集成 gin 和 go-micro。我們使用的 go-micro 版本是 v1.18.0,golang 版本是 v1.13,gin 版本是 v1.7.2。

02 

使用 go-micro 和 go-grpc 構建微服務

在我們開始使用 go-micro 之前,我們還需要提前做一些準備工作。安裝 protoc、protoc-gen-go 和 protoc-gen-micro,關於如何安裝,讀者朋友們可以參閱官方文檔,我們在之前的文章中也介紹過,限於篇幅,本文不再贅述。

其實,我們可以使用 Go Micro 工具集以命令的方式快速生成模板文件,但是因爲本文我們不準備介紹工具集的相關內容,所以我們使用手動創建文件的方式。

下面我們正式開始介紹如何構建服務,包括服務端服務和客戶端服務。

服務端

服務端代碼目錄:

├── go.mod
├── go.sum
├── handler
│   └── user
│       └── user.go
├── main.go
└── proto
    └── user
        ├── user.pb.go
        ├── user.pb.micro.go
        └── user.proto

構建服務端服務,分爲以下幾個步驟:

  1. 編寫 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 文件中,創建了一個 rpc 服務。

  2. 生成文件

    第二步是生成文件,使用命令:

    protoc --proto_path=. --micro_out=. --go_out=. user.proto

    執行以上命令,將會自動生成兩個文件,分別是 user.pb.go 和 user.micro.go

    閱讀 user.micro.go 文件,可以發現在該文件中已經自動生成了客戶端和服務端的代碼。

  3. 編寫 handler

    第三步是編寫服務端的 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
    }
  4. 定義服務端服務

    第四步是定義服務端服務,需要注意的是,這裏使用的是 grpc。在 main.go 文件中編寫如下代碼:

    文件路徑:main.go

    func main() {
      // 創建服務
      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)
      }
      // 運行服務
      if err = service.Run(); err != nil {
        log.Fatal(err)
      }
    }

完成以上 4 個步驟,我們就已經實現了服務端 rpc 服務,接下來,我們開始編寫客戶端代碼。

客戶端

客戶端代碼目錄:

├── go.mod
├── go.sum
├── main.go
├── proto
│   └── user
│       ├── user.pb.go
│       ├── user.pb.micro.go
│       └── user.proto
└── router
    ├── router.go
    └── v1
        └── user.go

構建客戶端服務,分爲以下幾個步驟:

  1. 拷貝 proto 文件和生成文件

    第一步是拷貝服務端的 proto 文件和生成文件,目的是爲了保證服務端和客戶端的類型一致性。

  2. 定義客戶端服務

    第二步是定義客戶端:

    文件路徑:router/v1/user.go

    func NewUserClient() protoUser.UserService {
      // 創建服務
      service := grpc.NewService()
        
      // 創建客戶端
      userClient := protoUser.NewUserService("go.micro.srv.demo", service.Client())
        
      return userClient
    }
  3. rpc 調用遠程服務的方法

    第三步是 rpc 調用遠程服務的方法:

    文件路徑:router/v1/user.go

    client := NewUserClient()
        
    // rpc 調用遠程服務的方法
    resp, err := client.Login(context.TODO()&protoUser.LoginRequest{Email: param.Email, Password: param.Password})
    if err != nil {
      fmt.Println(err)
    }

完成以上 3 步,我們就已經基本編寫完客戶端的代碼。

03 

gin 和 go-micro 集成

接下來,我們介紹如何集成 gin 和 go-micro,該部分代碼也是在客戶端中,共需要兩個步驟。

  1. 創建路由

    文件路徑: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
    }
  2. 啓動(監聽)服務

    文件路徑: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)
      }
    }

至此,我們已經完成了集成 gin 和 go-micro,啓動服務端服務和客戶端服務後,我們就可以使用以下命令進行 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 

總結

本文我們主要介紹怎麼使用 go-micro 和 go-grpc 構建微服務,和怎麼集成 gin 和 go-micro,並沒有介紹 gin 和 go-micro 的使用方法,如果讀者朋友們還不瞭解 gin 和 go-micro,建議先閱讀 gin 和 go-micro 官方文檔,也可以參考公衆號之前推送的關於 gin 的文章。

參考資料:
https://github.com/asim/go-micro 
https://gin-gonic.com/zh-cn/docs/introduction/

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/xCFsKMHSlBG4ao1FM98n2w