Merge paradox/scala/cluster-usage.md and java/cluster-usage.md (#23154)
* Identical contents in scala/cluster-usage.md and java/cluster-usage.md for easier review * Replace java/cluster-usage.md with a symlink to scala/cluster-usage.md
This commit is contained in:
parent
17e07c0ae2
commit
48c8c1ab91
4 changed files with 160 additions and 876 deletions
|
|
@ -6,11 +6,23 @@ For introduction to the Akka Cluster concepts please see @ref:[Cluster Specifica
|
|||
|
||||
The Akka cluster is a separate jar file. Make sure that you have the following dependency in your project:
|
||||
|
||||
@@@vars
|
||||
```
|
||||
"com.typesafe.akka" %% "akka-cluster" % "$akka.version$"
|
||||
```
|
||||
@@@
|
||||
Scala
|
||||
: @@@vars
|
||||
```
|
||||
"com.typesafe.akka" %% "akka-cluster" % "$akka.version$"
|
||||
```
|
||||
@@@
|
||||
|
||||
Java
|
||||
: @@@vars
|
||||
```
|
||||
<dependency>
|
||||
<groupId>com.typesafe.akka</groupId>
|
||||
<artifactId>akka-cluster_$scala.binary_version$</artifactId>
|
||||
<version>$akka.version$</version>
|
||||
</dependency>
|
||||
```
|
||||
@@@
|
||||
|
||||
## A Simple Cluster Example
|
||||
|
||||
|
|
@ -73,15 +85,21 @@ ip-addresses or host names of the machines in `application.conf` instead of `127
|
|||
|
||||
An actor that uses the cluster extension may look like this:
|
||||
|
||||
@@snip [SimpleClusterListener.scala]($code$/scala/docs/cluster/SimpleClusterListener.scala) { type=scala }
|
||||
Scala
|
||||
: @@snip [SimpleClusterListener.scala]($code$/scala/docs/cluster/SimpleClusterListener.scala) { type=scala }
|
||||
|
||||
Java
|
||||
: @@snip [SimpleClusterListener.java]($code$/java/jdocs/cluster/SimpleClusterListener.java) { type=java }
|
||||
|
||||
The actor registers itself as subscriber of certain cluster events. It receives events corresponding to the current state
|
||||
of the cluster when the subscription starts and then it receives events for changes that happen in the cluster.
|
||||
|
||||
The easiest way to run this example yourself is to download the ready to run
|
||||
@extref[Akka Cluster Sample with Scala](ecs:akka-samples-cluster-scala)
|
||||
@scala[@extref[Akka Cluster Sample with Scala](ecs:akka-samples-cluster-scala)]
|
||||
@java[@extref[Akka Cluster Sample with Java](ecs:akka-samples-cluster-java)]
|
||||
together with the tutorial. It contains instructions on how to run the `SimpleClusterApp`.
|
||||
The source code of this sample can be found in the @extref[Akka Samples Repository](samples:akka-sample-cluster-scala).
|
||||
The source code of this sample can be found in the
|
||||
@scala[@extref[Akka Samples Repository](samples:akka-sample-cluster-scala)]@java[@extref[Akka Samples Repository](samples:akka-sample-cluster-java)].
|
||||
|
||||
## Joining to Seed Nodes
|
||||
|
||||
|
|
@ -123,7 +141,7 @@ seed nodes in the existing cluster.
|
|||
If you don't configure seed nodes you need to join the cluster programmatically or manually.
|
||||
|
||||
Manual joining can be performed by using [JMX](#cluster-jmx) or [HTTP](#cluster-http).
|
||||
Joining programmatically can be performed with `Cluster(system).join`. Unsuccessful join attempts are
|
||||
Joining programmatically can be performed with @scala[`Cluster(system).join`]@java[`Cluster.get(system).join`]. Unsuccessful join attempts are
|
||||
automatically retried after the time period defined in configuration property `retry-unsuccessful-join-after`.
|
||||
Retries can be disabled by setting the property to `off`.
|
||||
|
||||
|
|
@ -131,7 +149,7 @@ You can join to any node in the cluster. It does not have to be configured as a
|
|||
Note that you can only join to an existing cluster member, which means that for bootstrapping some
|
||||
node must join itself,and then the following nodes could join them to make up a cluster.
|
||||
|
||||
You may also use `Cluster(system).joinSeedNodes` to join programmatically,
|
||||
You may also use @scala[`Cluster(system).joinSeedNodes`]@java[`Cluster.get(system).joinSeedNodes`] to join programmatically,
|
||||
which is attractive when dynamically discovering other nodes at startup by using some external tool or API.
|
||||
When using `joinSeedNodes` you should not include the node itself except for the node that is
|
||||
supposed to be the first seed node, and that should be placed first in parameter to
|
||||
|
|
@ -146,7 +164,7 @@ configured `seed-node-timeout`.
|
|||
|
||||
An actor system can only join a cluster once. Additional attempts will be ignored.
|
||||
When it has successfully joined it must be restarted to be able to join another
|
||||
cluster or to join the same cluster again.It can use the same host name and port
|
||||
cluster or to join the same cluster again. It can use the same host name and port
|
||||
after the restart, when it come up as new incarnation of existing member in the cluster,
|
||||
trying to join in, then the existing one will be removed from the cluster and then it will
|
||||
be allowed to join.
|
||||
|
|
@ -168,7 +186,7 @@ status of the unreachable member must be changed to 'Down'. Changing status to '
|
|||
can be performed automatically or manually. By default it must be done manually, using
|
||||
[JMX](#cluster-jmx) or [HTTP](#cluster-http).
|
||||
|
||||
It can also be performed programmatically with `Cluster(system).down(address)`.
|
||||
It can also be performed programmatically with @scala[`Cluster(system).down(address)`]@java[`Cluster.get(system).down(address)`].
|
||||
|
||||
A pre-packaged solution for the downing problem is provided by
|
||||
[Split Brain Resolver](http://developer.lightbend.com/docs/akka-commercial-addons/current/split-brain-resolver.html),
|
||||
|
|
@ -217,7 +235,11 @@ A more graceful exit can be performed if you tell the cluster that a node shall
|
|||
This can be performed using [JMX](#cluster-jmx) or [HTTP](#cluster-http).
|
||||
It can also be performed programmatically with:
|
||||
|
||||
@@snip [ClusterDocSpec.scala]($code$/scala/docs/cluster/ClusterDocSpec.scala) { #leave }
|
||||
Scala
|
||||
: @@snip [ClusterDocSpec.scala]($code$/scala/docs/cluster/ClusterDocSpec.scala) { #leave }
|
||||
|
||||
Java
|
||||
: @@snip [ClusterDocTest.java]($code$/java/jdocs/cluster/ClusterDocTest.java) { #leave }
|
||||
|
||||
Note that this command can be issued to any member in the cluster, not necessarily the
|
||||
one that is leaving.
|
||||
|
|
@ -257,9 +279,13 @@ have no knowledge about the existence of the new members. You should for example
|
|||
## Subscribe to Cluster Events
|
||||
|
||||
You can subscribe to change notifications of the cluster membership by using
|
||||
`Cluster(system).subscribe`.
|
||||
@scala[`Cluster(system).subscribe`]@java[`Cluster.get(system).subscribe`].
|
||||
|
||||
@@snip [SimpleClusterListener2.scala]($code$/scala/docs/cluster/SimpleClusterListener2.scala) { #subscribe }
|
||||
Scala
|
||||
: @@snip [SimpleClusterListener2.scala]($code$/scala/docs/cluster/SimpleClusterListener2.scala) { #subscribe }
|
||||
|
||||
Java
|
||||
: @@snip [SimpleClusterListener2.java]($code$/java/jdocs/cluster/SimpleClusterListener2.java) { #subscribe }
|
||||
|
||||
A snapshot of the full state, `akka.cluster.ClusterEvent.CurrentClusterState`, is sent to the subscriber
|
||||
as the first message, followed by events for incremental updates.
|
||||
|
|
@ -270,19 +296,23 @@ This is expected behavior. When the node has been accepted in the cluster you wi
|
|||
receive `MemberUp` for that node, and other nodes.
|
||||
|
||||
If you find it inconvenient to handle the `CurrentClusterState` you can use
|
||||
`ClusterEvent.InitialStateAsEvents` as parameter to `subscribe`.
|
||||
@scala[`ClusterEvent.InitialStateAsEvents`] @java[`ClusterEvent.initialStateAsEvents()`] as parameter to `subscribe`.
|
||||
That means that instead of receiving `CurrentClusterState` as the first message you will receive
|
||||
the events corresponding to the current state to mimic what you would have seen if you were
|
||||
listening to the events when they occurred in the past. Note that those initial events only correspond
|
||||
to the current state and it is not the full history of all changes that actually has occurred in the cluster.
|
||||
|
||||
@@snip [SimpleClusterListener.scala]($code$/scala/docs/cluster/SimpleClusterListener.scala) { #subscribe }
|
||||
Scala
|
||||
: @@snip [SimpleClusterListener.scala]($code$/scala/docs/cluster/SimpleClusterListener.scala) { #subscribe }
|
||||
|
||||
Java
|
||||
: @@snip [SimpleClusterListener.java]($code$/java/jdocs/cluster/SimpleClusterListener.java) { #subscribe }
|
||||
|
||||
The events to track the life-cycle of members are:
|
||||
|
||||
* `ClusterEvent.MemberJoined` - A new member has joined the cluster and its status has been changed to `Joining`.
|
||||
* `ClusterEvent.MemberUp` - A new member has joined the cluster and its status has been changed to `Up`.
|
||||
* `ClusterEvent.MemberExited` - A member is leaving the cluster and its status has been changed to `Exiting`.
|
||||
* `ClusterEvent.MemberJoined` - A new member has joined the cluster and its status has been changed to `Joining`
|
||||
* `ClusterEvent.MemberUp` - A new member has joined the cluster and its status has been changed to `Up`
|
||||
* `ClusterEvent.MemberExited` - A member is leaving the cluster and its status has been changed to `Exiting`
|
||||
Note that the node might already have been shutdown when this event is published on another node.
|
||||
* `ClusterEvent.MemberRemoved` - Member completely removed from the cluster.
|
||||
* `ClusterEvent.UnreachableMember` - A member is considered as unreachable, detected by the failure detector
|
||||
|
|
@ -295,7 +325,7 @@ of classes that extends `akka.cluster.ClusterEvent.ClusterDomainEvent`
|
|||
for details about the events.
|
||||
|
||||
Instead of subscribing to cluster events it can sometimes be convenient to only get the full membership state with
|
||||
`Cluster(system).state`. Note that this state is not necessarily in sync with the events published to a
|
||||
@scala[`Cluster(system).state`]@java[`Cluster.get(system).state()`]. Note that this state is not necessarily in sync with the events published to a
|
||||
cluster subscription.
|
||||
|
||||
### Worker Dial-in Example
|
||||
|
|
@ -311,11 +341,19 @@ added or removed to the cluster dynamically.
|
|||
|
||||
Messages:
|
||||
|
||||
@@snip [TransformationMessages.scala]($code$/scala/docs/cluster/TransformationMessages.scala) { #messages }
|
||||
Scala
|
||||
: @@snip [TransformationMessages.scala]($code$/scala/docs/cluster/TransformationMessages.scala) { #messages }
|
||||
|
||||
Java
|
||||
: @@snip [TransformationMessages.java]($code$/java/jdocs/cluster/TransformationMessages.java) { #messages }
|
||||
|
||||
The backend worker that performs the transformation job:
|
||||
|
||||
@@snip [TransformationBackend.scala]($code$/scala/docs/cluster/TransformationBackend.scala) { #backend }
|
||||
Scala
|
||||
: @@snip [TransformationBackend.scala]($code$/scala/docs/cluster/TransformationBackend.scala) { #backend }
|
||||
|
||||
Java
|
||||
: @@snip [TransformationBackend.java]($code$/java/jdocs/cluster/TransformationBackend.java) { #backend }
|
||||
|
||||
Note that the `TransformationBackend` actor subscribes to cluster events to detect new,
|
||||
potential, frontend nodes, and send them a registration message so that they know
|
||||
|
|
@ -323,7 +361,11 @@ that they can use the backend worker.
|
|||
|
||||
The frontend that receives user jobs and delegates to one of the registered backend workers:
|
||||
|
||||
@@snip [TransformationFrontend.scala]($code$/scala/docs/cluster/TransformationFrontend.scala) { #frontend }
|
||||
Scala
|
||||
: @@snip [TransformationFrontend.scala]($code$/scala/docs/cluster/TransformationFrontend.scala) { #frontend }
|
||||
|
||||
Java
|
||||
: @@snip [TransformationFrontend.java]($code$/java/jdocs/cluster/TransformationFrontend.java) { #frontend }
|
||||
|
||||
Note that the `TransformationFrontend` actor watch the registered backend
|
||||
to be able to remove it from its list of available backend workers.
|
||||
|
|
@ -333,9 +375,11 @@ actor. Death watch generates the `Terminated` message to the watching actor when
|
|||
unreachable cluster node has been downed and removed.
|
||||
|
||||
The easiest way to run **Worker Dial-in Example** example yourself is to download the ready to run
|
||||
@extref[Akka Cluster Sample with Scala](ecs:akka-samples-cluster-scala)
|
||||
@scala[@extref[Akka Cluster Sample with Scala](ecs:akka-samples-cluster-scala)]
|
||||
@java[@extref[Akka Cluster Sample with Java](ecs:akka-samples-cluster-java)]
|
||||
together with the tutorial. It contains instructions on how to run the **Worker Dial-in Example** sample.
|
||||
The source code of this sample can be found in the @extref[Akka Samples Repository](samples:akka-sample-cluster-scala).
|
||||
The source code of this sample can be found in the
|
||||
@scala[@extref[Akka Samples Repository](samples:akka-sample-cluster-scala)]@java[@extref[Akka Samples Repository](samples:akka-sample-cluster-java)].
|
||||
|
||||
## Node Roles
|
||||
|
||||
|
|
@ -375,7 +419,11 @@ You can start the actors in a `registerOnMemberUp` callback, which will
|
|||
be invoked when the current member status is changed to 'Up', i.e. the cluster
|
||||
has at least the defined number of members.
|
||||
|
||||
@@snip [FactorialFrontend.scala]($code$/scala/docs/cluster/FactorialFrontend.scala) { #registerOnUp }
|
||||
Scala
|
||||
: @@snip [FactorialFrontend.scala]($code$/scala/docs/cluster/FactorialFrontend.scala) { #registerOnUp }
|
||||
|
||||
Java
|
||||
: @@snip [FactorialFrontendMain.java]($code$/java/jdocs/cluster/FactorialFrontendMain.java) { #registerOnUp }
|
||||
|
||||
This callback can be used for other things than starting actors.
|
||||
|
||||
|
|
@ -410,7 +458,7 @@ Distributes actors across several nodes in the cluster and supports interaction
|
|||
with the actors using their logical identifier, but without having to care about
|
||||
their physical location in the cluster.
|
||||
|
||||
See @ref:[Cluster Sharding](cluster-sharding.md)
|
||||
See @ref:[Cluster Sharding](cluster-sharding.md).
|
||||
|
||||
## Distributed Publish Subscribe
|
||||
|
||||
|
|
@ -575,7 +623,11 @@ Set it to a lower value if you want to limit total number of routees.
|
|||
|
||||
The same type of router could also have been defined in code:
|
||||
|
||||
@@snip [StatsService.scala]($akka$/akka-cluster-metrics/src/multi-jvm/scala/akka/cluster/metrics/sample/StatsService.scala) { #router-lookup-in-code }
|
||||
Scala
|
||||
: @@snip [StatsService.scala]($akka$/akka-cluster-metrics/src/multi-jvm/scala/akka/cluster/metrics/sample/StatsService.scala) { #router-lookup-in-code }
|
||||
|
||||
Java
|
||||
: @@snip [StatsService.java]($code$/java/jdocs/cluster/StatsService.java) { #router-lookup-in-code }
|
||||
|
||||
See [configuration](#cluster-configuration) section for further descriptions of the settings.
|
||||
|
||||
|
|
@ -592,16 +644,35 @@ the average number of characters per word when all results have been collected.
|
|||
|
||||
Messages:
|
||||
|
||||
@@snip [StatsMessages.scala]($akka$/akka-cluster-metrics/src/multi-jvm/scala/akka/cluster/metrics/sample/StatsMessages.scala) { #messages }
|
||||
Scala
|
||||
: @@snip [StatsMessages.scala]($akka$/akka-cluster-metrics/src/multi-jvm/scala/akka/cluster/metrics/sample/StatsMessages.scala) { #messages }
|
||||
|
||||
Java
|
||||
: @@snip [StatsMessages.java]($code$/java/jdocs/cluster/StatsMessages.java) { #messages }
|
||||
|
||||
The worker that counts number of characters in each word:
|
||||
|
||||
@@snip [StatsWorker.scala]($akka$/akka-cluster-metrics/src/multi-jvm/scala/akka/cluster/metrics/sample/StatsWorker.scala) { #worker }
|
||||
Scala
|
||||
: @@snip [StatsWorker.scala]($akka$/akka-cluster-metrics/src/multi-jvm/scala/akka/cluster/metrics/sample/StatsWorker.scala) { #worker }
|
||||
|
||||
Java
|
||||
: @@snip [StatsWorker.java]($code$/java/jdocs/cluster/StatsWorker.java) { #worker }
|
||||
|
||||
The service that receives text from users and splits it up into words, delegates to workers and aggregates:
|
||||
|
||||
@@@ div { .group-scala }
|
||||
|
||||
@@snip [StatsService.scala]($akka$/akka-cluster-metrics/src/multi-jvm/scala/akka/cluster/metrics/sample/StatsService.scala) { #service }
|
||||
|
||||
@@@
|
||||
|
||||
@@@ div { .group-java }
|
||||
|
||||
@@snip [StatsService.java]($code$/java/jdocs/cluster/StatsService.java) { #service }
|
||||
@@snip [StatsAggregator.java]($code$/java/jdocs/cluster/StatsAggregator.java) { #aggregator }
|
||||
|
||||
@@@
|
||||
|
||||
Note, nothing cluster specific so far, just plain actors.
|
||||
|
||||
All nodes start `StatsService` and `StatsWorker` actors. Remember, routees are the workers in this case.
|
||||
|
|
@ -625,9 +696,11 @@ This means that user requests can be sent to `StatsService` on any node and it w
|
|||
`StatsWorker` on all nodes.
|
||||
|
||||
The easiest way to run **Router Example with Group of Routees** example yourself is to download the ready to run
|
||||
@extref[Akka Cluster Sample with Scala](ecs:akka-samples-cluster-scala)
|
||||
@scala[@extref[Akka Cluster Sample with Scala](ecs:akka-samples-cluster-scala)]
|
||||
@java[@extref[Akka Cluster Sample with Java](ecs:akka-samples-cluster-java)]
|
||||
together with the tutorial. It contains instructions on how to run the **Router Example with Group of Routees** sample.
|
||||
The source code of this sample can be found in the @extref[Akka Samples Repository](samples:akka-sample-cluster-scala).
|
||||
The source code of this sample can be found in the
|
||||
@scala[@extref[Akka Samples Repository](samples:akka-sample-cluster-scala)]@java[@extref[Akka Samples Repository](samples:akka-sample-cluster-java)].
|
||||
|
||||
### Router with Pool of Remote Deployed Routees
|
||||
|
||||
|
|
@ -658,7 +731,11 @@ Set it to a lower value if you want to limit total number of routees.
|
|||
|
||||
The same type of router could also have been defined in code:
|
||||
|
||||
@@snip [StatsService.scala]($akka$/akka-cluster-metrics/src/multi-jvm/scala/akka/cluster/metrics/sample/StatsService.scala) { #router-deploy-in-code }
|
||||
Scala
|
||||
: @@snip [StatsService.scala]($akka$/akka-cluster-metrics/src/multi-jvm/scala/akka/cluster/metrics/sample/StatsService.scala) { #router-deploy-in-code }
|
||||
|
||||
Java
|
||||
: @@snip [StatsService.java]($code$/java/jdocs/cluster/StatsService.java) { #router-deploy-in-code }
|
||||
|
||||
See [configuration](#cluster-configuration) section for further descriptions of the settings.
|
||||
|
||||
|
|
@ -666,27 +743,39 @@ See [configuration](#cluster-configuration) section for further descriptions of
|
|||
|
||||
Let's take a look at how to use a cluster aware router on single master node that creates
|
||||
and deploys workers. To keep track of a single master we use the @ref:[Cluster Singleton](cluster-singleton.md)
|
||||
in the cluster-tools module. The `ClusterSingletonManager` is started on each node.:
|
||||
in the cluster-tools module. The `ClusterSingletonManager` is started on each node:
|
||||
|
||||
```
|
||||
system.actorOf(
|
||||
ClusterSingletonManager.props(
|
||||
singletonProps = Props[StatsService],
|
||||
terminationMessage = PoisonPill,
|
||||
settings = ClusterSingletonManagerSettings(system).withRole("compute")),
|
||||
name = "statsService")
|
||||
```
|
||||
Scala
|
||||
: @@@vars
|
||||
```
|
||||
system.actorOf(
|
||||
ClusterSingletonManager.props(
|
||||
singletonProps = Props[StatsService],
|
||||
terminationMessage = PoisonPill,
|
||||
settings = ClusterSingletonManagerSettings(system).withRole("compute")),
|
||||
name = "statsService")
|
||||
```
|
||||
@@@
|
||||
|
||||
Java
|
||||
: @@snip [StatsSampleOneMasterMain.java]($code$/java/jdocs/cluster/StatsSampleOneMasterMain.java) { #create-singleton-manager }
|
||||
|
||||
We also need an actor on each node that keeps track of where current single master exists and
|
||||
delegates jobs to the `StatsService`. That is provided by the `ClusterSingletonProxy`.:
|
||||
delegates jobs to the `StatsService`. That is provided by the `ClusterSingletonProxy`:
|
||||
|
||||
```
|
||||
system.actorOf(
|
||||
ClusterSingletonProxy.props(
|
||||
singletonManagerPath = "/user/statsService",
|
||||
settings = ClusterSingletonProxySettings(system).withRole("compute")),
|
||||
name = "statsServiceProxy")
|
||||
```
|
||||
Scala
|
||||
: @@@vars
|
||||
```
|
||||
system.actorOf(
|
||||
ClusterSingletonProxy.props(
|
||||
singletonManagerPath = "/user/statsService",
|
||||
settings = ClusterSingletonProxySettings(system).withRole("compute")),
|
||||
name = "statsServiceProxy")
|
||||
```
|
||||
@@@
|
||||
|
||||
Java
|
||||
: @@snip [StatsSampleOneMasterMain.java]($code$/java/jdocs/cluster/StatsSampleOneMasterMain.java) { #singleton-proxy }
|
||||
|
||||
The `ClusterSingletonProxy` receives text from users and delegates to the current `StatsService`, the single
|
||||
master. It listens to cluster events to lookup the `StatsService` on the oldest node.
|
||||
|
|
@ -708,15 +797,19 @@ akka.actor.deployment {
|
|||
```
|
||||
|
||||
The easiest way to run **Router Example with Pool of Remote Deployed Routees** example yourself is to download the ready to run
|
||||
@extref[Akka Cluster Sample with Scala](ecs:akka-samples-cluster-scala)
|
||||
@scala[@extref[Akka Cluster Sample with Scala](ecs:akka-samples-cluster-scala)]
|
||||
@java[@extref[Akka Cluster Sample with Java](ecs:akka-samples-cluster-java)]
|
||||
together with the tutorial. It contains instructions on how to run the **Router Example with Pool of Remote Deployed Routees** sample.
|
||||
The source code of this sample can be found in the @extref[Akka Samples Repository](samples:akka-sample-cluster-scala).
|
||||
The source code of this sample can be found in the
|
||||
@scala[@extref[Akka Samples Repository](samples:akka-sample-cluster-scala)]@java[@extref[Akka Samples Repository](samples:akka-sample-cluster-java)].
|
||||
|
||||
## Cluster Metrics
|
||||
|
||||
The member nodes of the cluster can collect system health metrics and publish that to other cluster nodes
|
||||
and to the registered subscribers on the system event bus with the help of `cluster-metrics`.
|
||||
|
||||
@@@ div { .group-scala }
|
||||
|
||||
## How to Test
|
||||
|
||||
@ref:[Multi Node Testing](multi-node-testing.md) is useful for testing cluster applications.
|
||||
|
|
@ -769,6 +862,17 @@ the actor system for a specific role. This can also be used to grab the `akka.ac
|
|||
|
||||
@@snip [StatsSampleSpec.scala]($akka$/akka-cluster-metrics/src/multi-jvm/scala/akka/cluster/metrics/sample/StatsSampleSpec.scala) { #addresses }
|
||||
|
||||
@@@
|
||||
|
||||
@@@ div { .group-java }
|
||||
|
||||
## How to Test
|
||||
|
||||
Currently testing with the `sbt-multi-jvm` plugin is only documented for Scala.
|
||||
Go to the corresponding @ref[Scala page](../scala/cluster-usage.md#how-to-test) for details.
|
||||
|
||||
@@@
|
||||
|
||||
## Management
|
||||
|
||||
<a id="cluster-http"></a>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue