内容简介:通常的分布式的锁的应用场景有如下几种方式:本文主要讨论第2种场景中遇到的一个细节问题。
etcd
越来越多的被应用在分布式系统中,最典型的一个应用场景就是作为分布式锁,用于在分布式系统中保证资源的独占。
通常的分布式的锁的应用场景有如下几种方式:
etcd etcd
本文主要讨论第2种场景中遇到的一个细节问题。
在主备切换的场景,我们希望服务一旦获取到锁,就不必主动的与 etcd
交互,而是专心的进行自己的本职工作。但是如果不主动跟 etcd
询问持有的锁的状态的话,我们又无法保证当前是确实持有锁的。正如下边的代码:
package main
import (
"context"
"fmt"
"time"
"go.etcd.io/etcd/clientv3"
"go.etcd.io/etcd/clientv3/concurrency"
)
func main() {
client, errClient := clientv3.New(clientv3.Config{Endpoints: []string{"http://127.0.0.1:2379"}, DialTimeout: 10 * time.Second})
if errClient != nil {
fmt.Errorf("client create fail - %v", errClient)
return
}
session, errSession := concurrency.NewSession(client, concurrency.WithTTL(10))
if errSession != nil {
fmt.Errorf("create session fail - %v", errSession)
return
}
mutex := concurrency.NewMutex(session, "/lock")
if mutex == nil {
fmt.Errorf("create mutex fail")
return
}
errMutex := mutex.Lock(context.TODO())
if errMutex != nil {
fmt.Errorf("lock fail - %v", errMutex)
return
}
fmt.Println("got lock, begin run work")
go func() {
// do real work here
}()
// prevent progress quit
select {}
}
在 // do real work here
执行过程中,很可能我们的网络状态出现了问题,或者 etcd
服务出现问题导致程序已经跟网络断开,这时实际上锁很可能已经失效了。为了保证锁的有效性,我们可以在 session
的有效期内轮询锁的状态,但是这种做法很繁琐,也比较浪费资源。有没有更好的方式呢?
好在 session
提供了一个 Done
方法,该方法返回一个 channel
, 一旦 session
结束,这个 channel
就会被写入内容,这样就给了我们一个简单地方法来监控锁的状态。
package main
import (
"context"
"fmt"
"time"
"go.etcd.io/etcd/clientv3"
"go.etcd.io/etcd/clientv3/concurrency"
)
func main() {
client, errClient := clientv3.New(clientv3.Config{Endpoints: []string{"http://127.0.0.1:2379"}, DialTimeout: 10 * time.Second})
if errClient != nil {
fmt.Errorf("client create fail - %v", errClient)
return
}
session, errSession := concurrency.NewSession(client, concurrency.WithTTL(10))
if errSession != nil {
fmt.Errorf("create session fail - %v", errSession)
return
}
mutex := concurrency.NewMutex(session, "/lock")
if mutex == nil {
fmt.Errorf("create mutex fail")
return
}
errMutex := mutex.Lock(context.TODO())
if errMutex != nil {
fmt.Errorf("lock fail - %v", errMutex)
return
}
fmt.Println("got lock, begin run work")
go func() {
select {
case <-session.Done():
// do what ever you want to process lock lost
fmt.Println("lock lost")
}
}()
go func() {
// do real work
}()
// prevent progress quit
select {}
}
如上边的代码所示,我们在一个 goroutine
中监听一个 <-session.Done()
的 channel
,这样,一旦锁出现了问题,就会得到通知,这样就可以在这里进行一些锁丢失的善后工作,比如在这里停止所有的需要锁才能进行的工作,这样就不会出现锁已经失效,但是工作进程却全然不知的状况了。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- MQTT Essential 细节笔记总结(深入理解MQTT细节)
- MetInfo 7.0.0 20200326 细节优化补丁,主要优化商城相关细节
- MetInfo7.0.0 20200407 细节优化补丁,修复编辑及手机端细节
- php 的小细节
- 2021 Raft 实现细节
- iOS键盘动画细节
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Java语言精粹
Jim Waldo / 王江平 / 电子工业出版社 / 2011-6 / 39.00元
这是一本几乎只讲java优点的书。 Jim Waldo先生是原sun微系统公司实验室的杰出工程师,他亲历并参与了java从技术萌生、发展到崛起的整个过程。在这《java语言精粹》里,jim总结了他所认为的java语言及其环境的诸多精良部分,包括:类型系统、异常处理、包机制、垃圾回收、java虚拟机、javadoc、集合、远程方法调用和并发机制。另外,他还从开发者的角度分析了在java技术周围......一起来看看 《Java语言精粹》 这本书的介绍吧!
URL 编码/解码
URL 编码/解码
Markdown 在线编辑器
Markdown 在线编辑器