IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> go微服务调用报错too many colons in address -> 正文阅读

[网络协议]go微服务调用报错too many colons in address

go微服务调用报错too many colons in address

问题描述:

我提取了关键部分的代码编写了单元测试,方便测试问题。给大家参考一下。这原先是大佬给的案例,我没见过这种写法,出于兴趣就按照案例写了一个demo,结果一写就出现报错。

func TestSrvConn(t *testing.T) {
	consulInfo := global.ServerConfig.Consul
	address := fmt.Sprintf("consul://%s:%d/%s?wait=14s", consulInfo.Host, consulInfo.Port, global.ServerConfig.GrpcSrv.Name)
	var bulider = NewBuilder()
	userConn, err := grpc.Dial(
		address,
		grpc.WithTransportCredentials(insecure.NewCredentials()),
		grpc.WithDefaultServiceConfig(`{"loadBalancingPolicy": "round_robin"}`),
		grpc.WithResolvers(bulider),
	)
	if err != nil {
		//zap.S().Fatal("[InitSrvConn] 连接 【用户服务失败】")
		fmt.Println("111", err)
	}
	
	//下面这段时尝试调用PingPong方法,测试是否在正常输出
	userSrvClient := proto.NewFileStoreGreeterClient(userConn)
	ping := proto.Ping{Stroke: 1111}
	res, err := userSrvClient.PingPong(context.Background(), &ping)
	fmt.Println("res", res)
	fmt.Println("err:::", err)
	fmt.Println("end")
}

然后,直接调用srv服务没问题,调用通过consul发现的srv服务会有此报错;

transport: Error while dialing dial tcp: address consul://192.168.32.90:8500/fileStore-srv?wait=14s: too many colons in address

问题分析

简单来说就是解析器的问题。如果你不是和我一样基于 conusl协议的,可以尝试把地址写成[协议://ip地址]:端口/endpoint 或者 [账号@密码:地址]:端口/endpoint这样说不定就解决了(也就是:端口前面的内容用中括号括起来)。

而grpc的包中,没有consul协议的解析器。所以会报错。

但是我对大佬给的模板debug时惊奇地发现,居然能看到consul.Resolver这个解析器,也就是说,它被自动引入了。

我在模板代码里找了半天,又去grpc的包中找,再去consul的包中去查找,都找不到哪里有些这个解析器。

快要放弃了的时候,突然灵光一闪,自动引入…


解决方案

其实在发现问题原因前,已经找到替代方案了。这样钻牛角尖,纯粹为了技术研究,拖这个问题的福,我对gprc底层的通信的实现原理大致全新的理解。

最终方案1:

import _ "github.com/mbobakov/grpc-consul-resolver"

就这么简单,懂的都懂…

替代方案:
通过client.Agent().ServicesWithFilter这个方法来发现服务并调用

//代码内容做了删减,只保留了重要部分
improt ""github.com/hashicorp/consul/api""
client, err := api.NewClient(cfg)
if err != nil {
	panic(err)
}

//根据服务名或id查询grpc服务端地址
data, err := client.Agent().ServicesWithFilter(fmt.Sprintf(`Service=="%v"`, srvName))
if err != nil {
	panic(err)
}

for _, value := range data {
	//把连接的gprc服务地址和端口复制到全局变量
	global.ServerConfig.GrpcSrv.Host = value.Address
	global.ServerConfig.GrpcSrv.Port = value.Port
	break
}

两种方案的区别

grpc-consul-resolver 这个包导入即用,不需要关心任何实现过程。是基于grpc通信解析开发的解析器。每次进行函数请求时,都会通过consul来转发到服务端,而不是直接和服务端通信。

client.Agent().ServicesWithFilter 这个方法是consul包内置的。可以用来自定义负载均衡的策略。简单易于理解,新手也有能力自行开发新功能。但是这个方法是基于http请求的,如果每次请求时,都调用这个方法,会损失一定性能。

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-03-13 22:11:44  更:2022-03-13 22:12:43 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 6:31:30-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码