欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > Go-Micro客户端请求报500错误的解决方法

Go-Micro客户端请求报500错误的解决方法

2024/11/29 18:15:53 来源:https://blog.csdn.net/qq_36466946/article/details/142710341  浏览:    关键词:Go-Micro客户端请求报500错误的解决方法

Go-Micro客户端请求报500错误的解决方法

1.服务端代码

package mainimport ("github.com/gin-gonic/gin""github.com/micro/go-micro/registry""github.com/micro/go-micro/web""github.com/micro/go-plugins/registry/consul""net/http"
)func main() {consulReg := consul.NewRegistry(registry.Addrs(":8500"))engine := gin.Default()engine.POST("/hello", func(c *gin.Context) {c.JSON(http.StatusOK, gin.H{"msg": "hello,world",})})service := web.NewService(web.Name("cas"),web.Address(":8001"),web.Registry(consulReg),web.Handler(engine),)service.Init()service.Run()
}

2.客户端代码

package mainimport ("context""github.com/micro/go-micro/client""github.com/micro/go-micro/client/selector""github.com/micro/go-micro/registry""github.com/micro/go-plugins/client/http""github.com/micro/go-plugins/registry/consul""log"
)func main() {consulReg := consul.NewRegistry(registry.Addrs(":8500"))selector := selector.NewSelector(selector.Registry(consulReg),selector.SetStrategy(selector.RoundRobin),)httpClient := http.NewClient(// 选择器client.Selector(selector),// 响应格式默认格式protobuf,设置为jsonclient.ContentType("application/json"),)req := map[string]string{}request := httpClient.NewRequest("cas", "/hello", req)rsp := map[string]interface{}{}err := httpClient.Call(context.Background(), request, &rsp)if err != nil {log.Fatalf("request err: %+v", err)}log.Printf("%+v",rsp)
}
 

3.发起请求报错

客户端请求报错如下:

代码语言:javascript
复制
{"id":"go.micro.client","code":500,"detail":"none available","status":"Internal Server Error"}

4.问题分析

1.顺着客户端调用的Call()方法,进入源码github.com\micro\go-plugins\client\http\http.go,找到获取服务节点的方法:

// get next nodes from the selectornext, err := h.next(req, callOpts)

2.再继续查看next()方法,找到第63行,这里为Selector节点选择器添加了过滤器,传递了两个参数"protocol", "http",可以发现是个键值对:

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

3.进一步进入FilterLabel()方法,在第41行可以发现,上一步传的两个参数在这里做了校验,分别作为的Metadata(元数据)的map的键和值,相当于验证协议需要为http:

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

4.回到http.go的69行,如果不满足http协议,则获取服务节点失败,返回我们所遇到的这个err:

// get next nodes from the selectornext, err := h.opts.Selector.Select(service, selectOptions...)if err != nil && err == selector.ErrNotFound {return nil, errors.NotFound("go.micro.client", err.Error())} else if err != nil {return nil, errors.InternalServerError("go.micro.client", err.Error())}

到这里其实已经可以基本确定我们遇到的问题了:在使用go-plugins插件进行服务调用时,在服务发现时为选择器添加了过滤,限定了请求协议,要求Metadata的键值必须为"protocol":"http",否则返回的服务节点切片长度将为0。

5.解决方法

因此解决方法则是在服务端进行服务注册的时候,为注册的服务添加上Metadata配置,指定请求协议为http:

    service := web.NewService(web.Name("cas"),web.Address(":8001"),web.Registry(consulReg),web.Handler(engine),// 为注册的服务添加Metadata,指定请求协议为httpweb.Metadata(map[string]string{"protocol" : "http"}),)
在指定了服务的请求协议后,成功解决该问题~😄

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com