我编写了一个简单的go应用程序,并添加了一个flock系统,以防止同时运行两次:
import "github.com/nightlyone/lockfile"
lock, err := lockfile.New(filepath.Join(os.TempDir(), "pagerduty-read-api.lock"))
if err != nil {
panic(err)
}
if err = lock.TryLock(); err != nil {
fmt.Println("Already running.")
return
}
defer lock.Unlock()
它在我的主机上运行良好。在docker上,我尝试通过
tmp
的卷共享运行它:docker run --rm -it -v /tmp:/tmp my-go-binary
但这是行不通的。我想这是因为羊群系统没有移植到卷共享上。
我的问题:Docker是否可以选择让群集在正在运行的实例之间工作?如果没有,那么我具有相同行为的其他选择是什么?
谢谢。
最佳答案
今天早上,我编写了一个小小的Python测试程序,该程序仅将一百万个连续的整数写入文件,并带有flock()锁定,为每个附加的数字获取并释放一次锁定。我启动了5个容器,每个容器运行该测试程序,并且每个容器都写入Docker卷中的相同文件。
启用锁定后,所有数字均互不干扰地写入,并且文件中正好有500万个整数。用这种方式编写时,它们不是连续的,但这是预期的,并且与flock()一致。
在没有锁定的情况下,许多数字以指示数字正在违反多任务无锁定的方式写入。文件中只有3,167,546的数字,并且有13,357空行。这总共增加了文件中的3,180,903行-与所需的5,000,000行实质上不同。
尽管一个程序仅通过多次测试就不能最终证明不会有问题,但是对我来说,这是一个令人信服的论点,即Linux flock()可跨容器工作。
同样,羊群可以跨容器工作也很有意义。容器几乎只是一个共享内核,不同的pid,不同的文件(卷除外)和不同的IP端口空间。
我在具有Linux内核4.15.0-20通用,Docker 19.03.0的Linux Mint 19.1系统上运行了测试-构建aeac949和CPython 3.6.8。
Go是一种很酷的语言,但是我不知道为什么flock()在跨Go程序的卷中似乎没有起作用。
HTH。
关于docker - Docker和文件锁定,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55361769/