2021/11/24 老男孩带你21周Go语言 (十一)

本文概述了Go语言中的etcd使用,包括配置文件映射、高可用kv存储、watch机制、分布式锁实现、配置动态更新和日志agent示例。重点讲解了etcd的部署、API操作、以及如何利用etcd的强一致性确保服务的实时更新和任务管理。
摘要由CSDN通过智能技术生成

P158内容回顾

TODO,比如有些函数包里定义的必须要传context.context对象,这时候你不知道传什么,这是你的模块不需要conetxt的一些超时或者deadline的控制,那就传一个TODO即可,方便 向后兼容。
background会提高一个根节点,往下传递。
withcancel,返回一个ctx对象和一个取消函数,把它当参数传到goroutine的一个执行的函数里,cancel就进行 在外面goroutine控制子goroutine的退出。
withTimeout设置一个相对时间
witthDeadline设置一个绝对的时间。
context.withvalue(),传递上下文相关的value

在这里插入图片描述

在这里插入图片描述
把配置文件读出来映射成go的结构体,cfg是需要修改的,传一个指针的
在这里插入图片描述
只能读的单向通道
在这里插入图片描述

P159 今日内容概要

在这里插入图片描述

P160 etcd介绍

etcd是go语言开发的一个开源高可用分布式kv存储,用于配置共享和服务注册发现

在这里插入图片描述
etcd具有以下特点:
完全复制:集群中的每个节点都可以使用完整的存档
高可用性: Etcd可用于避免硬件的单点故障或网络问题
一致性:每次读取都会返回跨多主机的最新写入
简单:包括一个定义良好、面向用户的API (gRPC)
安全:实现了带有可选的客户端证书身份验证的自动化TLS
快速:每秒10000次写入的基准速度
可靠:使用Raft算法实现了强一致、高可用的服务存储目录。
raft算法区别于zookeeper用的帕克索斯

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
可以在etcd上注册watcher并等待,每次配置有更新的时候,etcd会通知订阅者,实现热加载
在这里插入图片描述
**将所有分布式锁的机制交给etcd来控制,它从底层的raft原理实现了锁机制,要么取成功,要么不成功。
**

在这里插入图片描述
etcd里创建了一个key,lock,三个服务取抢,只有一个人能成功,其他都失败,谁抢到了value就是谁的。
在这里插入图片描述
为什么用etcd而不用ZooKeeper?
etcd实现的这些功能, Zookeeper都能实现。那么为什么用etcd而非直接使用Zookeeper呢?
相较之下, ZooKeeper有如下缺点
1,复杂。ZooKeeper的部署维护复杂,管理员需要掌握一系列的知识和技能;而Paxos强一致性算法也是素来以复杂难懂而闻名于世;另外, ZooKeeper的使用也比较复杂,需要安装客户端,官方只提供了Java和C两种语言的接口。
2. Java编写。这里不是对Java有偏见,而是Java本身就偏向于重型应用,它会引入大量的依赖。而运维人员则普遍希望保持强一致、高可用的机器集群尽可能简单,维护起来也不易出错。
3. 3、发展缓慢. Apache基金会项目特有的Apache way在开源界饱受争议,其中一大原因就是由于基金会庞大的结构以及松散的管理导致项目发展缓慢。

在这里插入图片描述
etcd部署比较方便,二进制文件,直接启动,是http的接口,数据默认已更新就持久化

在这里插入图片描述
etcd架构,httpserver相当于代理(v3,是grpc,二进制的协议),raft算法,
在这里插入图片描述从etcd的架构图中我们可以看到, etcd主要分为四个部分。
HTTP Server:用于处理用户发送的API请求以及其它etcd节点的同步与心跳信息请求。
Store:用于处理etcd支持的各类功能的事务,包括数据索引、节点状态变更、监控与反馈、事件处理与执行等等,是etcd对用户提供的大多数API功能的具体实现。
Raft: Raft强一致性算法的具体实现,是etcd的核心。
WAL: Write Ahead Log (预写式日志) ,是etcd的数据存储方式。除了在内存中存有所有数据的状态以及节点的索引以外, etcd就通过WAL进行持久化存储。WAL中,所有的数据提交前都会事先记录日志。Snapshot是为了防止数据过多而进行的状态快照; Entry表示存储的具体日志内容。

在这里插入图片描述
etcd是作为一个高可用的支持项目,天生为了集群而配置的。
raft算法带一个任期的索引,还有一个日志的索引,不同的节点是有优先级的,任期最新和日志最新才能被选举做leader

在这里插入图片描述
token随便起一个,不同集群不一样就行,cluster_state=new 创建新的集群,如果是新节点加入老集群就不是new了,
cluster相当于集群里面有几个节点。

在这里插入图片描述
依次启动二进制文件,-- data-dir数据存在哪里,–name节点名称,–listen-peer-urls集群通信节点,
advertise-client-urls 客户端2379.
–initial-cluster初始化集群,这个节点属于哪个集群。
–initial-cluster-state状态,上面的状态变量
–initial-cluster-token上面token变量

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
官网也提高了一个方式,指向公网的一个地址,就认为节点在一个集群里

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

P161 etcd搭建

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
最新的默认已经是v3版本了

在这里插入图片描述
在这里插入图片描述
设置环境变量,现在用etcdctl就是v3版本接口
在这里插入图片描述
put就是设置键值对
在这里插入图片描述
没有put命令就是环境变量没有设置v3版本,ok就是设置成功
在这里插入图片描述

get获取值
在这里插入图片描述
del删除key
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
先下载包
在这里插入图片描述
字符串切片可以传多个,5秒超时时间

在这里插入图片描述
延时关闭连接
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
写一个watch,观察值的变化
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
下面需要连接etcd,然后做watch操作,只要看到值变化,就通过通道通知,
ch 派一个哨兵去监控etcd的key变化,key发生变化,就会发消息给通道,从通道里尝试去取值,值是一个结构体,
cancel是立即释放掉context的资源

在这里插入图片描述

在这里插入图片描述
这样就不退出了

在这里插入图片描述v
这样可以做一个配置热更新,服务不重启

在这里插入图片描述

P162 etcd操作

可以在之前的logagent里修改,之前是从配置文件里读,配置项可以不读,放在etcd里

在这里插入图片描述

在这里插入图片描述
先加载配置文件,初始化kafka,初始化etcd

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

建立一个etcd模块并配上超时时间
在这里插入图片描述
初始化etcd
在这里插入图片描述
先启动zookeeper
在这里插入图片描述
启动kafka
在这里插入图片描述

在这里插入图片描述

P163 logagent从etcd加载收集项配置

第一步初始化kafka,第二步初始化etcd,下面开启日志收集,从etcd中获取日志收集项的配置信息,指定一个哨兵取监视日志收集项目的变化
在这里插入图片描述
从etcd里收集获取配置

在这里插入图片描述
这样就可以直接序列化
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
watch etcd 的key ‘’/xxx‘
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
传一个指针进来
在这里插入图片描述

在这里插入图片描述
这样就有值了

在这里插入图片描述

P164 logagent上午内容回顾

这是新增的部分,初始化需要etcd的地址和超时的时间

在这里插入图片描述
在这里插入图片描述
main函数这样就不需要写死了
在这里插入图片描述
需要收集的日志的配置信息
在这里插入图片描述
etcd put直接把数据推进去
在这里插入图片描述
这个变量是日志收集的slice
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
现在有三项

在这里插入图片描述
etcd里的key收集项,logagent是可以收集到的

在这里插入图片描述

P165 logagent根据etcd的配置创建

在这里插入图片描述
现在for循环里有几个配置项造几个配置项

在这里插入图片描述
对tailobj一行一行读取数据

在这里插入图片描述
taltask代替tailobj,代表是一个日志收集的任务收集的路径,收集的日志放到哪个topic下,具体的tailf对象

在这里插入图片描述
构造函数,返回tailObj对象

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
这样每一个tailtask都有readchan
在这里插入图片描述
在这里插入图片描述
现在做一个具体收集,下面的readchan就不需要了

在这里插入图片描述

在这里插入图片描述
开启一个gorutine去跑run方法,去instance里去读,赋值到line里
在这里插入图片描述
可以把tailllogmgr单独拿出来
在这里插入图片描述

在这里插入图片描述
main函数里就可以直接这么写
在这里插入图片描述
先把日志数据放到一个通道中,kafka那个包中有单独的goroutine去取日志数据发的kafka

在这里插入图片描述
定义了一个全局变量,但是没有初始化,不能往里放
在这里插入图片描述
通道大小可以配置

在这里插入图片描述
新增一个参数
在这里插入图片描述

提供外部的一个函数,这个函数只把日志数据发送到一个内部的channel
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
从通道取数据,不满足分支,就写一个default,真正往kafka发送日志的函数

在这里插入图片描述
在这里插入图片描述
从通道取数据发往kafka

在这里插入图片描述
在这里插入图片描述
把kafka这个配置传进去

在这里插入图片描述
退出是因为主程序没有run

在这里插入图片描述

P166 logagent实现watch新配置

当etcd配置项进行变化的时候,因为调整tailtask任务,原来3个任务,新增一个配置项,就需要新创建一个tailtask去收集日志;
2.原来有,现在没有了,把对应的tailtask停止;
3.有关闭的,有重新创建的。

写taillogmgr就是用map的方式把有的tailtask都存起来。
在这里插入图片描述
其实就是派一个哨兵去观察配置的变化,获得到配置,想办法传递到真正用这个配置的地方。
在这里插入图片描述
单独拎出来,做一个函数
在这里插入图片描述
在这里插入图片描述
watchconf,这个哨兵拿到配置后,需要去通知别人
在这里插入图片描述
写一个等待新配置来的通道
在这里插入图片描述
通道建立好后,需要make做初始化

在这里插入图片描述
从newconfchan一直去读,然后对配置进行新增,删除,变更
在这里插入图片描述
所有init之后,开始run
在这里插入图片描述
写一个函数,向外暴露tskMgr的newConfChan,这就是go语言写代码常用场景,给内部私有对象字段向外暴露

在这里插入图片描述
上面会卡住,但是监听操作时异步的,放在监听里就可以,如果删除操作,就可以返回空
在这里插入图片描述
从taillog包中获取对外暴露的通道,下面是哨兵,发现最新的配置信息,会通知上面的通道

在这里插入图片描述
这么写,可能因为下面的原因报空指针
在这里插入图片描述
一定要先调用init,再执行
在这里插入图片描述
在这里插入图片描述
传递新配置

在这里插入图片描述
这里就拿到配置了

在这里插入图片描述
如果删除,会手动传一个空的slice
在这里插入图片描述
现在是空的对象

在这里插入图片描述
在这里插入图片描述
设置key为空

在这里插入图片描述
在这里插入图片描述
当一个新的配置文件再etcd设置的时候,应该通知taillog模块,做监听是在etcd模块,(初始化etcd后,第一次拿到配置后,就派小弟监听)
在这里插入图片描述
如何watch(拿到新配置还要通知taillog模块,利用管道通知,把配置放到管道里),但tailog模块才是真正去收集日志的模块
在这里插入图片描述
taillogmgr,从管道里拿最新配置
在这里插入图片描述

P167 logagent实现新增收集任务

**拿到新配置后就需要进行日志收集了,如何判断是不是新的配置,不同的配置项,肯定路径不可能一致。
**
在这里插入图片描述
topic和路径连成一个key
在这里插入图片描述
如果配置存在及continue,如果不存在就新增
在这里插入图片描述
之前已经把配置文件存起来过

在这里插入图片描述

找出原来t.logEntry有的,但是newconf中没有的,要删掉
在这里插入图片描述
把mysql.log删除,到时候新增一个

在这里插入图片描述
消费者现在能收到更新的日志

在这里插入图片描述
增加一个mysql.log的配置

在这里插入图片描述
新配置来了,等待对应日志的出现

在这里插入图片描述
新建mysql日志
在这里插入图片描述
现在就检测出来日志了

在这里插入图片描述
现在就能收集到最新的日志

在这里插入图片描述

P168 logagent删除新配置中没有的那个任务

第一层循环拿到最先的配置项,然后跟 新的watch进行比较,要看看有没有删除掉的配置,就需要topic和path都进行比较,如果满足if条件,说明原来有现在也有,如果没找到说明,原来有现在没有了。
在这里插入图片描述
如果有删除的 配置项,就需要想办法把tailobj里的给停掉了

在这里插入图片描述
就需要把run 给停掉

在这里插入图片描述
在上下文中把在执行的tailtask停掉,为了实现退出t.run(),需要加两个字段
在这里插入图片描述
在初始化对象的时候加上去
在这里插入图片描述
go一个函数,当函数退出的时候,goroutine就结束了
在这里插入图片描述
这里根据对象拿到tailobj
在这里插入图片描述
现在有三个配置项
在这里插入图片描述把mysql的删除掉

在这里插入图片描述

在这里插入图片描述
etcd的watch,底层是基于socket建立连接发送消息的
在这里插入图片描述

P169 logagent根据IP拉取自己的配置

不通服务线的机器,拉取的服务器环境都不一样,应该每个log agent拉取不同的服务器位置上的日志
在这里插入图片描述
可以通过服务器的ip来区分
在这里插入图片描述
拿到本机的对外ip
在这里插入图片描述

在这里插入图片描述

把这个代码放到logagent包里,相当于logagent启动后,先去加载本机ip地址,根据ip地址去替换本机%s,这样再去拉配置,就是去拉自己ip的配置
在这里插入图片描述
建立一个utils
在这里插入图片描述
实现每个logagent都拉取自己独有的配置,所以要以自己的ip地址作为区分
在这里插入图片描述
在这里插入图片描述
这里别忘记改
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值