go微服務系列(二) - 服務註冊/服務發現

1. 服務註冊

1.1 代碼演示

仍是跟上一篇:go微服務(一) - go micro入門同樣使用consulhtml

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() {
    // 1.添加consul地址
	cr := consul.NewRegistry(
		registry.Addrs("127.0.0.1:8500"))
    
    // 2.使用gin做爲router
	router := gin.Default()
	router.GET("/user", func(c *gin.Context) {
		c.String(http.StatusOK, "user api")
	})
    
    // 3.初始化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()
}

1.2 在go run的時候傳入服務註冊的參數

上面爲了演示簡便,直接將服務註冊的服務名端口等寫死在代碼裏,可是實際運用場景不可能這麼寫,因此咱們通常會git

  • 把這部分定義在配置文件裏
  • 使用go micro提供的功能,能夠在go run的時候傳入參數

下面演示下如何在go run的時候傳入參數github

第一步web

在原來的服務註冊的基礎代碼上添加server.Init()算法

加上這個就會解析cli命令中的參數shell

以下導航到源碼看下具體的實現,就是添加了Init()方法以後,會將咱們傳入的cli命令的特定參數,進行註冊,優先級高於代碼定義的api

第二步dom

這裏選擇改變下服務註冊的端口,即在main包路徑下執行如下命令,且開兩個tab執行兩次微服務

# tab1
 go run productService_main.go --server_address :8088
 # tab2
 go run productService_main.go --server_address :8089

以下運行成功:測試

而後去consul界面查看,兩個實例都註冊成功:


2. 服務發現均衡負載

2.1 均衡負載算法

go-micro的服務發現的算法由github.com/micro/go-micro/client/selector下的selector提供,目前提供了兩種算法

  • RoundRobin(輪詢算法)
  • Random(隨機算法)

2.2 服務發現均衡負載的演示

使用上一節的方式,服務註冊部分,同時啓動了如下三個端口的productService服務

  • 8088
  • 8089
  • 8090

而後在服務發現部分

  • 使用selector.Random來隨機發現服務
  • 使用for循環來持續獲取
  • 打印出當前獲取到的服務實例的端口
func main() {
          // 1.鏈接到consul
	cr := consul.NewRegistry(registry.Addrs("127.0.0.1:8500"))

        //  使用for循環持續獲取
	for {
		// 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.Address)
		time.Sleep(time.Second * 1)
	}
}

因此輸出的實例端口能夠看以下,隨機獲取到三個端口中的任意一個

這時候吧8090端口的服務給關掉,再看下輸出,就不會有8090端口的實例了

相關文章
相關標籤/搜索