在構(gòu)建微服務(wù)時株婴,使用服務(wù)發(fā)現(xiàn)可以減少配置的復(fù)雜性溺欧,本文以go-micro為微服務(wù)框架揖铜,使用etcd作為服務(wù)發(fā)現(xiàn)服務(wù)茴丰,使用gin開發(fā)golang服務(wù)。
使用gin 的原因是gin能夠很好的和go-micro進行集成天吓。
本文主要介紹服務(wù)注冊和發(fā)現(xiàn)的實現(xiàn)
關(guān)于如何搭建etcd服務(wù)可以看歷史文章
本文默認(rèn)以搭建好了etcd服務(wù)贿肩,服務(wù)的地址是:192.168.109.131:12379
如果你搭建好了自己的etcd服務(wù),可以按照上面文章的步驟做失仁,會看到如下界面:
這里我的etcd服務(wù)啟用了 3個節(jié)點尸曼。
開擼
服務(wù)注冊
我們預(yù)設(shè)兩個server,userserver和orderserver
下面開始上代碼:
userserver程序結(jié)果如下:
有兩個文件router.go和main.go
main.go代碼如下
main.go實現(xiàn)初始化路由萄焦,服務(wù)注冊
package main
import (
"github.com/micro/go-micro/registry"http://
"github.com/micro/go-micro/web"http://
"github.com/micro/go-micro/registry/etcd"http://
"userserver/routers"
)
var etcdReg registry.Registry
func init() {
//新建一個consul注冊的地址控轿,也就是我們consul服務(wù)啟動的機器ip+端口
etcdReg = etcd.NewRegistry(
registry.Addrs("192.168.109.131:12379"),
)
}
func main() {
//初始化路由
ginRouter := routers.InitRouters()
//注冊服務(wù)
microService:= web.NewService(
web.Name("api.tutor.com.userserver"),
//web.RegisterTTL(time.Second*30),//設(shè)置注冊服務(wù)的過期時間
//web.RegisterInterval(time.Second*20),//設(shè)置間隔多久再次注冊服務(wù)
web.Address(":18001"),
web.Handler(ginRouter),
web.Registry(etcdReg ),
)
microService.Run()
}
router.go代碼如下
router.go主要用來定義程序的api接口,使用gin開發(fā)
package routers
import "github.com/gin-gonic/gin"
func InitRouters() *gin.Engine {
ginRouter := gin.Default()
ginRouter.POST("/users/", func(context *gin.Context) {
context.String(200, "get userinfos")
})
return ginRouter
}
注冊的代碼就寫好了拂封,啟動userserver茬射,我們在micro的服務(wù)界面,可以看到如下效果:
說明我們注冊成功了
服務(wù)發(fā)現(xiàn)
服務(wù)發(fā)現(xiàn)冒签,就是從etcd中獲取到我們注冊進去的服務(wù)在抛,這樣在調(diào)用別的服務(wù)時,就不用從配置文件獲取萧恕,直接查詢etcd即可刚梭。
orderserver我們除了實現(xiàn)服務(wù)注冊外,也實現(xiàn)服務(wù)發(fā)現(xiàn)的功能
orderserver代碼結(jié)構(gòu)如下:
上代碼
main.go代碼如下
package main
import (
"bytes"
"fmt"
"github.com/micro/go-micro/client/selector"
"github.com/micro/go-micro/registry"
"github.com/micro/go-micro/web"
"github.com/micro/go-micro/registry/etcd"
"net/http"
"orderserver/routers"
"time"
)
var etcdReg registry.Registry
func init(){
//新建一個consul注冊的地址票唆,也就是我們consul服務(wù)啟動的機器ip+端口
etcdReg = etcd.NewRegistry(
registry.Addrs("192.168.109.131:12379"),
)
}
func main() {
//初始化路由
ginRouter := routers.InitRouters()
//注冊服務(wù)
microService:= web.NewService(
web.Name("api.tutor.com.orderserver"),
//web.RegisterTTL(time.Second*30),//設(shè)置注冊服務(wù)的過期時間
//web.RegisterInterval(time.Second*20),//設(shè)置間隔多久再次注冊服務(wù)
web.Address(":18002"),
web.Handler(ginRouter),
web.Registry(etcdReg ),
)
//獲取服務(wù)地址
hostAddress := GetServiceAddr("api.tutor.com.userserver")
if len(hostAddress) <= 0{
fmt.Println("hostAddress is null")
}else{
url := "http://"+ hostAddress + "/users"
response, _ := http.Post(url, "application/json;charset=utf-8",bytes.NewBuffer([]byte("")))
fmt.Println(response)
}
microService.Run()
}
func GetServiceAddr(serviceName string)(address string){
var retryCount int
for{
servers,err :=etcdReg.GetService(serviceName)
if err !=nil {
fmt.Println(err.Error())
}
var services []*registry.Service
for _,value := range servers{
fmt.Println(value.Name, ":", value.Version)
services = append(services, value)
}
next := selector.RoundRobin(services)
if node , err := next();err == nil{
address = node.Address
}
if len(address) > 0{
return
}
//重試次數(shù)++
retryCount++
time.Sleep(time.Second * 1)
//重試5次為獲取返回空
if retryCount >= 5{
return
}
}
}
GetServiceAddr就是服務(wù)發(fā)現(xiàn)的代碼
首先朴读,使用servers,err :=consulReg.GetService(serviceName)獲取注冊的服務(wù)
返回的servers是個slice
然后,使用next := selector.RoundRobin(services)獲取其中一個服務(wù)的信息
這里注意:
在老版本中可以直接使用selector.RoundRobin(services)走趋,但是在v2版本中需要做個轉(zhuǎn)換處理:
var services []*registry.Service
for _,value := range servers{
fmt.Println(value.Name, ":", value.Version)
services = append(services, value)
}
因為使用的數(shù)據(jù)結(jié)構(gòu)不同衅金,感興趣的可以細(xì)看下區(qū)別。
router.go代碼如下
package routers
import "github.com/gin-gonic/gin"
func InitRouters() *gin.Engine {
ginRouter := gin.Default()
ginRouter.POST("/orders/", func(context *gin.Context) {
context.String(200, "get orderinfos")
})
return ginRouter
}
啟動oerderserver 我們就能獲取到userserver的地址,各位可以調(diào)試看下效果氮唯。
今天go-micro+gin+etcd微服務(wù)實戰(zhàn)就介紹完了鉴吹,是不是很簡單