1. 程式人生 > >go微服務系列(一) go micro入門

go微服務系列(一) go micro入門

- [1. 什麼是go micro](#head1) - [1.1 go micro作用](#head2) - [1.2 go micro架構組成](#head3) - [2. go micro入門](#head4) - [3. 結合consul進行服務註冊/發現](#head5) - [3.1 consul的安裝](#head6) - [3.2 服務註冊程式碼示例](#head7) - [3.2 服務發現程式碼示例](#head8) ## 1. 什麼是go micro ### 1.1 go micro作用 它是一個可插入的RPC框架,用於在Go中編寫微服務。開箱即用,您將收到: - **服務發現**: 應用程式自動註冊到服務發現系統 - **負載平衡**: 客戶端負載平衡,用於平衡服務例項之間的請求 - **同步通訊**: 提供請求 / 響應傳輸層。 - **非同步通訊**: 內建釋出 / 訂閱功能。 - **訊息編碼**: 基於訊息的內容型別頭的編碼 / 解碼。 - **RPC 客戶機/伺服器包**: 利用上述功能並公開介面來構建微服務 ### 1.2 go micro架構組成 Go 微體系結構可以描述為三層堆疊 ![](https://tva1.sinaimg.cn/large/007S8ZIlgy1ghjrbgs38oj30eb07rq35.jpg) 頂層由客戶端-伺服器模型和服務抽象組成。 - **伺服器**: 用於編寫服務的構建塊 - **客戶端**: 提供了向服務請求的介面。 底層由以下型別的外掛組成: - **代理**: 為非同步釋出/訂閱通訊提供訊息代理的介面。 - **編解碼器**: 用於編碼/解碼訊息。支援的格式包括 json,bson,protobuf,msgpack 等。 - **登錄檔**: 提供服務發現機制(預設為 Consul) - **選擇器**: 建立在登錄檔上的負載平衡抽象。它允許使用諸如隨機,輪循,最小康等演算法來 “選擇” 服務。 傳輸 - 服務之間同步請求 / 響應通訊的介面。 - `Go Micro`還提供了`Sidecar`等功能。這使您可以使用`Go`以外的語言編寫的服務 > Sidecar提供服務註冊,gRPC編碼/解碼和HTTP處理程式。它支援多種語言。 ## 2. go micro入門 最簡單的用法大概如下,結合`net/http`標準庫監聽路由 ```go package main import ( "github.com/micro/go-micro/web" "net/http" ) func main() { server := web.NewService(web.Address(":8081")) // 路由 server.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("hello go micro")) }) _ = server.Run() } ``` 也可以整合第三方web框架作為路由 - 比如`gin` ```go package main import ( "net/http" "github.com/gin-gonic/gin" "github.com/micro/go-micro/web" ) func main() { // 使用gin作為路由 r := gin.Default() r.GET("/user", func(c *gin.Context) { c.String(http.StatusOK, "user api") }) server := web.NewService( web.Address(":8081"), // 埠 web.Metadata(map[string]string{"protocol": "http"}), // 元資訊 web.Handler(r)) // 路由 _ = server.Run() } ``` ## 3. 結合consul進行服務註冊/發現 微服務裡最重要的關鍵一步就是**服務註冊** > 常用的有consul、etcd、zookeeper、eureka 我們這裡使用consul ### 3.1 consul的安裝 這裡直接使用docker安裝 ```shell docker run -d --name=cs -p 8500:8500 consul agent -server -bootstrap -ui -client 0.0.0.0 ``` 然後再訪問埠8500,如下現實安裝成功 ![](https://tva1.sinaimg.cn/large/007S8ZIlgy1ghjqvv4gxxj31h80j0ta0.jpg) ### 3.2 服務註冊程式碼示例 > `github.com/micro/go-micro/registry/consul`
上面這個在1.14.0版本之後刪除了,要用這個`github.com/micro/go-plugins/registry/consul`,或者換成etcd作為註冊中心 ```go package main import ( "net/http" "github.com/gin-gonic/gin" "github.com/micro/go-micro/registry" "github.com/micro/go-micro/web" "github.com/micro/go-plugins/registry/consul" ) func main() { // 新增consul地址 cr := consul.NewRegistry( registry.Addrs("127.0.0.1:8500")) // 使用gin作為router router := gin.Default() router.GET("/user", func(c *gin.Context) { c.String(http.StatusOK, "user api") }) // 初始化go micro server := web.NewService( web.Name("productService"), // 當前微服務服務名 web.Registry(cr), // 註冊到consul web.Address(":8081"), // 埠 web.Metadata(map[string]string{"protocol": "http"}), // 元資訊 web.Handler(router)) // 路由 _ = server.Run() } ``` 把上述程式碼執行起來,再去`consul`介面檢視,發現`productService`服務新增成功 ![](https://tva1.sinaimg.cn/large/007S8ZIlgy1ghjsef8s11j30v50cfjs9.jpg) 然後把程式碼停掉,再去`consul`介面檢視,`productService`就沒了,非常方便 ### 3.2 服務發現程式碼示例 ```go package main import ( "fmt" "log" "github.com/micro/go-micro/client/selector" "github.com/micro/go-micro/registry" "github.com/micro/go-plugins/registry/consul" ) func main() { // 1.連線到consul cr := consul.NewRegistry(registry.Addrs("127.0.0.1:8500")) // 2.根據service name獲取對應的微服務列表 services, err := cr.GetService("productService") if err != nil { log.Fatal("cannot get service list") } // 3.使用random隨機獲取其中一個例項 next := selector.Random(services) svc, err := next() if err != nil { log.Fatal("cannot get service") } fmt.Println("[測試輸出]:", svc.Id, svc.Address, svc.Metadata) } ``` 然後使用goland先啟動**服務註冊**中的`productService`的微服務,再啟動**服務發現**中的程式碼。 服務發現將會輸出如下,服務發現成功: ![](https://tva1.sinaimg.cn/large/007S8ZIlgy1ghjuv1uzgrj30oo05ua