• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

go-micro报500

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

server.go

package main

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

func main() {
	consulReg := consul.NewRegistry( //新建一个consul注册的地址,也就是我们consul服务启动的机器ip+端口
		registry.Addrs("127.0.0.1:8500"),
	)
	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")
	})

	v1Group := ginRouter.Group("/v1")
	{
		v1Group.Handle("POST", "/prods", func(context *gin.Context) {
			//rq := Helper.NewRequest()
			//context.bind(rq) //使用自定义的结构体解析post表单
			context.JSON(
				200,
				gin.H{
					"data":2,
				},
			)
		})
	}


	//其实下面这段代码的意义就是启动服务的同时把服务注册进consul中,做的是服务发现
	server := web.NewService( //go-micro很灵性的实现了注册和反注册,我们启动后直接ctrl+c退出这个server,它会自动帮我们实现反注册
		web.Name("httpprodservice"), //注册进consul服务中的service名字
		web.Address(":8088"), //注册进consul服务中的端口,也是这里我们gin的server地址
		web.Handler(ginRouter),  //web.Handler()返回一个Option,我们直接把ginRouter穿进去,就可以和gin完美的结合
		web.Registry(consulReg), //注册到哪个服务器伤的consul中
		
	)
	server.Init() //加了这句就可以使用命令行的形式去设置我们一些启动的配置
	server.Run()
}

  client.go

 

package main

import (
	"context"
	"github.com/micro/go-micro/client"
	"github.com/micro/go-micro/client/selector"
	"github.com/micro/go-micro/registry"
	"github.com/micro/go-micro/registry/consul"
	myhttp "github.com/micro/go-plugins/client/http"
	"log"
)

func callAPI(s selector.Selector) {
	myCli := myhttp.NewClient(
		client.Selector(s),
		client.ContentType("application/json"), //因为我们要调用的/v1/prods这个api返回的是json,要先规定好数据格式json(很重要,如果是其他的会报错)
	)
	//下面这句代码封装了一个请求(未发送)
	req := myCli.NewRequest("httpprodservice", "/v1/prods", map[string]string{})//这里最后一个参数是body,一般用于post请求的参数,因为我们这个api没有参数,所以我随便写了map[string]string{}
	//从之前的图可以看到我们的返回值是一个json,key-val为"data":[],所以我们的response要构建一个相同结构的,方便go-micro帮我们返回响应结构体map[string]int{"Size": 4},这里的key大小写都可以,只要和request结构体该字段字母一样就行入 abcd:3 Abcd:3 ABCD:3都可以
	var resp map[string]interface{}
	log.Println("===req===")
	log.Println(req)
	log.Println("===context====")
	log.Println(context.Background())
	err := myCli.Call(context.Background(), req, &resp) //发起请求调用,并返回结果
	if err != nil {
		log.Fatal(err)
	}
	log.Println(resp)
}

func main() {
	consulReg:=consul.NewRegistry(func(options *registry.Options) {
		options.Addrs=[]string{
			"127.0.0.1:8500",
		}
	})
	mySelector := selector.NewSelector(
		selector.Registry(consulReg),
		selector.SetStrategy(selector.Random), //设置查询策略,这里是轮询
	)
	log.Println("===sel===")
	log.Println(mySelector)
	callAPI(mySelector)
}

  go run server.go --server_address :8001

  go run client.go

  结果客户端报

{"id":"go.micro.client","code":500,"detail":"none available","status":"Internal Server Error"}

  将consul换成etcd,发现也是报

{"id":"go.micro.client","code":500,"detail":"none available","status":"Internal Server Error"}

  后来通过查看源码 pkg\mod\github.com\micro\go-plugins\client\[email protected]\http.go

  大概在63行左右

	// only get the things that are of mucp protocol
	selectOptions := append(opts.SelectOptions, selector.WithFilter(
		selector.FilterLabel("protocol", "http"),
	))

  会添加过滤器 pkg\mod\github.com\micro\[email protected]\client\selector\default.go 的 

Select()  大概在56行
	// apply the filters
	for _, filter := range sopts.Filters {
		services = filter(services)
	}

  

里面的进行过滤
查看 pkg\mod\github.com\micro\[email protected]\client\selector\filter.go
func FilterLabel(key, val string) 方法, key是protocol val是http
// FilterLabel is a label based Select Filter which will
// only return services with the label specified.
func FilterLabel(key, val string) Filter {
	return func(old []*registry.Service) []*registry.Service {
		var services []*registry.Service

		for _, service := range old {
			serv := new(registry.Service)
			var nodes []*registry.Node

			for _, node := range service.Nodes {
				if node.Metadata == nil {
					continue
				}

				if node.Metadata[key] == val {
					nodes = append(nodes, node)
				}
			}

			// only add service if there's some nodes
			if len(nodes) > 0 {
				// copy
				*serv = *service
				serv.Nodes = nodes
				services = append(services, serv)
			}
		}

		return services
	}
}

  发现是

node.Metadata[key] == val

解决方法在server.go 的web服务注册添加Metadata信息
//其实下面这段代码的意义就是启动服务的同时把服务注册进consul中,做的是服务发现
	server := web.NewService( //go-micro很灵性的实现了注册和反注册,我们启动后直接ctrl+c退出这个server,它会自动帮我们实现反注册
		web.Name("httpprodservice"), //注册进consul服务中的service名字
		web.Address(":8088"), //注册进consul服务中的端口,也是这里我们gin的server地址
		web.Handler(ginRouter),  //web.Handler()返回一个Option,我们直接把ginRouter穿进去,就可以和gin完美的结合
		web.Metadata(map[string]string{"protocol" : "http"}),
		web.Registry(consulReg), //注册到哪个服务器伤的consul中
		web.RegisterTTL(time.Second*30),
		web.RegisterInterval(time.Second*15),
	)

  

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Go语言标准库之context发布时间:2022-07-10
下一篇:
Windows 10 Enterprise LTSC做Windows To Go蓝屏无法进入系统发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap