Go語言微服務實戰之micro微服務框架

之前的文章我們大致瞭解了微服務,同時我們還準備好了一臺搭載CentOS系統的雲服務器,這篇文章我們正式開始微服務的實踐之旅。

一提到微服務,首先想到的就是Spring Cloud,阿里的Dubbo等。與go語言相比,java的一個巨大優勢就是生態系統非常成熟,有很多成熟的商業級框架可供使用,go相對而言比較新,因此生態上還不如java那麼完善,但是這並不妨礙我們學習微服務,在github上已經有一些開源的go微服務框架可以使用,比如go micro,go kit,go chassis等,這裏我們選擇go micro,在寫這篇文章的時候,這個開源微服務框架在github上已經有多達12.9K的Star數,一個微服務框架該有的東西基本上全都具備了,是入門微服務非常不錯的一個開源項目。

1、認識micro微服務框架

如果想深入學習,最好的方法是先蕩一份源碼研究,go micro的主頁:

https://github.com/micro/go-micro

初學者可以先不急着一上來就去挖原理,先學會如何使用,然後在循序漸進,建議初學者先點開下面的鏈接仔細看一遍文檔:

https://micro.mu/docs/framework.html

micro滿足分佈式系統開發的核心需求,在設計上採用插件化的方式,一些核心功能諸如消息中間件、服務註冊及發現等都是可插拔的,micro提供默認實現,但是開發者可以根據自己的需求隨意替換。

我們來看看micro的主要特點:

(1) 服務發現:micro支持自動化的服務發現和域名解析。服務發現在微服務開發中處於核心地位,正如我們在第一篇文章所說,當微服務獨立部署在不同機器上的時候,服務A想要和服務B通信就必須要知道服務B所在的機器。micro提供了基於mDNS的服務發現的默認實現,當然你可以使用其他插件甚至自己編寫插件來滿足自己的需求。

(2) 負載均衡:通常一個商業級的應用,因爲用戶量較大,一些核心服務往往會部署在多臺機器上,這就涉及到負載均衡的問題,大量的請求不能落地到某一臺機器上,而是用某種負載均衡策略分攤到所有的機器上去。micro提供了基於隨機哈希的負載均衡策略,當發現某臺機器有問題時會選擇另外一臺機器進行重試。

(3) RPC:micro對同步通信進行了抽象,客戶端到服務端的請求會被自動解析並做負載均衡,默認採用gRPC做爲RPC通道。

(4) 異步消息:micro支持消息的發佈-訂閱,這個也是可插拔的,你可以用Kafka,RabbitMQ等任何你熟悉的消息中間件發送異步消息。

(5) 插件化:諸如服務發現、負載均衡、消息中間件等這些分佈式系統開發中的核心組件,micro都做了抽象,可以根據自己的需求實現接口去替換,當然社區也已經有很多現成的插件供開發者使用。

2、Hello,Micro

這一節,我們就用經典的Hello world的方式來看看如何編寫一個最簡單的微服務。

2.1 開發環境

我們假定讀者已經是go語言的開發者,這個系列的文章我們不會介紹go語法相關的知識。我們以GoLand IDE爲例。

go版本1.14,GoLand版本2020.1.2

首先,新建一個工程,建好之後在GoLand中開啓go module,並且添加環境變量:GOPROXY = https://goproxy.cn,在Mac上可以通過Preferences -> Go Modules來設置:

2.2 初始化模塊

我們在工程中新建一個模塊micro,新建一個文件夾micro,然後命令行:

go mod init micro

然後我們會在項目根目錄下看到一個go.mod的文件文件。

2.3 編寫協議文件

micro是基於google protobuf的,因此我們需要先編寫.proto的協議文件:

syntax = "proto3";

package pb;

// 定義微服務對外提供的接口
service Greeter {

    rpc Hello(Request) returns (Response) {}
}

// 請求
message Request {
    string name = 1;
}

// 響應
message Response {
    string msg = 1;
}

是不是很簡單,你的服務想提供什麼能力,就用接口定義出來(包括參數等),我們在項目中新建一個proto目錄,將協議文件放在這裏,目錄結構如下,其中pbfile目錄存放.proto,pb目錄則保存生成的代碼:

接下來我們需要根據這份.proto協議生成代碼,爲了生成micro特定的代碼,需要先在開發機上安裝protobuf以及一些相關工具:

brew install protobuf
go get -u github.com/golang/protobuf/proto
go get -u github.com/golang/protobuf/protoc-gen-go
go get github.com/micro/micro/v2/cmd/protoc-gen-micro@master

所有必須的工具都安裝好之後,在命令行敲入命令來生成代碼: 

protoc --proto_path=$GOPATH/src:./proto/pbfile --go_out=./proto/pb --micro_out=./proto/pb hello.proto

--proto_path指定了要在哪些目錄中尋找.proto協議文件,--go_out和--micro_out指定了文件的輸出目錄。

2.4 編寫微服務

終於到了手撕第一個微服務的時刻了,因爲功能非常簡單,我們直接上代碼,相信大家都能秒懂實在不懂的也沒關係,複製到IDE裏先運行起來也可以。在項目中新建server/main目錄,在此目錄下新建main.go,把以下代碼複製進去:

package main

import (
	"context"
	"fmt"
	"github.com/micro/go-micro/v2"
	"micro/proto/pb"
)

type Greeter struct {}

func (g *Greeter) Hello(ctx context.Context, req *pb.Request, rsp *pb.Response) error  {
	//把客戶端的請求回射給客戶端
	rsp.Msg = req.Name
	return nil
}

func main() {

	// 新創建一個服務,服務名爲greeter,服務註冊中心會用這個名字來發現服務
	service := micro.NewService(
		micro.Name("greeter"),
	)

	// 初始化
	service.Init()

	// 註冊處理器
	pb.RegisterGreeterHandler(service.Server(), new(Greeter))

	// 啓動服務運行
	if err := service.Run(); err != nil {
		fmt.Println(err)
	}
}

總結一下主要的點:

(1) 定義結構體,實現協議文件中定義的接口;

(2) 使用micro.NewService創建一個微服務,必須要指定一個服務名,如果一個系統有多個微服務,請注意不要重名,這個名字是用來做服務發現用的;

(3) 將我們實現了協議接口的結構體註冊到micro;

(4) 最後啓動服務運行;

現在,我們運行一下試試,在終端使用go run server/main/main.go運行程序,可以看到以下輸出:

從控制檯輸出的日誌中可以看到服務使用grpc,在54836端口上監聽請求,同時可以看到我們在mdns上註冊了一個節點,這樣客戶端就能通過mdns發現我們的微服務並調用接口。此前我們說過micro的服務發現與註冊中心是可以通過插件化的方式替換的,在後續的文章中我們會用kubernetes做爲服務註冊中心,替換micro默認的mdns。

2.5 編寫客戶端

最後我們寫個客戶端程序來調用上面的微服務,在項目中新建client/main目錄,在此目錄下新建main.go文件,把以下代碼拷貝過去:

package main

import (
	"context"
	"fmt"
	"github.com/micro/go-micro/v2"
	"micro/proto/pb"
)

func main() {

	// 創建一個服務
	service := micro.NewService(micro.Name("greeter.client"))
	// 初始化
	service.Init()
	// 創建一個微服務的客戶端
	greeter := pb.NewGreeterService("greeter", service.Client())
	// 調用微服務
	rsp, err := greeter.Hello(context.TODO(), &pb.Request{Name: "Hello Micro"})
	if err != nil {
		fmt.Println(err)
	}

	fmt.Println(rsp.Msg)
}

同樣我們先創建並初始化一個客戶端服務,注意名字與服務端不同,然後調用服務接口,並在控制檯打印服務的響應,在終端運行該程序,在控制檯上看到以下輸出:

如果你順利完成了這一步,那麼恭喜,你已經開發出了自己的第一個微服務,雖然它幾乎什麼也沒有做。

2.6 使用micro來運行微服務

前面我們在自己的開發機上本地編譯運行微服務,我們還可以用micro工具集來啓動微服務,micro有一套完備的工具集供我們使用,我們先安裝一下:

go install github.com/micro/micro/v2

安裝完成以後,我們來嘗試運行一下剛纔的服務:

在終端運行:

micro server

然後,在打開一個終端,運行:

micro run server/main/

指定我們的微服務代碼所在的目錄即可,此時可以在終端看到以下輸出:

我們用micro工具集一樣運行起了我們的微服務。

然後我們利用工具來查看一下有哪些服務,在終端敲以下命令:

micro list services

輸出如下:

可以看到默認已經啓動了不少的服務,我們的greeter服務位於最下面。

現在查看一下這個服務的詳細信息,在終端鍵入下面的命令:

micro get service greeter

看到以下輸出:

詳細信息一目瞭然。

最後咱們試着調用一下:

這次我們得到了JSON格式的輸出。

3、總結

這篇文章我們實操了第一個微服務例子,並用不同的方式運行了它,完整的跑通這個簡單的示例後,相信你對微服務的認識又進了一步。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章