golang etcd 操作
go get -u -x google.golang.org/grpc@v1.26.0
package main
import (
"context"
"fmt"
"time"
"github.com/coreos/etcd/clientv3"
)
func main() {
cli, err := clientv3.New(clientv3.Config{
Endpoints: []string{"localhost:2379"},
DialTimeout: time.Duration(5) * time.Second,
})
if err != nil {
fmt.Println("connect failed, err", err)
return
}
fmt.Println("connect success")
defer cli.Close()
for {
ctx, cancel := context.WithCancel(context.Background())
fmt.Println("Please input xi value:")
var xiValue string
fmt.Scanln(&xiValue)
if xiValue == "exit" {
break
}
_, err = cli.Put(ctx, "/xi", xiValue)
cancel()
if err != nil {
fmt.Println("put failed, err: ", err)
return
}
ctx, cancel = context.WithCancel(context.Background())
resp, err := cli.Get(ctx, "/xi")
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)
}
}
}
etcd 实现分布式锁
package example
import (
"context"
"fmt"
"sync"
"testing"
"github.com/coreos/etcd/clientv3"
)
var (
cnt int
)
func worker(i int) int {
cnt++
return 1
}
type XLock struct {
lease clientv3.Lease
kv clientv3.KV
LockKey string
cancelFunc context.CancelFunc
}
func New(cli *clientv3.Client) *XLock {
return &XLock{
lease: clientv3.NewLease(cli),
kv: clientv3.NewKV(cli),
LockKey: "simple0",
}
}
func (u *XLock) LockTest0() (err error) {
var (
leaseGrantResp *clientv3.LeaseGrantResponse
cancelCtx context.Context
cancelFunc context.CancelFunc
leaseid clientv3.LeaseID
keepRespChan <-chan *clientv3.LeaseKeepAliveResponse
)
if leaseGrantResp, err = u.lease.Grant(context.TODO(), 5); err != nil {
return
}
leaseid = leaseGrantResp.ID
defer u.lease.Revoke(context.TODO(), leaseid)
cancelCtx, cancelFunc = context.WithCancel(context.TODO())
defer cancelFunc()
if keepRespChan, err = u.lease.KeepAlive(cancelCtx, leaseid); err != nil {
return err
}
_ = keepRespChan
go func() {
var (
keepResp *clientv3.LeaseKeepAliveResponse
)
for {
select {
case keepResp = <-keepRespChan:
if keepResp == nil {
goto END
}
}
}
END:
}()
txn := u.kv.Txn(context.TODO())
lockkey := u.LockKey
txn.If(clientv3.Compare(clientv3.CreateRevision(lockkey), "=", 0)).Then(clientv3.OpPut(lockkey, "", clientv3.WithLease(leaseid))).
Else(clientv3.OpGet(lockkey))
var (
txnResp *clientv3.TxnResponse
)
if txnResp, err = txn.Commit(); err != nil {
return err
}
if !txnResp.Succeeded {
fmt.Println("版本更新了!")
}
fmt.Println("dot it")
cnt++
return nil
}
func Test_llock(t *testing.T) {
if client, err = clientv3.New(conf); err != nil {
t.Log(err)
return
}
maxn := 50
var wg sync.WaitGroup
for i := 0; i < maxn; i++ {
wg.Add(1)
go func() {
ll := New(client)
ll.LockTest0()
wg.Done()
}()
}
wg.Wait()
if cnt != maxn {
t.Errorf("errror cnt=%d, want %d", cnt, maxn)
} else {
t.Logf("succeess cnt=%d, want %d", cnt, maxn)
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?