首页 > 其他分享 >golang etcd容器构建与客户端操作踩坑实操

golang etcd容器构建与客户端操作踩坑实操

时间:2024-08-01 11:41:46浏览次数:8  
标签:0.0 golang 实操 etcd go indirect 2379

目录

1.问题说明

在用 go-zero 实现相关服务时一直报错,从报错信息看应该是 etcd 的容器有问题,应该是之前的构建哪里出错了,所以重新构建 etcd 容器应用。

记录下主要的踩坑情况:

  • 1.连接 etcd 容器没有问题,但是写入数据时一直报错,报超时错,可以看下面的操作记录,但本人就构建了一个单节点的 etcd,也用不到 etcd 集群功能
# ./etcdctl --endpoints=0.0.0.0:2379 --write-out=table endpoint health
{"level":"warn","ts":"2024-08-01T10:50:35.003109+0800","logger":"client","caller":"[email protected]/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"etcd-endpoints://0xc0002e2a80/0.0.0.0:2379","attempt":0,"error":"rpc error: code = DeadlineExceeded desc = latest balancer error: last connection error: connection error: desc = \"error reading server preface: read tcp 127.0.0.1:49164->127.0.0.1:2379: read: connection reset by peer\""}
+--------------+--------+--------------+---------------------------+
|   ENDPOINT   | HEALTH |     TOOK     |           ERROR           |
+--------------+--------+--------------+---------------------------+
| 0.0.0.0:2379 |  false | 5.007223857s | context deadline exceeded |
+--------------+--------+--------------+---------------------------+
Error: unhealthy cluster
  • 2.通过 golang 实现 etcd 客户端时,一直报依赖的问题,最后发现 v3.3 问题很多,后面就切 v3.5了,之后依赖问题解决

下面记录下整体的工作流。

2. etcd 容器构建

具体操作参考:

以下是具体的一些操作。

这里的容器用到的镜像是:quay.io/coreos/etcd:v3.5.12,所以你需要 docker pull 先拉取下来。

接下来是具体的一些容器构建的工作。

# 创建目录,数据与配置目录
mkdir -p /data/containers/etcd/{data,config}

# 创建配置文件
vi /data/containers/etcd/config/etcd.conf.yml
---
name: etcd-s1
data-dir: /var/etcd
listen-client-urls: http://0.0.0.0:2379
advertise-client-urls: http://0.0.0.0:2379
listen-peer-urls: http://0.0.0.0:2380
initial-advertise-peer-urls: http://0.0.0.0:2380
initial-cluster: etcd-s1=http://0.0.0.0:2380
initial-cluster-token: etcd-cluster
initial-cluster-state: new
logger: zap
log-level: info
#log-outputs: stderr
---

说明:
特殊参数说明:

name: etcd member 名称,可根据实际情况修改
data-dir: etcd 数据目录,可根据实际情况修改
listen-client-urls:  client 流量监听地址,没特殊需求按文档填写即可
advertise-client-urls: 该 member 向外部通告的客户端 url 列表,单节点部署时不需要修改,集群部署模式需修改为容器所在节点对外提供服务的 IP
listen-peer-urls:  peer 流量监听地址,没特殊需求按文档填写即可
initial-advertise-peer-urls:  该 member 向同一集群内其他 member 通告的 peer url 列表,单节点部署时不需要修改,集群部署模式需修改为容器所在节点对外提供服务的 IP
initial-cluster:  初始化集群节点信息,单节点部署时不需要修改,集群部署模式需要填写集群中所有 member 的信息
initial-cluster-token:  初始化集群时使用的 token,随便写
initial-cluster-state:  初始化集群状态,可选的值为 new  或者  existing,通常采用 new


# 编写 compose 文件
ubuntu:/data/containers/etcd#  vi docker-compose.yaml
--- 
version: '3'

services:
  etcd:
    container_name: etcd-s1
    image: quay.io/coreos/etcd:v3.5.12
    command: /usr/local/bin/etcd --config-file=/var/lib/etcd/conf/etcd.conf.yml
    volumes:
      - ${DOCKER_VOLUME_DIRECTORY:-.}/data:/var/etcd
      - ${DOCKER_VOLUME_DIRECTORY:-.}/config/etcd.conf.yml:/var/lib/etcd/conf/etcd.conf.yml
      - "/etc/localtime:/etc/localtime:ro"
    ports:
      - 2379:2379
      - 2380:2380
    restart: always


networks:
  app_net:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.238.238.0/24
---

启动容器, 在 compose 文件目录

docker-compose up -d

root@ubuntu:/data/containers/etcd# docker-compose up -d
WARNING: Some networks were defined but are not used by any service: app_net
Creating network "etcd_default" with the default driver
Creating etcd-s1 ... done
root@ubuntu:/data/containers/etcd# docker ps
CONTAINER ID   IMAGE                         COMMAND                  CREATED         STATUS         PORTS                                                           NAMES
24162db8e44b   quay.io/coreos/etcd:v3.5.12   "/usr/local/bin/etcd…"   4 seconds ago   Up 2 seconds   0.0.0.0:2379-2380->2379-2380/tcp, :::2379-2380->2379-2380/tcp   etcd-s1

顺便测试下容器,用到 etcdctl 工具,下载参见参考文档:

root@ubuntu:~/etcd/etcd-v3.5.12-linux-amd64# ./etcdctl --endpoints=0.0.0.0:2379 --write-out=table endpoint health
+--------------+--------+-------------+-------+
|   ENDPOINT   | HEALTH |    TOOK     | ERROR |
+--------------+--------+-------------+-------+
| 0.0.0.0:2379 |   true | 31.864411ms |       |
+--------------+--------+-------------+-------+
root@ubuntu:~/etcd/etcd-v3.5.12-linux-amd64# ./etcdctl --endpoints=0.0.0.0:2379 put foo bar
OK
root@ubuntu:~/etcd/etcd-v3.5.12-linux-amd64# ./etcdctl --endpoints=0.0.0.0:2379 get foo
foo
bar

走到这里,说明你的 etcd 单节点容器目前可用了,恭喜你。

3.goalng etcd 客户端实现

先看看具体的实现:

package main

import (
	"context"
	"fmt"
	"time"

	"go.etcd.io/etcd/client/v3"
)

// demo, etcd client put/get
func main() {
	cli, err := clientv3.New(clientv3.Config{
		Endpoints: []string{"172.30.5.240:2379"},
		DialTimeout: 5 * time.Second,
	})

	if err != nil {
		// handle error!
		fmt.Printf("connect to etcd failed, err:%v\n", err)
		return
	}
	fmt.Println("connect to etcd success")
	defer cli.Close()


	// put
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	_, err = cli.Put(ctx, "test", fmt.Sprintf("test-val: %v", time.Now().Format(time.RFC3339)))
	cancel()
	if err != nil {
		fmt.Printf("put to etcd failed, err:%v\n", err)
		return
	}
	// get
	ctx, cancel = context.WithTimeout(context.Background(), time.Second)
	resp, err := cli.Get(ctx, "test")
	cancel()
	if err != nil {
		fmt.Printf("get from etcd failed, err:%v\n", err)
		return
	}
	for _, ev := range resp.Kvs {
		fmt.Printf("%s:%s\n", ev.Key, ev.Value)
	}
}

我的依赖 - go.mod:

module go-etcd

go 1.19

require (
	github.com/coreos/go-semver v0.3.0 // indirect
	github.com/coreos/go-systemd/v22 v22.3.2 // indirect
	github.com/gogo/protobuf v1.3.2 // indirect
	github.com/golang/protobuf v1.5.4 // indirect
	go.etcd.io/etcd/api/v3 v3.5.15 // indirect
	go.etcd.io/etcd/client/pkg/v3 v3.5.15 // indirect
	go.etcd.io/etcd/client/v3 v3.5.15 // indirect    // 这里需要注意版本问题,v3.3问题挺多,建议用3.5后的
	go.uber.org/atomic v1.7.0 // indirect
	go.uber.org/multierr v1.6.0 // indirect
	go.uber.org/zap v1.17.0 // indirect
	golang.org/x/net v0.23.0 // indirect
	golang.org/x/sys v0.18.0 // indirect
	golang.org/x/text v0.14.0 // indirect
	google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect
	google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d // indirect
	google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect
	google.golang.org/grpc v1.59.0 // indirect
	google.golang.org/protobuf v1.33.0 // indirect
)

以下是运行结果:

connect to etcd success
test:test-val: 2024-08-01T11:13:06+08:00

恭喜你,已经掌握 golang etcd 的客户端实现。

标签:0.0,golang,实操,etcd,go,indirect,2379
From: https://www.cnblogs.com/davis12/p/18336333

相关文章

  • golang对遍历目录操作的优化
    一转眼go1.23都快发布了,时间过得真快。不过今天我们把时间倒流回三年半之前,来关注一个在go1.16引入的关于处理目录时的优化。对于go1.16的新变化,大家印象最深的可能是io包的大规模重构,但这个重构实际上还引进了一个优化,这篇文章要说的就是这个优化。本文默认Linux环境,不过这个......
  • golang面试题:json包变量不加tag会怎么样?
    问题json包里使用的时候,结构体里的变量不加tag能不能正常转成json里的字段?怎么答如果变量首字母小写,则为private。无论如何不能转,因为取不到反射信息。如果变量首字母大写,则为public。不加tag,可以正常转为json里的字段,json内字段名跟结构体内字段原名一致。加了tag,从str......
  • Golang试用阿里通义千问大语言模型
    一、控制台配置通义千问密匙官方操作指南地址控制台地址注意:一个密匙申请之后,官方给了一个月期限共计100万条Token的额度 二、代码阶段1、DashScopRequest结构体 typeEngineRolestringconst(EngineRoleUserEngineRole="user"EngineRoleSystem......
  • skynet 实操篇
    文章目录概述demo启动文件skynet_start配置文件main.luastart函数thread_workerskynet_context_message_dispatchskynet_mq_popdispatch_message小结概述上一篇写完skynet入门篇,这一篇写点实操性质的。demo对于一个开源框架,大部分都有他们自己的demo。先来看下这......
  • 【Golang 面试 - 进阶题】每日 3 题(三)
    ✍个人博客:Pandaconda-CSDN博客......
  • 【Golang 面试 - 进阶题】每日 3 题(四)
     ✍个人博客:Pandaconda-CSDN博客......
  • 用依赖倒置和控制反转,突破Golang循环调用限制之后的思考
    在软件开发中,随着项目规模的扩大和业务逻辑的复杂化,重构代码变得越来越重要。本文将介绍如何在既有代码基础上,通过依赖倒置(DIP)和控制反转(IoC),实现新增加的代码可以循环引用到服务层的代码。然后,我们将探讨接口隔离、设计小而清晰的接口和包,以及共同依赖原则等内容。包引用时的......
  • git篇-- Git在项目实操中常见的使用命令--02
    Git是现代软件开发中不可或缺的版本控制工具。它能帮助开发者跟踪项目的所有变更,并与团队成员高效协作。本文将介绍一些在项目实操中常见的Git命令,帮助你更好地管理代码。1.初始化和配置初始化仓库在一个新的项目目录中,初始化Git仓库:gitinit配置用户信息在提交代码......
  • 【Golang 面试 - 进阶题】每日 3 题(三)
    ✍个人博客:Pandaconda-CSDN博客......
  • golang 数组转为链表 - 正序和逆序
    有时候,有这样的场景,我们需要就给定数组将其转为一个链表,通常的思路有两种:正序逆序以下是具体的代码实现和测试函数:packagemainimport("fmt""testing")typelistNodestruct{next*listNodevalint}//正序遍历构建链表//通过一个虚拟头结点,不......