协作
- 警告:此模块当前标记为「可能更改」。它已准备好用于生产,但 API 可能在没有警告或预测期的情况下发生变化。
Akka 协作(Coordination
)是一套用于分布式协作的工具。
Discovery
曾是 Akka 管理的一部分,但从 Akka 的2.5.19
版和 Akka 管理的1.0.0
版开始,它已成为 Akka 的模块。如果你还将 Akka 管理用于其他服务发现方法或加载程序,请确保你至少使用了 Akka 管理(Management
)的1.0.0
版本。
依赖
为了使用 Akka 协作,你需要将以下依赖添加到你的项目中:
<!-- Maven -->
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-coordination_2.12</artifactId>
<version>2.5.23</version>
</dependency>
<!-- Gradle -->
dependencies {
compile group: 'com.typesafe.akka', name: 'akka-coordination_2.12', version: '2.5.23'
}
<!-- sbt -->
libraryDependencies += "com.typesafe.akka" %% "akka-coordination" % "2.5.23"
Lease
Lease
是分布式锁的可插拔 API。
使用 Lease
Lease
通过以下方式加载:
Lease
名称- 配置位置以指示应加载哪个实现
- 所有者名称
任何Lease
实现应提供以下保证:
- 同一名称的
Lease
多次加载,即使在不同的节点上,也是同一Lease
- 一次只能有一个所有者获得
Lease
获取Lease
:
Lease lease =
LeaseProvider.get(system).getLease("<name of the lease>", "docs-lease", "<owner name>");
CompletionStage<Boolean> acquired = lease.acquire();
boolean stillAcquired = lease.checkLease();
CompletionStage<Boolean> released = lease.release();
获取Lease
会返回一个CompletionStage
,因为Lease
实现通常是通过第三方系统(如 Kubernetes API 服务器或 ZooKeeper)实现的。
一旦获得Lease
,就可以调用checkLease
以确保Lease
仍然被获得。由于Lease
实现基于其他分布式系统,因此Lease
可能会因第三方系统超时而丢失。此操作不是异步的,因此可以在执行任何具有Lease
的操作之前调用它。
Lease
有一个所有者。如果同一所有者多次尝试获取Lease
,那么它将成功,即Lease
是可重入的。
选择一个对你的用例来说是唯一的Lease
名称是很重要的。如果集群中每个节点的Lease
都需要唯一,那么可以使用群集主机端口:
String owner = Cluster.get(system).selfAddress().hostPort();
对于在同一节点上有多个不同Lease
的用例,必须在名称中添加一些唯一的东西。例如,Lease
可以与集群分片(Cluster Sharding
)一起使用,在这种情况下,分片 ID 包含在每个分片的Lease
名称中。
其他 Akka 模块的用途
Lease 实现
实现一个 Lease
实现应该扩展akka.coordination.lease.javadsl.Lease
static class SampleLease extends Lease {
private LeaseSettings settings;
public SampleLease(LeaseSettings settings) {
this.settings = settings;
}
@Override
public LeaseSettings getSettings() {
return settings;
}
@Override
public CompletionStage<Boolean> acquire() {
return null;
}
@Override
public CompletionStage<Boolean> acquire(Consumer<Optional<Throwable>> leaseLostCallback) {
return null;
}
@Override
public CompletionStage<Boolean> release() {
return null;
}
@Override
public boolean checkLease() {
return false;
}
}
这些方法应提供以下保证:
acquire
:如果成功获取Lease
,则为true
;如果Lease
被其他所有者占用,则为false
;如果无法与实现Lease
的第三方系统通信,则失败。release
:如果Lease
已明确释放,则为true
;如果Lease
未明确释放,则为false
;如果不知道Lease
是否已释放,则失败。- 在
acquire
的CompletionStage
完成之前,checkLease
应返回false
;如果Lease
由于与第三方通信错误而丢失,也应该返回false
。检查Lease
也不应阻塞。 Lease lost callback
只能在acquire
的CompletionStage
完成后调用,如果Lease
丢失(例如,由于与第三方系统的通信丢失),则应调用该回调。
此外,期望Lease
的实现包括生存时间机制(a time to live mechanism
),这意味着在节点崩溃的情况下不会永远保留Lease
。如果用户希望在这种情况下进行外部干预以获得最大的安全性,那么生存时间可以设置为无限。
配置必须为Lease
实现的 FQCN 定义lease-class
属性。
如果默认值来自akka.coordination.lease
,则Lease
实现应支持以下属性:
# if the node that acquired the leases crashes, how long should the lease be held before another owner can get it
heartbeat-timeout = 120s
# interval for communicating with the third party to confirm the lease is still held
heartbeat-interval = 12s
# lease implementations are expected to time out acquire and release calls or document
# that they do not implement an operation timeout
lease-operation-timeout = 5s
此配置位置将传递到getLease
。
akka.actor.provider = cluster
docs-lease {
lease-class = "docs.akka.coordination.SampleLease"
heartbeat-timeout = 100s
heartbeat-interval = 1s
lease-operation-timeout = 1s
# Any lease specific configuration
}
英文原文链接:Coordination.