Go-Micro微服務框架速學


1,引入外部框架gin生成web API

go版本為1.14

go-micro升級到1.14之后的一些變動和安裝方式,確保你開啟了go module模式

先裝
 go get github.com/micro/go-micro

然后裝plugins
go get github.com/micro/go-plugins

1,如果出現

 

 請參考 這個帖子: https://github.com/golang/go/issues/34394

解決方法:在go.mod里加入
replace github.com/gogo/protobuf v0.0.0-20190410021324-65acae22fc9 => github.com/gogo/protobuf v0.0.0-20190723190241-65acae22fc9d
然后再執行安裝:go get github.com/micro/go-plugins

2,如果出現 

則可以這樣:

首先安裝 (注意后面的@master)
 go get github.com/lucas-clemente/quic-go@master

 然后在go.mod里面找到 版本號  譬如是 
   github.com/lucas-clemente/quic-go v0.7.1-0.20191025234737-672328ca3059

然后 在go.mod里加入
replace github.com/lucas-clemente/quic-go => github.com/lucas-clemente/quic-go v0.7.1-0.20191025234737-672328ca3059

此時可以再次執行go get github.com/micro/go-micro (注意不要加-u)

有可能你會發現  go-plugins 木有consul相關內容;

那就只能這樣了: go get github.com/micro/go-plugins@master

Github地址: https://github.com/micro/go-micro

本課程一律使用go module的方式 安裝

package main

import (
    "github.com/gin-gonic/gin"
    "github.com/micro/go-micro/web"
)

func main(){

    ginRouter:=gin.Default()
    ginRouter.Handle("GET","/user", func(context *gin.Context) {
         context.String(200,"user api")
    })
    ginRouter.Handle("GET","/news", func(context *gin.Context) {
        context.String(200,"news api")
    })
    server:=web.NewService(
        web.Address(":8001"),
        web.Handler(ginRouter),
        )

    server.Run()

}

 

2,服務注冊:快速把服務注冊到etcd中

package main

import (
    "github.com/gin-gonic/gin"
    "github.com/micro/go-micro/registry"
    "github.com/micro/go-micro/registry/etcd"
    "github.com/micro/go-micro/web"
)

func main(){
     etcdReg := etcd.NewRegistry(registry.Addrs("127.0.0.1:2379"))

    ginRouter:=gin.Default()
    ginRouter.Handle("GET","/user", func(context *gin.Context) {
         context.String(200,"user api")
    })
    ginRouter.Handle("GET","/news", func(context *gin.Context) {
        context.String(200,"news api")
    })
    server:=web.NewService(
        web.Name("api.jtthink.com.prodservice"),
        web.Address(":8001"),
        web.Handler(ginRouter),
        web.Registry(etcdReg),
        )

    server.Run()

}

 

web.bat

set MICRO_REGISTRY=etcd
set MICRO_REGISTRY_ADDRESS=localhost:2379
set MICRO_API_NAMESPACE=api.jtthink.com
micro web

 

3,模擬運行API(主站API、商品API) 服務注冊 服務發現

服務注冊

首選編寫服務端  服務注冊到go-micro中

 

package ProdService

import "strconv"

type ProdModel struct {
    ProdID int
    ProdName string
}

func NewProd(id int,pname string ) *ProdModel  {
    return &ProdModel{ProdName:pname,ProdID:id}
}
func NewProdList(n int) []*ProdModel {
    ret:=make([]*ProdModel,0)
    for i:=0;i<n;i++{
        ret=append(ret,NewProd(100+i,"prodname"+strconv.Itoa(100+i)))
    }
    return ret
}
D:\gocode1.14.3\gocode\go-micro\ProdService\ProdModels.go
package main

import (
	"github.com/gin-gonic/gin"
	"github.com/micro/go-micro/registry"
	"github.com/micro/go-micro/registry/etcd"
	"github.com/micro/go-micro/web"
	"gomicro.jtthink.com/ProdService"
)

func main(){
	 etcdReg := etcd.NewRegistry(registry.Addrs("127.0.0.1:2379"))

	ginRouter:=gin.Default()
	v1Group:=ginRouter.Group("/v1")
	{
		v1Group.Handle("GET","/prods", func(context *gin.Context) {
			context.JSON(200,ProdService.NewProdList(5))
		})
	}
	server:=web.NewService(
		web.Name("prodservice"),
		web.Address(":8001"),
		web.Handler(ginRouter),
		web.Registry(etcdReg),
		)

	server.Run()

}

 go run ./prod_main.go

 

 服務發現

獲取consul服務列表、selector隨機選擇

                           

 

 test.go

package main

import (
    "fmt"
    "github.com/micro/go-micro/client/selector"
    "github.com/micro/go-micro/registry"
    "github.com/micro/go-micro/registry/etcd"
    "log"
)

func main()  {
    etcdReg := etcd.NewRegistry(registry.Addrs("127.0.0.1:2379"))
    getService,err:=etcdReg.GetService("prodservice")
    if err!=nil{
        log.Fatal(err)
    }
    next:=selector.Random(getService)
    node,err:=next()
    if err!=nil{
        log.Fatal(err)
    }
    fmt.Println(node.Id,node.Address,node.Metadata)


}
D:\gocode1.14.3\gocode\go-micro>go run test.go
6925a735-58c3-4148-92fa-d560d80d3bb7 192.168.1.101:8001 map[]

 

4,使用內置命令參數啟動,注冊多個服務

Go-micro 內置了 一些參數,可以在啟動時 指定,這樣就不用寫死了

譬如地址: 我們可以 這樣運行 go run prod_main.go --server_address :8001 別忘了,加上 server.Init()

server:=web.NewService(
		web.Name("prodservice"),
		//web.Address(":8001"),
		web.Handler(ginRouter),
		web.Registry(etcdReg),
		)

	server.Init()
	server.Run()

  

開啟多個服務,用輪訓方式獲取服務

服務端:

package main

import (
    "github.com/gin-gonic/gin"
    "github.com/micro/go-micro/registry"
    "github.com/micro/go-micro/registry/etcd"
    "github.com/micro/go-micro/web"
    "gomicro.jtthink.com/ProdService"
)

func main(){
     etcdReg := etcd.NewRegistry(registry.Addrs("127.0.0.1:2379"))

    ginRouter:=gin.Default()
    v1Group:=ginRouter.Group("/v1")
    {
        v1Group.Handle("GET","/prods", func(context *gin.Context) {
            context.JSON(200,ProdService.NewProdList(5))
        })
    }
    server:=web.NewService(
        web.Name("prodservice"),
        //web.Address(":8001"),
        web.Handler(ginRouter),
        web.Registry(etcdReg),
        )

    server.Init()
    server.Run()

}

啟動服務 並注冊服務

go run prod_main.go --server_address :8001

go run prod_main.go --server_address :8002

go run prod_main.go --server_address :8003

客戶端:

用輪訓方式調用服務

package main

import (
    "fmt"
    "github.com/micro/go-micro/client/selector"
    "github.com/micro/go-micro/registry"
    "github.com/micro/go-micro/registry/etcd"
    "log"
    "time"
)

func main()  {
    //etcdReg := etcd.NewRegistry(registry.Addrs("127.0.0.1:2379"))
    //getService,err:=etcdReg.GetService("prodservice")
    //if err!=nil{
    //    log.Fatal(err)
    //}
    //next:=selector.Random(getService)
    //node,err:=next()
    //if err!=nil{
    //    log.Fatal(err)
    //}
    //fmt.Println(node.Id,node.Address,node.Metadata)

    for {
        etcdReg := etcd.NewRegistry(registry.Addrs("127.0.0.1:2379"))
        getService,err:=etcdReg.GetService("prodservice")
        if err!=nil{
            log.Fatal(err)
        }
        next:=selector.RoundRobin(getService)
        node,err:=next()
        if err!=nil{
            log.Fatal(err)
        }
        fmt.Println( node.Address)
        time.Sleep(time.Second*1)
    }
}

 

D:\gocode1.14.3\gocode\go-micro>go run  test.go
192.168.1.101:8002
192.168.1.101:8001
192.168.1.101:8003
192.168.1.101:8002
192.168.1.101:8001
192.168.1.101:8003

 

啟動web管理界面:

web.bat

set MICRO_REGISTRY=etcd
set MICRO_REGISTRY_ADDRESS=localhost:2379
set MICRO_API_NAMESPACE=prodservice
micro web

 

5,服務調用:基本方式調用 Api(http api)

 

package main

import (
    "fmt"
    "github.com/micro/go-micro/v2/client/selector"
    "github.com/micro/go-micro/v2/registry/etcd"
    "github.com/micro/go-micro/v2/registry"
    "io/ioutil"
    "log"
    "net/http"
)

func callAPI(addr string,path string,method string) (string,error)  {
    req,_:=http.NewRequest(method,"http://"+addr+path,nil)
    client:=http.DefaultClient
    res,err:=client.Do(req)
    if err!=nil{
        return "",err
    }
    defer res.Body.Close()
    buf,_:= ioutil.ReadAll(res.Body)
    return string(buf),nil
}
func main()  {
    etcdReg := etcd.NewRegistry(registry.Addrs("127.0.0.1:2379"))
    getService,err:=etcdReg.GetService("prodservice")
    if err!=nil{
        log.Fatal(err)
    }
    next:=selector.Random(getService)
    node,err:=next()
    if err!=nil{
        log.Fatal(err)
    }
    fmt.Println(node.Id,node.Address,node.Metadata)

    callRes,err:=callAPI(node.Address,"/v1/prods","GET")
    if err!=nil{
        log.Fatal(err)
    }
    fmt.Println(callRes)

    //for {
    //    etcdReg := etcd.NewRegistry(registry.Addrs("127.0.0.1:2379"))
    //    getService,err:=etcdReg.GetService("prodservice")
    //    if err!=nil{
    //        log.Fatal(err)
    //    }
    //    next:=selector.RoundRobin(getService)
    //    node,err:=next()
    //    if err!=nil{
    //        log.Fatal(err)
    //    }
    //    fmt.Println( node.Address)
    //    time.Sleep(time.Second*1)
    //}
}

返回結果:

D:\gocode1.14.3\gocode\go-micro>go run  test.go
0b93cd42-ba4d-4dcc-afee-73eb00e87547 192.168.1.101:8002 map[]
[{"ProdID":100,"ProdName":"prodname100"},{"ProdID":101,"ProdName":"prodname101"},{"ProdID":102,"ProdName":"prodname102"},
{"ProdID":103,"ProdName":"prodna me103"},{"ProdID":104,"ProdName":"prodname104"}]

 

 服務調用_ 使用插件、調用http api的正規姿勢(初步)

 使用插件

 

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

這里面包含了很多go-micro可選插件。譬如服務注冊中心要選擇etcd、eureka等,就需要使用到插件(當然,手工玩耍也行)

安裝go get github.com/micro/go-plugins
這個不多說了

 

http 包

對應的http調用包: import myhttp "github.com/micro/go-plugins/client/http " 此包除了有 http client基本功能,還支持Selector參數,

自動選取服務,並支持json、protobuf等數據格式

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM