【etcd】解决 go-zero 注册 etcd 出现 “Auto sync endpoints failed.” 的问题

go: v1.20.3

go-zero: v1.5.4

etcd: v3.5.9


问题描述

在 go-zero 中用 etcd 去实现服务注册发现,rpc 服务可以注册到 etcd,同时其他服务可以发现注册的微服务,也可以访问。但是,注册的 rpc 服务的日志,就是一直报以下错误。日志一直在刷 Auto sync endpoints failed 的问题,服务也可以访问,就很诡异。

{"level":"warn","ts":"2023-07-30T15:57:02.004+0800","logger":"etcd-client","caller":"v3@v3.5.4/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"etcd-endpoints://0xc0007281c0/192.168.2.2:2379","attempt":0,"error":"rpc error: code = DeadlineExceeded desc = latest balancer error: last connection error: connection error: desc = \"transport: Error while dialing dial tcp 0.0.0.0:2379: connect: connection refused\""}
{"level":"info","ts":"2023-07-30T15:57:02.004+0800","logger":"etcd-client","caller":"v3@v3.5.4/client.go:210","msg":"Auto sync endpoints failed.","error":"context deadline exceeded"}

如果是老手,看到这里 ,应该知道问题会出在哪里。我是菜鸟,就只好一步步分析。

如果想直接看解决方法的,到最后,下面是我的分析过程。


排查

当出现问题的时候,想的就是包的问题,不是我的问题。就去 trace go-zero 的源码,也就是 etcd 注册的那个地方。

把 go-zero,封装 etcd 的源码看了好几遍,也没发现有问题,都是正常的注册与发现。(注意:这时候我 go-zero 版本还是 v1.3.2)

没什么问题,以为是 go-zero 版本太旧了,升级一下。因为看 issue 说 etcd 版本也有可能太旧。

验证一

把 go-zero 版本升级到 v1.5.4(中间是先到v1.4.4),把 etcd 升级到 v3.5.9(中间是先到v3.5.7),发现并没有成功,还是会出现 Auto sync endpoints failed


想想 go-zero 应该也不至于会出这个问题,会不会是我 etcd 启动的问题?我是用 docker 启动的 etcd,因为是在测试,就用单点。这边对配置的 IP 其实没有概念,也不知道都是干嘛的。

docker run -d --name ai-etcd --network=host --restart always \-v $PWD/etcd.conf.yml:/opt/bitnami/etcd/conf/etcd.conf.yml \-e ETCD_ADVERTISE_CLIENT_URLS=http://0.0.0.0:2379 \-e ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379 \-e ETCD_LISTEN_PEER_URLS=http://0.0.0.0:2380 \-e ETCD_INITIAL_ADVERTISE_PEER_URLS=http://0.0.0.0:2380 \-e ALLOW_NONE_AUTHENTICATION=yes \bitnami/etcd:3.5.9

这个 docker 的启动方式,也是往上找的,没问题呀。启动也 ok,go-zero 也注册得上去。

再看看 etcd 到底哪里出的问题,又去看了下源码。

// client.go L196
func (c *Client) autoSync() {if c.cfg.AutoSyncInterval == time.Duration(0) {return}for {select {case <-c.ctx.Done():returncase <-time.After(c.cfg.AutoSyncInterval):ctx, cancel := context.WithTimeout(c.ctx, 5*time.Second)err := c.Sync(ctx)cancel()if err != nil && err != c.ctx.Err() {c.lg.Info("Auto sync endpoints failed.", zap.Error(err))}}}
}// Sync synchronizes client's endpoints with the known endpoints from the etcd membership.
func (c *Client) Sync(ctx context.Context) error {mresp, err := c.MemberList(ctx)if err != nil {return err}var eps []stringfor _, m := range mresp.Members {...}c.SetEndpoints(eps...)return nil
}

上面这个方法报错,因为 Auto sync endpoints failed 是一直出现的,说明 go-zero 里面有个地方,应该也配置了 AutoSyncInterval ,所以这边会跑这个。下面是,go-zero 调用的地方,其实也就是初始化一个etcd client的传参。

// registry.go L337
// DialClient dials an etcd cluster with given endpoints.
func DialClient(endpoints []string) (EtcdClient, error) {cfg := clientv3.Config{Endpoints:            endpoints,AutoSyncInterval:     autoSyncInterval,DialTimeout:          DialTimeout,DialKeepAliveTime:    dialKeepAliveTime,DialKeepAliveTimeout: DialTimeout,RejectOldCluster:     true,PermitWithoutStream:  true,}...
}

此时此刻很无奈,感觉不知道往哪里思考。服务也没报错,也能调用,就又很不想去分析。这种问题就很折磨,关键日志很多,很丑。还是多找找吧,去看 go-zero 的 issue,看到也有人提这个问题,不过都没有什么解决方案。去看 etcd 的 issue,也没有看到什么。最后也不知道怎么地,想为什么要一直带着 go-zero 去想这个问题,我自己写一个 etcd client 试一下不就行了。找了个范例,测一下,不就知道是 go-zero 的问题,还是 etcd 起的有问题。

范例我就不详细列了,可以去看我的另一篇 【etcd】docker 启动单点 etcd_非晓为骁的博客-CSDN博客 的文章。

cli, err = clientv3.New(clientv3.Config{Endpoints:        []string{"192.168.2.2:2379"},DialTimeout:      time.Second * 5,AutoSyncInterval: time.Second * 5,
})

同样也设置了 AutoSyncInterval,结果难受香菇,竟然也会报这个错误

这里有一个很重要的点,不要出了问题就局限在你用的框架里面,更要会抽丝剥茧,简单地看问题。


这时候说明 etcd 部的就是有问题的,只好再看下 docker run 的指令和错误。我把错误,减少到下面这一行,仔细看下,可以看到是服务 dial 0.0.0.0:2379 失败。rpc 服务和 etcd 是在 2 台服务器,访问本地 2379 就是访问容器内 2379,那肯定访问不到呀。关键是 0.0.0.0:2379 拿来的呢?

"rpc error: code = DeadlineExceeded desc = latest balancer error: last connection error: connection error: desc = \"transport: Error while dialing dial tcp 0.0.0.0:2379: connect: connection refused\""

rpc 的配置,配的是 etcd 的 host,肯定不是 0.0.0.0:2379。那说明是 etcd 服务自身返回回来的。这时候,只好去分析 docker run 里面的 url。4 个,有 2 个是 2380,说明不是我要关注的,剩下 2 个应该就是问题本身。另外 2 个 2380,看起来是 cluster 相关的,所以也可以直接忽略。

  • -e ETCD_ADVERTISE_CLIENT_URLS=http://0.0.0.0:2379 \
  • -e ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379 \

看了下注释:

  • ETCD_LISTEN_CLIENT_URLS :List of comma separated URLs to listen on for client traffic.
  • ETCD_ADVERTISE_CLIENT_URLS:List of this member’s peer URLs to advertise to the rest of the cluster. The URLs needed to be a comma-separated list.

我理解的是 ETCD_LISTEN_CLIENT_URLS 是监听的 IP:PORT,谁可以访问这个服务,类似我们其他服务用的 bind,所以这个用 0.0.0.0 应该没问题。ETCD_ADVERTISE_CLIENT_URLS 这看起来是要通知别人要访问这个 IP:PORT 才可以访问到我,看起来好像是这个的问题。改成我的服务器 IP 试试。

验证二
docker run -d --name ai-etcd --network=host --restart always \-v $PWD/etcd.conf.yml:/opt/bitnami/etcd/conf/etcd.conf.yml \-e ETCD_ADVERTISE_CLIENT_URLS=http://192.168.2.2:2379 \-e ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379 \-e ALLOW_NONE_AUTHENTICATION=yes \bitnami/etcd:3.5.9

emmm,这样子在用我 etcd 的范例测试一下,果真没有报错了。为自己的愚蠢感到深深的无语,还一直以为是 go-zero 的问题,其实跟 go-zero 一点关系都没有。


总结

这个问题,出现了很久从 v1.3.2 开始就有。但一直分析不出来就搁置,而且不影响使用。最后还是洁癖,看不惯,分析这个问题。一开始就先入为主地看是 go-zero 的问题,去看 issue,去百度,google,但都带上了 go-zero。其实就不是它的问题,自己的分析能力还是不够。etcd 这边 docker 启动的方式,大部分都是一样的,启动起来好像也没啥问题,也不会往那边去想。

这个问题深层次原因,应该还是对 etcd 不了解,里面的一些 url 不了解。而且,需要多去尝试,用最小单元去做测试,这样才可以事半功倍。

解决方案

etcd docker run 的 ETCD_ADVERTISE_CLIENT_URLS 要改成服务器 IP,然后 rpc 服务重新注册。


这个是我自己分析的过程及理解,可能这里面还有更深层次的问题,有懂的大佬可以分享一下。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/14594.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

bat一键批量、有序启动jar

将脚本文件后缀改为 bat&#xff0c;脚本文件和 jar 包放在同一个目录 echo offstart cmd /c "java -jar register.jar " ping 192.0.2.2 -n 1 -w 10000 > nulstart cmd /c "java -jar admin.jar " ping 192.0.2.2 -n 1 -w 30000 > nulstart cmd /c…

基于ARM+FPGA (STM32+ Cyclone 4)的滚动轴承状态监测系统

状态监测系统能够在故障早期及时发现机械设备的异常状态&#xff0c;避免故障的 进一步恶化造成不必要的损失&#xff0c;滚动轴承是机械设备的易损部件&#xff0c;本文对以滚动 轴承为研究对象的状态监测系统展开研究。现有的监测技术多采用定时上传监 测数据&#xff0c;…

Spring MVC学习笔记,包含mvc架构使用,过滤器、拦截器、执行流程等等

&#x1f600;&#x1f600;&#x1f600;创作不易&#xff0c;各位看官点赞收藏. 文章目录 Spring MVC 习笔记1、Spring MVC demo2、Spring MVC 中常见注解3、数据处理3.1、请求参数处理3.2、响应数据处理 4、RESTFul 风格5、静态资源处理6、HttpMessageConverter 转换器7、过…

Open3D(C++) 根据索引提取点云

目录 一、功能概述1、主要函数2、源码二、代码实现三、结果展示本文由CSDN点云侠原创,原文链接。爬虫网站自重,把自己当个人 一、功能概述 1、主要函数 std::shared_ptr<PointCloud> SelectByIn

spring boot 2 配置上传文件大小限制

一、起因&#xff1a;系统页面上传一个文件超过日志提示的文件最大100M的限制&#xff0c;需要更改配置文件 二、经过&#xff1a; 1、在本地代码中找到配置文件&#xff0c;修改相应数值后交给运维更新生产环境配置&#xff0c;但是运维说生产环境没有这行配置&#xff0c;遂…

MODBUS-TCP转Ethernet IP 网关连接空压机 配置案例

本案例是工业现场应用捷米特JM-EIP-TCP的Ethernet/IP转Modbus-TCP网关连接欧姆龙PLC与空压机的配置案例。使用设备&#xff1a;欧姆龙PLC&#xff0c;捷米特JM-EIP-TCP网关&#xff0c; ETHERNET/IP 的电气连接 ETHERNET/IP 采用标准的 T568B 接法&#xff0c;支持直连和交叉接…

[个人笔记] Linux配置NTP时间同步

Linux - 运维篇 第四章 Linux配置NTP时间同步 Linux - 运维篇系列文章回顾Linux配置NTP时间同步Linux配置CST时区 参考来源 系列文章回顾 第一章 Linux扩容LVM分区 第二章 Linux虚拟机安装VMware Tools插件 第三章 ssh-keygen和openssl工具的使用 Linux配置NTP时间同步 仅实验…

Ubuntu通用镜像加速配置

备份 cp -rf /etc/apt/sources.list /etc/apt/sources.list.bak开始配置 阿里云 sed -i shttp://archive.ubuntu.comhttps://mirrors.aliyun.comg /etc/apt/sources.listsed -i shttp://security.ubuntu.comhttps://mirrors.aliyun.comg /etc/apt/sources.list清华源 sed -i …

【etcd】docker 启动单点 etcd

etcd: v3.5.9 etcd-browser: rustyx/etcdv3-browser:latest 本文档主要描述用 docker 部署单点的 etcd&#xff0c; 用 etcd-browser 来查看注册到 etcd 的 key 默认配置启动 docker run -d --name ai-etcd --networkhost --restart always \-v $PWD/etcd.conf.yml:/opt/bitn…

【Linux】线程池

1 线程池的介绍 1.1 线程池 一种线程使用模式。线程过多会带来调度开销&#xff0c;进而影响局部性和整体性能。而线程池维护多个线程&#xff0c;等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务创建与销毁线程的代价。线程池不仅能够保证内核的充分利用&am…

生命在于学习——指纹混淆技术学习

一、前言 本篇文章仅为学习笔记记录&#xff0c;不得用于违规用途。 本篇文章为安全社公众号的Poker安全所发&#xff0c;本文仅为学习复现。 二、介绍 指纹混淆技术&#xff0c;顾名思义&#xff0c;就是迷惑指纹扫描识别技术。 三、思路 作者的思路&#xff1a; 1、伪…

常见网关对比

常见网关对比 目前常见的开源网关大致上按照语言分类有如下几类&#xff1a; Nginxlua &#xff1a;OpenResty、Kong、Orange、Abtesting gateway 等 Java &#xff1a;Zuul/Zuul2、Spring Cloud Gateway、Kaazing KWG、gravitee、Dromara soul 等 Go &#xff1a;Janus、fa…

如何⾃定义⼀个SpringBoot Srarter

⾃定义⼀个SpringBoot Srarter 1、创建⼀个项⽬&#xff0c;命名为 demo-springboot-starter&#xff0c;引⼊SpringBoot相关依赖 2、编写配置⽂件 定义属性配置的前缀 3、⾃动装配 创建⾃动配置类HelloPropertiesConfigure 4、配置⾃动类 在 /resources/META-INF/spri…

Qt报错解决办法

anaconda环境安装qt报错解决办法 报错&#xff1a;thresholdGap: 20 pointsShape: 164142 qt.qpa.plugin: Could not find the Qt platform plugin “wayland” in “/home/tianhailong/anaconda3/envs/edge_algorithm/lib/python3.8/site-packages/cv2/qt/plugins” This app…

Qt : day3

1.完成简易闹钟 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTextToSpeech> //播报类 #include <QTimer> //定时器类 #include <QTime> //时间类QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEcla…

windows C++多线程同步<3>-互斥量

windows C多线程同步&#xff1c;3&#xff1e;-互斥量 概念&#xff0c;如下图&#xff1a; 另外就是互斥对象谁拥有&#xff0c;谁释放 那么一个线程允许多次获取互斥对象吗&#xff1f; 答案是允许&#xff0c;但是申请多次就要释放多次&#xff0c;否则其他线程获取不到互…

【Git】Git GitHub

1. Git1.1 Git基本操作1.2 Git版本回退1.3 Git分支操作 2. Git 配合GitHub2.1 生成密钥2.2 GitHub添加公钥2.3 Git连接GitHub2.4 本地仓库关联远程仓库2.5 本地代码push远程仓库2.6 本地clone远程仓库2.7 本地fetch和pull 1. Git 1.1 Git基本操作 touch test.py 工作区创建文…

android首页申请android.permission.READ_PHONE_STATE权限合规处理办法?

1、像闲鱼一样&#xff0c;申请的时候在顶部弹个解释说明对话框&#xff1f;

求解方程x^2=a的根,不使用库函数直接求解(不动点迭代法)

首先可以将方程两边同时加上x&#xff0c;&#xff0c;这时候两边同时再除以1x&#xff0c;就得到了&#xff0c;变形为。&#xff08;变性后的迭代式不唯一&#xff0c;这里随便选取一个&#xff09; 当x是准确值的时候&#xff0c;两边应该是相等的&#xff0c;如果x是近似值…

VBAC多层防火墙技术的研究-状态检测

黑客技术的提升和黑客工具的泛滥,造成大量的企业、机构和个人的电脑系统遭受程度不同的入侵和攻击,或面临随时被攻击的危险。迫使大家不得不加强对自身电脑网络系统的安全防护,根据系统管理者设定的安全规则把守企业网络,提供强大的、应用选通、信息过滤、流量控制、网络侦…