首页 > 其他分享 >Go-Micro客户端请求报500错误的解决方法

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

时间:2024-10-04 18:49:10浏览次数:1  
标签:web http err micro selector Micro go Go 500

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

1.服务端代码

package main

import (
    "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 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-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,设置为json
        client.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 selector
    next, err := h.next(req, callOpts)

 

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

// only get the things that are of mucp protocol
	selectOptions := 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 selector
    next, 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,指定请求协议为http
        web.Metadata(map[string]string{
   "protocol" : "http"}),
    )

 

在指定了服务的请求协议后,成功解决该问题~

标签:web,http,err,micro,selector,Micro,go,Go,500
From: https://www.cnblogs.com/phpwyl/p/18447128

相关文章

  • google chrome去除组织策略
    https://groups.google.com/g/huddcaricang/c/Bahkeds6vrg?pli=1https://hackerdose.com/downloads/utility/chrome-policy-remover/::ChromePolicyRemoverforWindows::version1.0-21May2022::CreatedbyStefanvd::ChromeProductExpert::https://prod......
  • 基于django+vue+Vue的高校设备信息管理系统的设计与实现【开题报告+程序+论文】-计算
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着高校教育事业的蓬勃发展,各类教学科研设备的数量急剧增加,设备信息管理成为高校管理中的重要环节。传统的人工管理方式不仅效率低下,而且......
  • 基于django+vue+Vue的高校教师多维考核评价系统设计开发与实现【开题报告+程序+论文】
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着高等教育的快速发展,高校教师的工作内容与职责日益复杂多样,传统的单一维度评价体系已难以满足当前对高校教师全面、公正评价的需求。近......
  • 基于django+vue+Vue的房屋租借系统【开题报告+程序+论文】-计算机毕设
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着城市化进程的加速和人口流动性的增强,房屋租借市场日益繁荣,成为满足人们居住需求的重要途径。然而,传统的房屋租借方式往往依赖于中介或......
  • PicGo无法删除云端图片问题
    在使用PicGo一段时间后,遇到了一个麻烦的问题:上传后无法在相册内同步删除云端,一旦不小心上传错图片或者想更换图片就很麻烦。经过一段时间的寻找,赫萝大佬基于PicGo做出的PicList完美实现了在相册内同步删除云端文件的同时可以兼容PicGo的插件下载地址:PicListgitee地址:https://gi......
  • Windows11系统Microsoft.Build.Engine.dll文件丢失问题
    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库,这时你可以下载这个Microsoft.Build.Engine.dll文件(挑选合适的......
  • GoogLeNet训练CIFAR10[Pytorch+训练信息+.pth文件]
    0引言GoogLeNet,它是一种深度卷积神经网络,由Google研究人员在2014年提出,用于图像识别任务。CIFAR-10是一个常用的图像识别数据集,包含10个类别,每个类别有6000张32x32的彩色图像。本文使用Pycharm及Pytorch框架搭建GoogLeNet神经网络框架,使用CIFAR10数据集训练模型。笔者查阅资......
  • use combined and 'and' or query in the mongo
    1、description:  usecombinedandandorqueryinthemongo2、sqlquerystatement:    select*fromdeviceInfo wheredevId='11010001' and (sndStatus=0orsndCount<3);3、matchmongosqlquery:   db.getCollection("deviceInfo&qu......
  • 题解:CF724E Goods transportation
    可以在cnblog中阅读。题意有\(n\)座城市,第\(i\)座城市生产了\(p_i\)件货物,最多可以出售\(s_i\)件货物,编号小的城市可以向编号大的城市运输至多\(c\)件货物,问最多能出售多少货物。\(n\le10^4\)。分析乍一看是一个网络流问题,可以这样建图,令\(S\)为源点\(T\)......
  • 题解:SP7973 ACPC10E - Sometimes, a penalty is good!
    比较简单的一道数学题。思路:计算小组赛的比赛总数。longlongstage1=G*T*(T-1)/2;每组有\(T\)个队伍,每个队伍都需要与其他\(T-1\)个队伍比赛,共有\(T\cdot(T-1)\)场比赛。共有\(G\)组,因此小组赛总比赛数为\(\frac{G\cdotT\cdot(T-1)}{2}\)。计算进入......