From cf58402dd92084fe39de07cdaa638764d2b2bae2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Endre=20S=C3=A1ndor=20Varga?= Date: Thu, 12 Dec 2013 13:05:59 +0100 Subject: [PATCH] !rem #3765: Change the defaults for remoting - removed retry-window and related settings - removed gate-invalid-addresses-for - gate is now mandatory - remoting has a dedicated dispatcher by default - updated tests to work with changed timings - added doc section for association lifecycle --- .../SurviveNetworkInstabilitySpec.scala | 52 +- .../contrib/pattern/ClusterShardingSpec.scala | 2 +- .../rst/images/association_lifecycle.png | Bin 0 -> 83124 bytes .../rst/images/association_lifecycle.svg | 447 ++++++++++++++++++ akka-docs/rst/java/remoting.rst | 24 + .../project/migration-guide-2.2.x-2.3.x.rst | 39 ++ akka-docs/rst/scala/remoting.rst | 23 + .../remote/RemoteNodeDeathWatchSpec.scala | 4 +- .../RemoteNodeRestartDeathWatchSpec.scala | 4 +- .../RemoteNodeShutdownAndComesBackSpec.scala | 19 +- akka-remote/src/main/resources/reference.conf | 67 ++- .../src/main/scala/akka/remote/Endpoint.scala | 24 +- .../scala/akka/remote/RemoteSettings.scala | 19 +- .../src/main/scala/akka/remote/Remoting.scala | 45 +- .../transport/ThrottlerTransportAdapter.scala | 2 - .../transport/netty/NettyTransport.scala | 2 +- .../scala/akka/remote/RemoteConfigSpec.scala | 19 +- .../transport/AkkaProtocolStressTest.scala | 28 +- .../SystemMessageDeliveryStressTest.scala | 17 +- .../ThrottlerTransportAdapterSpec.scala | 5 +- 20 files changed, 699 insertions(+), 143 deletions(-) create mode 100644 akka-docs/rst/images/association_lifecycle.png create mode 100644 akka-docs/rst/images/association_lifecycle.svg diff --git a/akka-cluster/src/multi-jvm/scala/akka/cluster/SurviveNetworkInstabilitySpec.scala b/akka-cluster/src/multi-jvm/scala/akka/cluster/SurviveNetworkInstabilitySpec.scala index 09f9e1f338..ff7eca00d4 100644 --- a/akka-cluster/src/multi-jvm/scala/akka/cluster/SurviveNetworkInstabilitySpec.scala +++ b/akka-cluster/src/multi-jvm/scala/akka/cluster/SurviveNetworkInstabilitySpec.scala @@ -49,10 +49,18 @@ object SurviveNetworkInstabilityMultiJvmSpec extends MultiNodeConfig { class RemoteChild extends Actor { import context.dispatcher - context.system.scheduler.scheduleOnce(500.millis, self, "boom") + def receive = { + case "hello" ⇒ + context.system.scheduler.scheduleOnce(2.seconds, self, "boom") + sender ! "hello" case "boom" ⇒ throw new SimulatedException - case x ⇒ sender ! x + } + } + + class Echo extends Actor { + def receive = { + case m ⇒ sender ! m } } @@ -70,8 +78,8 @@ class SurviveNetworkInstabilityMultiJvmNode8 extends SurviveNetworkInstabilitySp abstract class SurviveNetworkInstabilitySpec extends MultiNodeSpec(SurviveNetworkInstabilityMultiJvmSpec) - with MultiNodeClusterSpec - with ImplicitSender { + with MultiNodeClusterSpec + with ImplicitSender { import SurviveNetworkInstabilityMultiJvmSpec._ @@ -85,15 +93,31 @@ abstract class SurviveNetworkInstabilitySpec awaitAssert(clusterView.unreachableMembers.map(_.address) should be(expected)) } + system.actorOf(Props[Echo], "echo") + + def assertCanTalk(alive: RoleName*): Unit = { + runOn(alive: _*) { + for (to ← alive) { + val sel = system.actorSelection(node(to) / "user" / "echo") + awaitAssert { + sel ! "ping" + expectMsg(1.second, "ping") + } + } + } + enterBarrier("ping-ok") + } + "A network partition tolerant cluster" must { "reach initial convergence" taggedAs LongRunningTest in { awaitClusterUp(first, second, third, fourth, fifth) enterBarrier("after-1") + assertCanTalk(first, second, third, fourth, fifth) } - "heal after a broken pair" taggedAs LongRunningTest in within(30.seconds) { + "heal after a broken pair" taggedAs LongRunningTest in within(45.seconds) { runOn(first) { testConductor.blackhole(first, second, Direction.Both).await } @@ -119,9 +143,10 @@ abstract class SurviveNetworkInstabilitySpec awaitAllReachable() enterBarrier("after-2") + assertCanTalk(first, second, third, fourth, fifth) } - "heal after one isolated node" taggedAs LongRunningTest in within(30.seconds) { + "heal after one isolated node" taggedAs LongRunningTest in within(45.seconds) { val others = Vector(second, third, fourth, fifth) runOn(first) { for (other ← others) { @@ -145,9 +170,10 @@ abstract class SurviveNetworkInstabilitySpec enterBarrier("repair-3") awaitAllReachable() enterBarrier("after-3") + assertCanTalk((others :+ first): _*) } - "heal two isolated islands" taggedAs LongRunningTest in within(30.seconds) { + "heal two isolated islands" taggedAs LongRunningTest in within(45.seconds) { val island1 = Vector(first, second) val island2 = Vector(third, fourth, fifth) runOn(first) { @@ -175,9 +201,10 @@ abstract class SurviveNetworkInstabilitySpec enterBarrier("repair-4") awaitAllReachable() enterBarrier("after-4") + assertCanTalk((island1 ++ island2): _*) } - "heal after unreachable when ring is changed" taggedAs LongRunningTest in within(45.seconds) { + "heal after unreachable when ring is changed" taggedAs LongRunningTest in within(60.seconds) { val joining = Vector(sixth, seventh) val others = Vector(second, third, fourth, fifth) runOn(first) { @@ -220,9 +247,10 @@ abstract class SurviveNetworkInstabilitySpec awaitMembersUp(roles.size - 1) } enterBarrier("after-5") + assertCanTalk((joining ++ others): _*) } - "down and remove quarantined node" taggedAs LongRunningTest in within(45.seconds) { + "down and remove quarantined node" taggedAs LongRunningTest in within(60.seconds) { val others = Vector(first, third, fourth, fifth, sixth, seventh) runOn(second) { @@ -269,9 +297,10 @@ abstract class SurviveNetworkInstabilitySpec } enterBarrier("after-6") + assertCanTalk(others: _*) } - "continue and move Joining to Up after downing of one half" taggedAs LongRunningTest in within(45.seconds) { + "continue and move Joining to Up after downing of one half" taggedAs LongRunningTest in within(60.seconds) { // note that second is already removed in previous step val side1 = Vector(first, third, fourth) val side1AfterJoin = side1 :+ eighth @@ -331,8 +360,9 @@ abstract class SurviveNetworkInstabilitySpec } enterBarrier("after-7") + assertCanTalk((side1AfterJoin): _*) } } -} +} \ No newline at end of file diff --git a/akka-contrib/src/multi-jvm/scala/akka/contrib/pattern/ClusterShardingSpec.scala b/akka-contrib/src/multi-jvm/scala/akka/contrib/pattern/ClusterShardingSpec.scala index d9d695c25e..1c377f00fd 100644 --- a/akka-contrib/src/multi-jvm/scala/akka/contrib/pattern/ClusterShardingSpec.scala +++ b/akka-contrib/src/multi-jvm/scala/akka/contrib/pattern/ClusterShardingSpec.scala @@ -359,7 +359,7 @@ class ClusterShardingSpec extends MultiNodeSpec(ClusterShardingSpec) with STMult enterBarrier("after-7") } - "rebalance to nodes with less shards" in within(30 seconds) { + "rebalance to nodes with less shards" in within(60 seconds) { runOn(fourth) { // third, fourth and fifth are still alive diff --git a/akka-docs/rst/images/association_lifecycle.png b/akka-docs/rst/images/association_lifecycle.png new file mode 100644 index 0000000000000000000000000000000000000000..22c3a386da843ec63f89e5898c4a07d8f6be651c GIT binary patch literal 83124 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 + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + Quarantined + + Idle + + Active + + Gated + + + Gate time elapses + ● Message send toremote system● Successful inboundconnection + + Communicationfailure:● Failed TCP connection● Transport FD trigger● Name lookup failure● Remote system shutdown + (Connecting or Connected)Messages are deliveredor buffered if needed + + Successfulinbound connection + All outbound messages destined to the gated systemare dropped + Catastrophic communicationfailure:● Remote DeathWatch trigger● System message delivery failure● Cluster MemberRemoved event + All outbound and inboundmessages arriving from thequarantined system aredropped. Remote systemmust be restarted to be ableestablish communication again. + + + + + Successfulinbound our outboundconnection from/to restarted system + + diff --git a/akka-docs/rst/java/remoting.rst b/akka-docs/rst/java/remoting.rst index 0aafdadfd2..745abcb4ab 100644 --- a/akka-docs/rst/java/remoting.rst +++ b/akka-docs/rst/java/remoting.rst @@ -149,6 +149,30 @@ you can advise the system to create a child on that remote node like so: .. includecode:: code/docs/remoting/RemoteDeploymentDocTest.java#deploy + +Lifecycle and Failure Recovery Model +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. image:: ../images/association_lifecycle.png + :align: center + :width: 620 + +Each link with a remote system can be in one of the four states as illustrated above. Before any communication +happens with a remote system at a given ``Address`` the state of the association is ``Idle``. The first time a message +is attempted to be sent to the remote system or an inbound connection is accepted the state of the link transitions to +``Active`` denoting that the two systems has messages to send or receive and no failures were encountered so far. +When a communication failure happens and the connection is lost between the two systems the link becomes ``Gated``. + +In this state the system will not attempt to connect to the remote host and all outbound messages will be dropped. The time +while the link is in the ``Gated`` state is controlled by the setting ``akka.remote.retry-gate-closed-for``: +after this time elapses the link state transitions to ``Idle`` again. ``Gate`` is one-sided in the +sense that whenever a successful *inbound* connection is accepted from a remote system during ``Gate`` it automatically +transitions to ``Active`` and communication resumes immediately. + +In the face of communication failures that are unrecoverable because the state of the participating systems are inconsistent, +the remote system becomes ``Quarantined``. Unlike ``Gate``, quarantining is permanent and lasts until one of the systems +is restarted. After a restart communication can be resumed again and the link can become ``Active`` again. + Watching Remote Actors ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/akka-docs/rst/project/migration-guide-2.2.x-2.3.x.rst b/akka-docs/rst/project/migration-guide-2.2.x-2.3.x.rst index a371f1c25e..bc0048a9df 100644 --- a/akka-docs/rst/project/migration-guide-2.2.x-2.3.x.rst +++ b/akka-docs/rst/project/migration-guide-2.2.x-2.3.x.rst @@ -29,6 +29,8 @@ configured time of unreachability. This feature is disabled by default, as it al During the deprecation phase ``akka.cluster.auto-down=on`` is interpreted at as instant auto-down. + + ======= Routers ======= @@ -99,6 +101,43 @@ Changed cluster expected-response-after configuration Configuration property ``akka.cluster.failure-detector.heartbeat-request.expected-response-after`` has been renamed to ``akka.cluster.failure-detector.expected-response-after``. +Removed automatic retry feature from Remoting in favor of retry-gate +==================================================================== + +The retry-gate feature is now the only failure handling strategy in Remoting. This change means that when remoting detects faulty +connections it goes into a gated state where all buffered and subsequent remote messages are dropped until the configurable +time defined by the configuration key ``akka.remote.retry-gate-closed-for`` elapses after the failure event. This +behavior prevents reconnect storms and unbounded buffer growth during network instabilities. After the configured +time elapses the gate is lifted and a new connection will be attempted when there are new remote messages to be +delivered. + +In concert with this change all settings related to the old reconnect behavior (``akka.remote.retry-window`` and +``akka.remote.maximum-retries-in-window``) were removed. + +The timeout setting ``akka.remote.gate-invalid-addresses-for`` that controlled the gate interval for certain failure +events is also removed and all gating intervals are now controlled by the ``akka.remote.retry-gate-closed-for`` setting +instead. + +Reduced default sensitivity settings for transport failure detector in Remoting +=============================================================================== + +Since the most commonly used transport with Remoting is TCP, which provides proper connection termination events the failure detector sensitivity +setting ``akka.remote.transport-failure-detector.acceptable-heartbeat-pause`` now defaults to 20 seconds to reduce load induced +false-positive failure detection events in remoting. In case a non-connection-oriented protocol is used it is recommended +to change this and the ``akka.remote.transport-failure-detector.heartbeat-interval`` setting to a more sensitive value. + +Quarantine is now permanent +=========================== + +The setting that controlled the length of quarantine ``akka.remote.quarantine-systems-for`` has been removed. The only +setting available now is ``akka.remote.prune-quarantine-marker-after`` which influences how long quarantine tombstones +are kept around to avoid long-term memory leaks. This new setting defaults to 5 days. + +Remoting uses a dedicated dispatcher by default +=============================================== + +The default value of ``akka.remote.use-dispatcher`` has been changed to a dedicated dispatcher. + Dataflow is Deprecated ====================== diff --git a/akka-docs/rst/scala/remoting.rst b/akka-docs/rst/scala/remoting.rst index d215d8586a..d637c40a53 100644 --- a/akka-docs/rst/scala/remoting.rst +++ b/akka-docs/rst/scala/remoting.rst @@ -156,6 +156,29 @@ you can advise the system to create a child on that remote node like so: .. includecode:: code/docs/remoting/RemoteDeploymentDocSpec.scala#deploy +Lifecycle and Failure Recovery Model +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. image:: ../images/association_lifecycle.png +:align: center + :width: 620 + + Each link with a remote system can be in one of the four states as illustrated above. Before any communication + happens with a remote system at a given ``Address`` the state of the association is ``Idle``. The first time a message +is attempted to be sent to the remote system or an inbound connection is accepted the state of the link transitions to +``Active`` denoting that the two systems has messages to send or receive and no failures were encountered so far. +When a communication failure happens and the connection is lost between the two systems the link becomes ``Gated``. + +In this state the system will not attempt to connect to the remote host and all outbound messages will be dropped. The time +while the link is in the ``Gated`` state is controlled by the setting ``akka.remote.retry-gate-closed-for``: +after this time elapses the link state transitions to ``Idle`` again. ``Gate`` is one-sided in the +sense that whenever a successful *inbound* connection is accepted from a remote system during ``Gate`` it automatically +transitions to ``Active`` and communication resumes immediately. + +In the face of communication failures that are unrecoverable because the state of the participating systems are inconsistent, +the remote system becomes ``Quarantined``. Unlike ``Gate``, quarantining is permanent and lasts until one of the systems +is restarted. After a restart communication can be resumed again and the link can become ``Active`` again. + Watching Remote Actors ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/akka-remote-tests/src/multi-jvm/scala/akka/remote/RemoteNodeDeathWatchSpec.scala b/akka-remote-tests/src/multi-jvm/scala/akka/remote/RemoteNodeDeathWatchSpec.scala index c4064a3b39..c1814a8298 100644 --- a/akka-remote-tests/src/multi-jvm/scala/akka/remote/RemoteNodeDeathWatchSpec.scala +++ b/akka-remote-tests/src/multi-jvm/scala/akka/remote/RemoteNodeDeathWatchSpec.scala @@ -28,7 +28,9 @@ object RemoteNodeDeathWatchMultiJvmSpec extends MultiNodeConfig { ConfigFactory.parseString(""" akka.loglevel = INFO akka.remote.log-remote-lifecycle-events = off - """))) + ## Use a tighter setting than the default, otherwise it takes 20s for DeathWatch to trigger + akka.remote.watch-failure-detector.acceptable-heartbeat-pause = 3 s + """))) case class WatchIt(watchee: ActorRef) case class UnwatchIt(watchee: ActorRef) diff --git a/akka-remote-tests/src/multi-jvm/scala/akka/remote/RemoteNodeRestartDeathWatchSpec.scala b/akka-remote-tests/src/multi-jvm/scala/akka/remote/RemoteNodeRestartDeathWatchSpec.scala index d1fddef7b5..8c54a62cfb 100644 --- a/akka-remote-tests/src/multi-jvm/scala/akka/remote/RemoteNodeRestartDeathWatchSpec.scala +++ b/akka-remote-tests/src/multi-jvm/scala/akka/remote/RemoteNodeRestartDeathWatchSpec.scala @@ -30,7 +30,9 @@ object RemoteNodeRestartDeathWatchMultiJvmSpec extends MultiNodeConfig { ConfigFactory.parseString(""" akka.loglevel = INFO akka.remote.log-remote-lifecycle-events = off - """))) + akka.remote.transport-failure-detector.heartbeat-interval = 1 s + akka.remote.transport-failure-detector.acceptable-heartbeat-pause = 3 s + """))) testTransport(on = true) diff --git a/akka-remote-tests/src/multi-jvm/scala/akka/remote/RemoteNodeShutdownAndComesBackSpec.scala b/akka-remote-tests/src/multi-jvm/scala/akka/remote/RemoteNodeShutdownAndComesBackSpec.scala index e12782101d..a368dbd5a3 100644 --- a/akka-remote-tests/src/multi-jvm/scala/akka/remote/RemoteNodeShutdownAndComesBackSpec.scala +++ b/akka-remote-tests/src/multi-jvm/scala/akka/remote/RemoteNodeShutdownAndComesBackSpec.scala @@ -26,7 +26,9 @@ object RemoteNodeShutdownAndComesBackSpec extends MultiNodeConfig { ConfigFactory.parseString(""" akka.loglevel = INFO akka.remote.log-remote-lifecycle-events = INFO - #akka.remote.retry-gate-closed-for = 0.5 s + ## Keep it tight, otherwise reestablishing a connection takes too much time + akka.remote.transport-failure-detector.heartbeat-interval = 1 s + akka.remote.transport-failure-detector.acceptable-heartbeat-pause = 3 s akka.remote.watch-failure-detector.acceptable-heartbeat-pause = 60 s akka.remote.gate-invalid-addresses-for = 0.5 s """))) @@ -87,13 +89,9 @@ abstract class RemoteNodeShutdownAndComesBackSpec // Trigger reconnect attempt and also queue up a system message to be in limbo state (UID of remote system // is unknown, and system message is pending) system.stop(subject) - subject ! "hello" - subject ! "hello" - subject ! "hello" // Get rid of old system -- now SHUTDOWN is lost testConductor.shutdown(second).await - expectTerminated(subject, 10.seconds) // At this point the second node is restarting, while the first node is trying to reconnect without resetting // the system message send state @@ -102,8 +100,10 @@ abstract class RemoteNodeShutdownAndComesBackSpec within(30.seconds) { // retry because the Subject actor might not be started yet awaitAssert { - system.actorSelection(RootActorPath(secondAddress) / "user" / "subject") ! "echo" - expectMsg(1.second, "echo") + system.actorSelection(RootActorPath(secondAddress) / "user" / "subject") ! Identify("subject") + expectMsgPF(1 second) { + case ActorIdentity("subject", Some(ref)) ⇒ true + } } } @@ -115,7 +115,10 @@ abstract class RemoteNodeShutdownAndComesBackSpec watch(subjectNew) subjectNew ! "shutdown" - expectTerminated(subjectNew) + fishForMessage(5.seconds) { + case _: ActorIdentity ⇒ false + case Terminated(subjectNew) ⇒ true + } } runOn(second) { diff --git a/akka-remote/src/main/resources/reference.conf b/akka-remote/src/main/resources/reference.conf index fdea9fb36f..5a078fef86 100644 --- a/akka-remote/src/main/resources/reference.conf +++ b/akka-remote/src/main/resources/reference.conf @@ -90,7 +90,7 @@ akka { # that since remoting can load arbitrary 3rd party drivers (see # "enabled-transport" and "adapters" entries) it is not guaranteed that # every module will respect this setting. - use-dispatcher = "" + use-dispatcher = "akka.remote.default-remote-dispatcher" ### Security settings @@ -157,7 +157,7 @@ akka { implementation-class = "akka.remote.PhiAccrualFailureDetector" # How often keep-alive heartbeat messages should be sent to each connection. - heartbeat-interval = 1 s + heartbeat-interval = 4 s # Defines the failure detector threshold. # A low threshold is prone to generate many wrong suspicions but ensures @@ -181,7 +181,7 @@ akka { # This margin is important to be able to survive sudden, occasional, # pauses in heartbeat arrivals, due to for example garbage collect or # network drop. - acceptable-heartbeat-pause = 3 s + acceptable-heartbeat-pause = 10 s } # Settings for the Phi accrual failure detector (http://ddg.jaist.ac.jp/pub/HDY+04.pdf @@ -219,7 +219,7 @@ akka { # This margin is important to be able to survive sudden, occasional, # pauses in heartbeat arrivals, due to for example garbage collect or # network drop. - acceptable-heartbeat-pause = 4 s + acceptable-heartbeat-pause = 10 s # How often to check for nodes marked as unreachable by the failure @@ -237,35 +237,20 @@ akka { # address as failed. This configuration option controls how much time should # be elapsed before reattempting a new connection. While the address is # gated, all messages sent to the address are delivered to dead-letters. - # If this setting is 0, the remoting will always immediately reattempt - # to establish a failed outbound connection and will buffer writes until - # it succeeds. - retry-gate-closed-for = 0 s + # Since this setting limits the rate of reconnects setting it to a + # very short interval (i.e. less than a second) may result in a storm of + # reconnect attempts. + retry-gate-closed-for = 5 s - # If the retry gate function is disabled (see retry-gate-closed-for) the - # remoting subsystem will always attempt to reestablish failed outbound - # connections. The settings below together control the maximum number of - # reattempts in a given time window. The number of reattempts during - # a window of "retry-window" will be maximum "maximum-retries-in-window". - retry-window = 60 s - maximum-retries-in-window = 3 - - # The length of time to gate an address whose name lookup has failed - # or has explicitly signalled that it will not accept connections - # (remote system is shutting down or the requesting system is quarantined). - # No connection attempts will be made to an address while it remains - # gated. Any messages sent to a gated address will be directed to dead - # letters instead. Name lookups are costly, and the time to recovery - # is typically large, therefore this setting should be a value in the - # order of seconds or minutes. - gate-invalid-addresses-for = 60 s - - # This settings controls how long a system will be quarantined after - # catastrophic communication failures that result in the loss of system - # messages. Quarantining prevents communication with the remote system - # of a given UID. This function can be disabled by setting the value - # to "off". - quarantine-systems-for = 60s + # After catastrophic communication failures that result in the loss of system + # messages or after the remote DeathWatch triggers the remote system gets + # quarantined to prevent inconsistent behavior. + # This setting controls how long the Quarantine marker will be kept around + # before being removed to avoid long-term memory leaks. + # WARNING: DO NOT change this to a small value to re-enable communication with + # quarantined nodes. Such feature is not supported and any behavior between + # the affected systems after lifting the quarantine is undefined. + prune-quarantine-marker-after = 5 d # This setting defines the maximum number of unacknowledged system messages # allowed for a remote system. If this limit is reached the remote system is @@ -280,11 +265,12 @@ akka { # an individual ack. system-message-ack-piggyback-timeout = 0.3 s - # This setting defines the time after messages that have not been + # This setting defines the time after internal management signals + # between actors (used for DeathWatch and supervision) that have not been # explicitly acknowledged or negatively acknowledged are resent. # Messages that were negatively acknowledged are always immediately # resent. - resend-interval = 1 s + resend-interval = 2 s ### Transports and adapters @@ -488,6 +474,19 @@ akka { debug = off } + ### Default dispatcher for the remoting subsystem + + default-remote-dispatcher { + type = Dispatcher + executor = "fork-join-executor" + fork-join-executor { + # Min number of threads to cap factor-based parallelism number to + parallelism-min = 2 + parallelism-max = 2 + } + } + + } } diff --git a/akka-remote/src/main/scala/akka/remote/Endpoint.scala b/akka-remote/src/main/scala/akka/remote/Endpoint.scala index 013a9c84b0..2d105154dc 100644 --- a/akka-remote/src/main/scala/akka/remote/Endpoint.scala +++ b/akka-remote/src/main/scala/akka/remote/Endpoint.scala @@ -187,12 +187,10 @@ private[remote] class ReliableDeliverySupervisor( val transport: AkkaProtocolTransport, val settings: RemoteSettings, val codec: AkkaPduCodec, - val receiveBuffers: ConcurrentHashMap[Link, ResendState]) extends Actor { + val receiveBuffers: ConcurrentHashMap[Link, ResendState]) extends Actor with ActorLogging { import ReliableDeliverySupervisor._ import context.dispatcher - def retryGateEnabled = settings.RetryGateClosedFor > Duration.Zero - var autoResendTimer: Option[Cancellable] = None def scheduleAutoResend(): Unit = if (resendBuffer.nacked.nonEmpty || resendBuffer.nonAcked.nonEmpty) { @@ -206,20 +204,18 @@ private[remote] class ReliableDeliverySupervisor( scheduleAutoResend() } - override val supervisorStrategy = OneForOneStrategy(settings.MaximumRetriesInWindow, settings.RetryWindow, loggingEnabled = false) { + override val supervisorStrategy = OneForOneStrategy(loggingEnabled = false) { case e @ (_: AssociationProblem) ⇒ Escalate case NonFatal(e) ⇒ + log.warning("Association with remote system [{}] has failed, address is now gated for [{}] ms. Reason is: [{}].", + remoteAddress, settings.RetryGateClosedFor.toMillis, e.getMessage) uidConfirmed = false // Need confirmation of UID again - if (retryGateEnabled) { - context.become(gated) - context.system.scheduler.scheduleOnce(settings.RetryGateClosedFor, self, Ungate) - context.unwatch(writer) - currentHandle = None - context.parent ! StoppedReading(self) - Stop - } else { - Restart - } + context.become(gated) + context.system.scheduler.scheduleOnce(settings.RetryGateClosedFor, self, Ungate) + context.unwatch(writer) + currentHandle = None + context.parent ! StoppedReading(self) + Stop } var currentHandle: Option[AkkaProtocolHandle] = handleOrActive diff --git a/akka-remote/src/main/scala/akka/remote/RemoteSettings.scala b/akka-remote/src/main/scala/akka/remote/RemoteSettings.scala index 4035423980..b447353aa1 100644 --- a/akka-remote/src/main/scala/akka/remote/RemoteSettings.scala +++ b/akka-remote/src/main/scala/akka/remote/RemoteSettings.scala @@ -60,20 +60,8 @@ final class RemoteSettings(val config: Config) { config.getMillisDuration("akka.remote.retry-gate-closed-for") } requiring (_ >= Duration.Zero, "retry-gate-closed-for must be >= 0") - val UnknownAddressGateClosedFor: FiniteDuration = { - config.getMillisDuration("akka.remote.gate-invalid-addresses-for") - } requiring (_ > Duration.Zero, "gate-invalid-addresses-for must be > 0") - val UsePassiveConnections: Boolean = getBoolean("akka.remote.use-passive-connections") - val MaximumRetriesInWindow: Int = { - getInt("akka.remote.maximum-retries-in-window") - } requiring (_ > 0, "maximum-retries-in-window must be > 0") - - val RetryWindow: FiniteDuration = { - config.getMillisDuration("akka.remote.retry-window") - } requiring (_ > Duration.Zero, "retry-window must be > 0") - val BackoffPeriod: FiniteDuration = { config.getMillisDuration("akka.remote.backoff-interval") } requiring (_ > Duration.Zero, "backoff-interval must be > 0") @@ -90,10 +78,9 @@ final class RemoteSettings(val config: Config) { getInt("akka.remote.system-message-buffer-size") } requiring (_ > 0, "system-message-buffer-size must be > 0") - val QuarantineDuration: Duration = { - if (getString("akka.remote.quarantine-systems-for") == "off") Duration.Undefined - else config.getMillisDuration("akka.remote.quarantine-systems-for").requiring(_ > Duration.Zero, - "quarantine-systems-for must be > 0 or off") + val QuarantineDuration: FiniteDuration = { + Duration(getMilliseconds("akka.remote.prune-quarantine-marker-after"), MILLISECONDS).requiring(_ > Duration.Zero, + "prune-quarantine-marker-after must be > 0 ms") } val CommandAckTimeout: Timeout = { diff --git a/akka-remote/src/main/scala/akka/remote/Remoting.scala b/akka-remote/src/main/scala/akka/remote/Remoting.scala index 89ec8b6380..2370155743 100644 --- a/akka-remote/src/main/scala/akka/remote/Remoting.scala +++ b/akka-remote/src/main/scala/akka/remote/Remoting.scala @@ -395,16 +395,16 @@ private[remote] class EndpointManager(conf: Config, log: LoggingAdapter) extends case e @ InvalidAssociation(localAddress, remoteAddress, reason) ⇒ log.warning("Tried to associate with unreachable remote address [{}]. " + "Address is now gated for {} ms, all messages to this address will be delivered to dead letters. Reason: {}", - remoteAddress, settings.UnknownAddressGateClosedFor.toMillis, reason.getMessage) - endpoints.markAsFailed(sender, Deadline.now + settings.UnknownAddressGateClosedFor) + remoteAddress, settings.RetryGateClosedFor.toMillis, reason.getMessage) + endpoints.markAsFailed(sender, Deadline.now + settings.RetryGateClosedFor) context.system.eventStream.publish(AddressTerminated(remoteAddress)) Stop case ShutDownAssociation(localAddress, remoteAddress, _) ⇒ log.debug("Remote system with address [{}] has shut down. " + "Address is now gated for {} ms, all messages to this address will be delivered to dead letters.", - remoteAddress, settings.UnknownAddressGateClosedFor.toMillis) - endpoints.markAsFailed(sender, Deadline.now + settings.UnknownAddressGateClosedFor) + remoteAddress, settings.RetryGateClosedFor.toMillis) + endpoints.markAsFailed(sender, Deadline.now + settings.RetryGateClosedFor) context.system.eventStream.publish(AddressTerminated(remoteAddress)) Stop @@ -419,13 +419,10 @@ private[remote] class EndpointManager(conf: Config, log: LoggingAdapter) extends Stop case HopelessAssociation(localAddress, remoteAddress, None, _) ⇒ - settings.QuarantineDuration match { - case d: FiniteDuration ⇒ - log.warning("Association to [{}] with unknown UID is irrecoverably failed. " + - "Address is now quarantined, all messages to this address will be delivered to dead letters.", remoteAddress) - endpoints.markAsFailed(sender, Deadline.now + d) - case _ ⇒ - } + log.warning("Association to [{}] with unknown UID is irrecoverably failed. " + + "Address cannot be quarantined without knowing the UID, gating instead for {} ms.", + remoteAddress, settings.RetryGateClosedFor.toMillis) + endpoints.markAsFailed(sender, Deadline.now + settings.RetryGateClosedFor) context.system.eventStream.publish(AddressTerminated(remoteAddress)) Stop @@ -482,22 +479,18 @@ private[remote] class EndpointManager(conf: Config, log: LoggingAdapter) extends Future.fold(allStatuses)(true)(_ && _) map ManagementCommandAck pipeTo sender case Quarantine(address, uid) ⇒ - settings.QuarantineDuration match { - case d: FiniteDuration ⇒ - // Stop writers - endpoints.writableEndpointWithPolicyFor(address) match { - case Some(Pass(endpoint)) ⇒ context.stop(endpoint) - case _ ⇒ // nothing to stop - } - // Stop inbound read-only associations - endpoints.readOnlyEndpointFor(address) match { - case Some(endpoint) ⇒ context.stop(endpoint) - case _ ⇒ // nothing to stop - } - endpoints.markAsQuarantined(address, uid, Deadline.now + d) - eventPublisher.notifyListeners(QuarantinedEvent(address, uid)) - case _ ⇒ // Ignore + // Stop writers + endpoints.writableEndpointWithPolicyFor(address) match { + case Some(Pass(endpoint)) ⇒ context.stop(endpoint) + case _ ⇒ // nothing to stop } + // Stop inbound read-only associations + endpoints.readOnlyEndpointFor(address) match { + case Some(endpoint) ⇒ context.stop(endpoint) + case _ ⇒ // nothing to stop + } + endpoints.markAsQuarantined(address, uid, Deadline.now + settings.QuarantineDuration) + eventPublisher.notifyListeners(QuarantinedEvent(address, uid)) case s @ Send(message, senderOption, recipientRef, _) ⇒ val recipientAddress = recipientRef.path.address diff --git a/akka-remote/src/main/scala/akka/remote/transport/ThrottlerTransportAdapter.scala b/akka-remote/src/main/scala/akka/remote/transport/ThrottlerTransportAdapter.scala index 4f54ee05dc..29b7439d63 100644 --- a/akka-remote/src/main/scala/akka/remote/transport/ThrottlerTransportAdapter.scala +++ b/akka-remote/src/main/scala/akka/remote/transport/ThrottlerTransportAdapter.scala @@ -453,8 +453,6 @@ private[transport] class ThrottledAssociation( sender ! SetThrottleAck stay() case Event(Disassociated(info), _) ⇒ - if (upstreamListener ne null) upstreamListener notify Disassociated(info) - originalHandle.disassociate() stop() } diff --git a/akka-remote/src/main/scala/akka/remote/transport/netty/NettyTransport.scala b/akka-remote/src/main/scala/akka/remote/transport/netty/NettyTransport.scala index e7ce152b57..7cb9359b7f 100644 --- a/akka-remote/src/main/scala/akka/remote/transport/netty/NettyTransport.scala +++ b/akka-remote/src/main/scala/akka/remote/transport/netty/NettyTransport.scala @@ -380,7 +380,7 @@ class NettyTransport(val settings: NettyTransportSettings, val system: ExtendedA // TODO: This should be factored out to an async (or thread-isolated) name lookup service #2960 def addressToSocketAddress(addr: Address): Future[InetSocketAddress] = addr match { - case Address(_, _, Some(host), Some(port)) ⇒ Future { new InetSocketAddress(InetAddress.getByName(host), port) } + case Address(_, _, Some(host), Some(port)) ⇒ Future { blocking { new InetSocketAddress(InetAddress.getByName(host), port) } } case _ ⇒ Future.failed(new IllegalArgumentException(s"Address [$addr] does not contain host or port information.")) } diff --git a/akka-remote/src/test/scala/akka/remote/RemoteConfigSpec.scala b/akka-remote/src/test/scala/akka/remote/RemoteConfigSpec.scala index deae34743d..076208af95 100644 --- a/akka-remote/src/test/scala/akka/remote/RemoteConfigSpec.scala +++ b/akka-remote/src/test/scala/akka/remote/RemoteConfigSpec.scala @@ -19,7 +19,7 @@ class RemoteConfigSpec extends AkkaSpec( akka.remote.netty.tcp.port = 0 """) { - "Remoting" must { + "Remoting" should { "contain correct configuration values in reference.conf" in { val remoteSettings = RARP(system).provider.remoteSettings @@ -33,17 +33,14 @@ class RemoteConfigSpec extends AkkaSpec( ShutdownTimeout.duration should be(10 seconds) FlushWait should be(2 seconds) StartupTimeout.duration should be(10 seconds) - RetryGateClosedFor should be(Duration.Zero) - UnknownAddressGateClosedFor should be(1 minute) - Dispatcher should equal("") + RetryGateClosedFor should be(5 seconds) + Dispatcher should equal("akka.remote.default-remote-dispatcher") UsePassiveConnections should be(true) - MaximumRetriesInWindow should be(3) - RetryWindow should be(60 seconds) BackoffPeriod should be(10 millis) SysMsgAckTimeout should be(0.3 seconds) - SysResendTimeout should be(1 seconds) + SysResendTimeout should be(2 seconds) SysMsgBufferSize should be(1000) - QuarantineDuration should be(60 seconds) + QuarantineDuration should be(5 days) CommandAckTimeout.duration should be(30 seconds) Transports.size should be(1) Transports.head._1 should be(classOf[akka.remote.transport.netty.NettyTransport].getName) @@ -58,7 +55,7 @@ class RemoteConfigSpec extends AkkaSpec( WatchUnreachableReaperInterval should be(1 second) WatchFailureDetectorConfig.getDouble("threshold") should be(10.0 +- 0.0001) WatchFailureDetectorConfig.getInt("max-sample-size") should be(200) - WatchFailureDetectorConfig.getMillisDuration("acceptable-heartbeat-pause") should be(4 seconds) + WatchFailureDetectorConfig.getMillisDuration("acceptable-heartbeat-pause") should be(10 seconds) WatchFailureDetectorConfig.getMillisDuration("min-std-deviation") should be(100 millis) remoteSettings.config.getString("akka.remote.log-frame-size-exceeding") should be("off") @@ -72,10 +69,10 @@ class RemoteConfigSpec extends AkkaSpec( SecureCookie should equal(None) TransportFailureDetectorImplementationClass should be(classOf[PhiAccrualFailureDetector].getName) - TransportHeartBeatInterval should equal(1.seconds) + TransportHeartBeatInterval should equal(4.seconds) TransportFailureDetectorConfig.getDouble("threshold") should be(7.0 +- 0.0001) TransportFailureDetectorConfig.getInt("max-sample-size") should be(100) - TransportFailureDetectorConfig.getMillisDuration("acceptable-heartbeat-pause") should be(3 seconds) + TransportFailureDetectorConfig.getMillisDuration("acceptable-heartbeat-pause") should be(10 seconds) TransportFailureDetectorConfig.getMillisDuration("min-std-deviation") should be(100 millis) } diff --git a/akka-remote/src/test/scala/akka/remote/transport/AkkaProtocolStressTest.scala b/akka-remote/src/test/scala/akka/remote/transport/AkkaProtocolStressTest.scala index 024f8f83d5..c8ecd7e6a7 100644 --- a/akka-remote/src/test/scala/akka/remote/transport/AkkaProtocolStressTest.scala +++ b/akka-remote/src/test/scala/akka/remote/transport/AkkaProtocolStressTest.scala @@ -14,6 +14,7 @@ object AkkaProtocolStressTest { val configA: Config = ConfigFactory parseString (""" akka { #loglevel = DEBUG + actor.serialize-messages = off actor.provider = "akka.remote.RemoteActorRefProvider" remote.log-remote-lifecycle-events = on @@ -22,13 +23,12 @@ object AkkaProtocolStressTest { threshold = 1.0 max-sample-size = 2 min-std-deviation = 1 ms - acceptable-heartbeat-pause = 0.01 s + ## We want lots of lost connections in this test, keep it sensitive + heartbeat-interval = 1 s + acceptable-heartbeat-pause = 1 s } - remote.retry-window = 1 s - # This test drops messages, but dropping too much will make it fail. The reason is that this test - # expects at least a few of the final messages to arrive to prove that the Remoting does not get stuck - # in an irrecoverable state. The retry limit enabled case is covered by the SystemMessageDelivery tests. - remote.maximum-retries-in-window = 100 + ## Keep gate duration in this test for a reasonably low value otherwise too much messages are dropped + remote.retry-gate-closed-for = 1 s remote.netty.tcp { applied-adapters = ["gremlin"] @@ -38,6 +38,8 @@ object AkkaProtocolStressTest { } """) + object ResendFinal + class SequenceVerifier(remote: ActorRef, controller: ActorRef) extends Actor { import context.dispatcher @@ -58,13 +60,25 @@ object AkkaProtocolStressTest { if (seq > maxSeq) { losses += seq - maxSeq - 1 maxSeq = seq - if (seq > limit * 0.9) { + // Due to the (bursty) lossyness of gate, we are happy with receiving at least one message from the upper + // half (> 50000). Since messages are sent in bursts of 2000 0.5 seconds apart, this is reasonable. + // The purpose of this test is not reliable delivery (there is a gremlin with 30% loss anyway) but respecting + // the proper ordering. + if (seq > limit * 0.5) { controller ! ((maxSeq, losses)) + context.system.scheduler.schedule(1.second, 1.second, self, ResendFinal) + context.become(done) } } else { controller ! s"Received out of order message. Previous: ${maxSeq} Received: ${seq}" } } + + // Make sure the other side eventually "gets the message" + def done: Receive = { + case ResendFinal ⇒ + controller ! ((maxSeq, losses)) + } } } diff --git a/akka-remote/src/test/scala/akka/remote/transport/SystemMessageDeliveryStressTest.scala b/akka-remote/src/test/scala/akka/remote/transport/SystemMessageDeliveryStressTest.scala index a245d3ccd9..1043ff4c5b 100644 --- a/akka-remote/src/test/scala/akka/remote/transport/SystemMessageDeliveryStressTest.scala +++ b/akka-remote/src/test/scala/akka/remote/transport/SystemMessageDeliveryStressTest.scala @@ -36,17 +36,19 @@ object SystemMessageDeliveryStressTest { akka { #loglevel = DEBUG actor.provider = "akka.remote.RemoteActorRefProvider" + actor.serialize-messages = off remote.log-remote-lifecycle-events = on - remote.failure-detector { + remote.transport-failure-detector { threshold = 1.0 max-sample-size = 2 min-std-deviation = 1 ms - acceptable-heartbeat-pause = 0.01 s + heartbeat-interval = 500 ms + acceptable-heartbeat-pause = 2 s } - remote.retry-window = 1 s - remote.maximum-retries-in-window = 2 + ## Keep this setting tight, otherwise the test takes a long time or times out + remote.resend-interval = 0.5 s remote.use-passive-connections = on remote.netty.tcp { @@ -142,12 +144,9 @@ abstract class SystemMessageDeliveryStressTest(msg: String, cfg: String) } -class SystemMessageDeliveryDefault extends SystemMessageDeliveryStressTest("retry gate off, passive connections on", "") -class SystemMessageDeliveryRetryGate extends SystemMessageDeliveryStressTest("retry gate on, passive connections on", +class SystemMessageDeliveryRetryGate extends SystemMessageDeliveryStressTest("passive connections on", "akka.remote.retry-gate-closed-for = 0.5 s") -class SystemMessageDeliveryNoPassive extends SystemMessageDeliveryStressTest("retry gate off, passive connections off", - "akka.remote.use-passive-connections = off") -class SystemMessageDeliveryNoPassiveRetryGate extends SystemMessageDeliveryStressTest("retry gate on, passive connections off", +class SystemMessageDeliveryNoPassiveRetryGate extends SystemMessageDeliveryStressTest("passive connections off", """ akka.remote.use-passive-connections = off akka.remote.retry-gate-closed-for = 0.5 s diff --git a/akka-remote/src/test/scala/akka/remote/transport/ThrottlerTransportAdapterSpec.scala b/akka-remote/src/test/scala/akka/remote/transport/ThrottlerTransportAdapterSpec.scala index 7b88de25a2..2716fbcb17 100644 --- a/akka-remote/src/test/scala/akka/remote/transport/ThrottlerTransportAdapterSpec.scala +++ b/akka-remote/src/test/scala/akka/remote/transport/ThrottlerTransportAdapterSpec.scala @@ -19,6 +19,9 @@ object ThrottlerTransportAdapterSpec { remote.netty.tcp.hostname = "localhost" remote.log-remote-lifecycle-events = off + remote.retry-gate-closed-for = 1 s + remote.transport-failure-detector.heartbeat-interval = 1 s + remote.transport-failure-detector.acceptable-heartbeat-pause = 3 s remote.netty.tcp.applied-adapters = ["trttl"] remote.netty.tcp.port = 0 @@ -115,7 +118,7 @@ class ThrottlerTransportAdapterSpec extends AkkaSpec(configA) with ImplicitSende here ! "Blackhole 3" false } - }, 5.seconds) + }, 15.seconds) here ! "Cleanup" fishForMessage(5.seconds) {