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 }
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等数据格式
本文来自博客园,作者:孙龙-程序员,转载请注明原文链接:https://www.cnblogs.com/sunlong88/p/12952907.html