- 下載: etcd-v3.3.18-linux-amd64.tar.gz ;解壓: tar -zxvf etcd-v3.3.18-linux-amd64.tar.gz
解壓後的情況如下:
其中etcd是服務端程序,etcdctl是客戶端程序。
2. 啓動etcd服務(後臺啓動,並監聽公網IP,默認只監聽localhost):
nohup ./etcd --listen-client-urls ‘http://0.0.0.0:2379’ --advertise-client-urls ‘http://0.0.0.0:2379’ &
使用less nohup.out 命令可以查看nohup.out 中的日誌輸出。
3. 設置環境變量,將etcd的接口版本切換到V3
export ETCDCTL_API=3
4. 下載etcd go語言客戶端代碼:
https://github.com/etcd-io/etcd
使用go get 下載速度很慢,可以去golang中國下載相應的包。
將GitHub中項目代碼對應的路徑複製到“導入路徑”這一欄目中(不能有HTTP前綴,不然會報錯)。
5. 調整etcdclientv3的目錄,導入時如下所示:
GoWorks\src\go.etcd.io\etcd (etcd爲下載後解壓的代碼)
完成前面5步後,就可以開始使用etcd 的go語言接口進行編程操作了。
獲取指定目錄下的內容:
func main() {
var (
config clientv3.Config
client *clientv3.Client
err error
kv clientv3.KV
//putResp *clientv3.PutResponse
getResp *clientv3.GetResponse
)
config = clientv3.Config{
Endpoints:[]string{"11.32.225.63:2379"}, // 集羣列表
DialTimeout:5 * time.Second,
}
// 建立一個客戶端
if client,err = clientv3.New(config); err != nil{
fmt.Println(err)
return
}
defer client.Close()
// 讀寫etcd的鍵值對
kv = clientv3.NewKV(client)
// 讀取/cron/jobs/爲前綴的所有key
if getResp, err = kv.Get(context.TODO(), "/corn/jobs/", clientv3.WithPrefix()); err != nil{
fmt.Println(err)
}else{
// 獲取成功,遍歷所有的kvs
fmt.Println(getResp.Kvs)
}
}
clientv3.KV下的操作包括最基礎的Get/Put/Delete,分別用於獲取/存入/刪除一個鍵值對。
租約和事務操作:
func main() {
var (
config clientv3.Config
client *clientv3.Client
err error
kv clientv3.KV
lease clientv3.Lease
leaseGrantResp *clientv3.LeaseGrantResponse
leaseID clientv3.LeaseID
keepResp *clientv3.LeaseKeepAliveResponse
keepRespChan <-chan *clientv3.LeaseKeepAliveResponse
ctx context.Context
cancelFunc context.CancelFunc
txn clientv3.Txn
txnResp *clientv3.TxnResponse
)
config = clientv3.Config{
Endpoints:[]string{"11.32.225.63:2379"}, // 集羣列表
DialTimeout:5 * time.Second,
}
// 建立一個客戶端
if client,err = clientv3.New(config); err != nil{
fmt.Println(err)
return
}
defer client.Close()
//lease 實現鎖自動過期
//op操作
//txn事務: if else then
// 申請一個租約lease
lease = clientv3.NewLease(client)
// 申請一個5s的租約
if leaseGrantResp, err = lease.Grant(context.TODO(), 5);err != nil{
fmt.Println(err)
return
}
// 拿到租約的ID
leaseID = leaseGrantResp.ID
// 準備一個用於取消自動續租的context
ctx, cancelFunc = context.WithCancel(context.TODO())
// 確保函數退出後,自動續租會停止
defer cancelFunc()
defer lease.Revoke(context.TODO(), leaseID)
// 自動續約,5s後取消自動續約
if keepRespChan,err = lease.KeepAlive(ctx, leaseID);err != nil{
fmt.Println(err)
return
}
// 處理續約的應答協程
go func() {
for{
select {
case keepResp = <-keepRespChan:
if keepResp == nil{
fmt.Println("租約已經失效了")
goto END
}else{
fmt.Println("收到自動續約應答:", keepResp.ID)
}
}
}
END:
}()
// if 不存在key, then設置它,else搶鎖失敗
kv = clientv3.NewKV(client)
// 1 創建事務
txn = kv.Txn(context.TODO())
//定義事務
// 如果key不存在
txn.If(clientv3.Compare(clientv3.CreateRevision("/cron/lock/job9"), "=", 0)).
Then(clientv3.OpPut("/cron/lock/job9", "XXX", clientv3.WithLease(leaseID))).
Else(clientv3.OpGet("/cron/lock/job9")) // 搶鎖失敗
// 提交事務
if txnResp,err = txn.Commit();err!=nil{
fmt.Println(err)
return
}
// 判斷是否搶到鎖
if !txnResp.Succeeded{
fmt.Println("鎖被佔用:", string(txnResp.Responses[0].GetResponseRange().Kvs[0].Value))
return
}
// 2 處理業務
fmt.Println("處理任務")
time.Sleep(5 * time.Second)
// 3 釋放鎖(取消自動續租,釋放租約)
// defer會把租約釋放掉,關聯的KV就會被刪除
}
接口函數有很多,不能一一舉例了,自己試着調用一下,感覺學起來也還是挺快的。