一. 环境准备。
- 创建一个
consul
服务中间件。
//拉取镜像
docker pull consul
//实例化镜像
docker run -d --name=cs -p 8500:8500 consul agent -server -bootstrap -ui -client 0.0.0.0
浏览器输入IP:8500
,打开consul可视化web。
二. 实现服务端。
- 服务端代码。
package main
import (
"github.com/micro/go-micro/web"
"github.com/gin-gonic/gin"
"log"
"github.com/micro/go-micro/registry"
"github.com/micro/go-plugins/registry/consul"
"go-micro-http/ProdService"
"go-micro-http/Helper"
)
func main(){
//consul注册中心
consulReg := consul.NewRegistry(
registry.Addrs("192.168.56.10:8500"),
)
//gin 路由
ginRouter := gin.Default()
v1Group := ginRouter.Group("/v1")
v1Group.Handle("POST", "/prods", func(context *gin.Context){
//请求对象
var pr Helper.ProdsRequest
//获取请求参数
err := context.Bind(&pr)
//默认为2个
if err!=nil || pr.Size<=0 {
pr = Helper.ProdsRequest{Size:2}
}
//返回JSON
context.JSON(200,
gin.H{
"data": ProdService.NewProdList(pr.Size), //自定义函数,生成prod列表
})
})
//创建web服务器
server := web.NewService(
web.Name("prodservice"), // 服务名
//web.Address(":8001"),
web.Handler(ginRouter), // 路由
web.Metadata(map[string]string{"protocol": "http"}), // 添加这行代码
web.Registry(consulReg), // 注册服务
)
//初始化服务器
server.Init()
//运行
err := server.Run()
if err != nil{
log.Panic(err)
}
}
- 这是
ProdModel
代码。
package ProdService
import "strconv"
//产品model
type ProdModel struct {
ProdID int //产品id
ProdName string //产品名称
}
//实例化对象
func NewProd(id int,pname string) *ProdModel {
return &ProdModel{
ProdID: id,
ProdName: pname,
}
}
//生成产品列表
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
}
- 运行。
//创建两个node
go run main.go --server_address :8001
go run main.go --server_address :8002
4. 测试。
三. 实现客户端。
- 客户端代码。
package main
import (
"github.com/micro/go-micro/registry"
"github.com/micro/go-plugins/registry/consul"
"log"
"github.com/micro/go-micro/client/selector"
"fmt"
myhttp "github.com/micro/go-plugins/client/http"
"github.com/micro/go-micro/client"
"context"
)
func main() {
//注册中心
consulReg := consul.NewRegistry(
registry.Addrs("192.168.56.10:8500"),
)
//创建Selector
mySelector := selector.NewSelector(
selector.Registry(consulReg),
//这里才用轮询算法,均衡分发请求
selector.SetStrategy(selector.RoundRobin),
)
callAPI2(mySelector)
}
//请求API
func callAPI2(s selector.Selector){
//创建Client
myClient := myhttp.NewClient(
client.Selector(s),
client.ContentType("application/json"),
)
//创建Request
req := myClient.NewRequest("prodservice", "/v1/prods", map[string]interface{}{"size":3})
var rsp map[string]interface{}
//请求
err := myClient.Call(context.Background(), req, &rsp)
if err != nil{
log.Fatal(err)
}
//打印
fmt.Println(rsp)
}
- 这是请求参数对象代码。
package Helper
type ProdsRequest struct {
//size参数,指定生成n个产品的列表
Size int `form:"size"`
}
3.运行。
//执行命令
go run test.go
//结果
map[data:[map[ProdID:100 ProdName:prodname100] map[ProdID:101 ProdName:prodname101] map[ProdID:102 ProdName:prodname102]]]
总结
昨天在B站上淘了一门新课,老师讲得真不错,循循善诱,让我搞明白了一点consul的概念,consul是真的强大,免去服务注册一系列繁琐的操作,内置负载均衡算法机制。
不过我听说由于Micro团队在版本迭代过程中发现使用Consul存在一些问题,这些改动起来可能比较大,所以现在Micro的服务发现已经不支持Consul,大家都转用etcd了。
教程用的是consul,我打算学完再看看etcd。
学习教程: https://www.bilibili.com/video/BV1E7411d7wr
git地址: https://gitee.com/php_is_no1/go-micro-http