当前位置:网站首页>go-etcd
go-etcd
2022-07-01 06:52:00 【ALEX_CYL】
1.etcd简介
高可用的分布式key-val存储,可以用于配置共享和服务发现
类似项目:zookeeper(java)和consul(go)
开发语言:go
接口:提供restful的http接口,使用简单
实现算法:基于raft一致性算法的强一致性、高可用(多个备份)的服务存储目录。
etcd 与redis:
redis集群一般是一主两从,主写入数据,从读出数据,故可能存在信息更新延迟;etcd的强一致性确保热和任何节点的数据都是一致的。故对与强一致性要求高的选用etcd,一致性要求不是很严的可选用redis,redis的读取速度优秀。
etcd 使用场景:
1.服务注册和服务发现
2.配置中心
3.分布式锁(强一致性)
4.master选举
2. etcd安装
安装etcd+etcdkeeper合集
启动etcd,使用etcdctl执行命令操作,默认端口"2379"
3.go 使用etcd的基础知识
3.1.context
包的使用:
context
包定义了context. Context
类型,它携带跨越 API 边界和进程之间的截止日期、取消信号和其他请求范围的值。对服务器的传入请求应该创建一个上下文,对服务器的传出调用应该接受一个上下文。它们之间的函数调用链必须传播 Context,可选择将其替换为使用 WithCancel、WithDeadline、WithTimeout 或 WithValue 创建的派生 Context。当一个上下文被取消时,所有从它派生的上下文也被取消。
3.1.1 WithCancel
package main
import (
"context"
"fmt"
"time"
)
func main() {
// gen generates integers in a separate goroutine and
// sends them to the returned channel.
// The callers of gen need to cancel the context once
// they are done consuming generated integers not to leak
// the internal goroutine started by gen.
gen := func(ctx context.Context) <-chan int {
dst := make(chan int)
n := 1
go func() {
//后台持续运行
for {
select {
case <-ctx.Done():
fmt.Println("goroutine exit")
return // returning not to leak the goroutine
case dst <- n:
fmt.Println("goroutine run")
n++
}
}
}()
fmt.Println("返回")
return dst
}
ctx, cancel := context.WithCancel(context.Background())
defer cancel() // cancel when we are finished consuming integers
for n := range gen(ctx) {
fmt.Println(n)
if n == 5 {
break
}
}
time.Sleep(time.Second)
}
输出
返回
goroutine run
1
2
goroutine run
goroutine run
3
4
goroutine run
goroutine run
5
3.1.2 WithDeadline
package main
import (
"context"
"fmt"
"time"
)
const shortDuration = 1 * time.Millisecond
func main() {
d := time.Now().Add(shortDuration)
ctx, cancel := context.WithDeadline(context.Background(), d)
// Even though ctx will be expired, it is good practice to call its
// cancellation function in any case. Failure to do so may keep the
// context and its parent alive longer than necessary.
defer cancel()
select {
case <-time.After(1 * time.Second):
fmt.Println("overslept")
case <-ctx.Done():
fmt.Println(ctx.Err())
}
}
3.1.3 WithTimeout
package main
import (
"context"
"fmt"
"io/ioutil"
"net/http"
"time"
)
type Result struct {
r *http.Response
err error
}
func process() {
// 基础ctx
baseCtx := context.Background()
// 设定context.WithTimeout
ctx, cancel := context.WithTimeout(baseCtx, 2*time.Second)
defer cancel()
tr := &http.Transport{
}
client := &http.Client{
Transport: tr}
c := make(chan Result, 1)
req, err := http.NewRequest("Get", "http://www.baidu.com", nil) //http://google.com
if err != nil {
fmt.Println("http request failed, err:", err)
return
}
go func() {
resp, err := client.Do(req)
pack := Result{
r: resp, err: err}
c <- pack
}()
select {
case <-ctx.Done():
tr.CancelRequest(req) //超时,取消http请求,
res := <-c //client.Do(),由于请求取消返回一个错误
fmt.Println("Timeout!,errr:", res.err)
case res := <-c:
if res.err != nil {
fmt.Println("Server Response ,client.Do() err:", err)
} else {
defer res.r.Body.Close()
out, _ := ioutil.ReadAll(res.r.Body)
fmt.Printf("Server Response :%s\n", out)
}
}
return
}
func main() {
process()
}
3.1.4 WithValue
package main
import (
"context"
"fmt"
)
type favContextKey string
func process1(ctx context.Context, k favContextKey) {
if ret := ctx.Value(k); ret != nil {
fmt.Println("found value:", ret)
return
}
fmt.Println("Not found key", k)
}
func process(ctx context.Context) {
ret, ok := ctx.Value("trace_id").(int)
if !ok {
ret = 12161844
}
fmt.Printf("ret:%d\n", ret)
if s := ctx.Value("session"); s != nil {
fmt.Println("found value:", s)
} else {
fmt.Println("not found key:", "session")
}
}
func main() {
basectx := context.Background()
// contex.WithValue()
var k favContextKey = "trace_id"
ctx := context.WithValue(basectx, k, 12161811)
process1(ctx, k)
ctx = context.WithValue(ctx, "session", "day-1") //ctx 可继承的树状结构
process(ctx)
}
3.2 etcd 使用
3.2.1 etcd_connect
package main
import (
"fmt"
"time"
etcd_client "github.com/coreos/etcd/clientv3"
)
func main() {
cli, err := etcd_client.New(etcd_client.Config{
Endpoints: []string{
"localhost:2379", "localhost:22379", "localhost:32379"},
DialTimeout: 5 * time.Second,
})
if err != nil {
fmt.Println("connect failed,err :", err)
return
}
defer cli.Close()
fmt.Println("connect succ")
}
3.2.2 etcd_example
get/put使用
package main
import (
"context"
"fmt"
"time"
etcd_client "github.com/coreos/etcd/clientv3"
)
func main() {
cli, err := etcd_client.New(etcd_client.Config{
Endpoints: []string{
"localhost:2379", "localhost:22379", "localhost:32379"},
DialTimeout: 5 * time.Second,
})
if err != nil {
fmt.Println("connect failed,err :", err)
return
}
fmt.Println("connect succ")
defer cli.Close()
baseCtx := context.Background()
ctx, cancel := context.WithTimeout(baseCtx, time.Second)
_, err = cli.Put(ctx, "/logagent/conf/", "sample_value")
cancel()
if err != nil {
fmt.Println("put failed,err:", err)
return
}
ctx, cancel = context.WithTimeout(baseCtx, time.Second)
resp, err := cli.Get(ctx, "/logagent/conf/")
cancel()
if err != nil {
fmt.Println("get failed,err:", err)
return
}
for _, ev := range resp.Kvs {
fmt.Printf("%s:%s\n", ev.Key, ev.Value)
}
}
3.2.3 etcd_wath
监听配置/节点配置信息的更新
package main
import (
"fmt"
"time"
"github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context"
etcd_client "github.com/coreos/etcd/clientv3"
)
func main() {
cli, err := etcd_client.New(etcd_client.Config{
Endpoints: []string{
"localhost:2379", "localhost:22379", "localhost:32379"},
DialTimeout: 5 * time.Second,
})
if err != nil {
fmt.Println("connect failed,err :", err)
return
}
fmt.Println("connect succ")
defer cli.Close()
for {
//持续监听,配置是否有变化 watch 主动告知配置有变
rch := cli.Watch(context.Background(), "/logagent/conf/") //阻塞在此处,有新变化,管道输出信息
for wresp := range rch {
for _, ev := range wresp.Events {
fmt.Printf("%s %q : %q\n", ev.Type, ev.Kv.Key, ev.Kv.Value)
}
}
}
}
边栏推荐
- Principle of introducing modules into node
- Stored procedure learning notes
- Programming examples of stm32f1 and stm32subeide infrared receiving and decoding of NEC protocol
- 【LINGO】求无向图的最短路问题
- 用手机在指南针上开户靠谱吗?这样有没有什么安全隐患
- Solve the problem of "unexpected status code 503 service unavailable" when kaniko pushes the image to harbor
- Rclone access web interface
- Chinese explanation of common rclone subcommands
- 2022 Jiangsu Vocational College skills competition (secondary vocational school) network construction and application open competition volume
- How to draw a product architecture diagram?
猜你喜欢
【LINGO】求七个城市最小连线图,使天然气管道价格最低
How to permanently configure local opencv4.5.5 for vs2019
[wechat applet] to solve button, input and image components
Solve the problem of "unexpected status code 503 service unavailable" when kaniko pushes the image to harbor
How to use SCI hub
如何通过cdn方式使用阿里巴巴矢量图字体文件
软件工程复习
Esp32 monitors the battery voltage with ULP when the battery is powered
How the esp32 deep sleep current is lower than 10uA
MySQL learning
随机推荐
How to use Alibaba vector font files through CDN
问题:OfficeException: failed to start and connect(二)
Stored procedure learning notes
广发证券开户是安全可靠的么?怎么开广发证券账户
The game is real! China software cup releases a new industrial innovation competition, and schools and enterprises can participate in it jointly
Which securities company does qiniu school cooperate with? Is it safe to open an account?
rclone常用子命令中文解释
8 figures | analyze Eureka's first synchronization registry
rclone配置minio及基本操作
Jena基于OWL的默认推理查询
【分类模型】Q 型聚类分析
2022 Jiangsu Vocational College skills competition (secondary vocational school) network construction and application open competition volume
Database notes
SQL learning notes nine connections 2
H5 web page determines whether an app is installed. If it is installed, it will jump to the summary of the scheme to download if it is not installed
[recommendation technology] matlab simulation of network information recommendation technology based on collaborative filtering
发现了一个 MySQL 的巨坑:update 更新别再用影响行数做判断了!!!
Router 6/ and the difference with router5
Resttemplate use
比赛即实战!中国软件杯发布全新产业创新赛项,校企可联合参赛