加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

斯卡拉 – 阿卡单点失败

发布时间:2020-12-16 18:34:45 所属栏目:安全 来源:网络整理
导读:我想创建一个不会出现单点故障的系统. 我的印象是路由器是这样做的工具,但我不确定它是否像我期望的那样工作. 这是我的计划的切入点: object Main extends App{ val system = ActorSystem("mySys",ConfigFactory.load("application")) val router = system.
我想创建一个不会出现单点故障的系统.
我的印象是路由器是这样做的工具,但我不确定它是否像我期望的那样工作.
这是我的计划的切入点:

object Main extends App{
  val system = ActorSystem("mySys",ConfigFactory.load("application"))
  val router = system.actorOf(
    ClusterRouterPool(RoundRobinPool(0),ClusterRouterPoolSettings(
      totalInstances = 2,maxInstancesPerNode = 1,allowLocalRoutees = false,useRole = Some("testActor"))).props(Props[TestActor]),name = "testActors")
}

这是运行远程ActorSystem的代码(因此路由器可以将TestActor代码部署到远程节点):

object TestActor extends App{
  val system = ActorSystem("mySys",ConfigFactory.load("application").getConfig("testactor1"))
  case object PrintRouterPath
}

我运行了两次,一次使用testactor1,一次使用testactor2.

TestActor代码:

class TestActor extends Actor with ActorLogging{
  implicit val ExecutionContext = context.dispatcher
  context.system.scheduler.schedule(10000 milliseconds,30000 milliseconds,self,PrintRouterPath)

  override def receive: Receive = {
    case PrintRouterPath =>
     log.info(s"router is on path ${context.parent}")
  }
}

和application.conf

akka{
actor {
  provider = "akka.cluster.ClusterActorRefProvider"
}
remote {
  log-remote-lifecycle-events = off
  netty.tcp {
    hostname = "127.0.0.1"
    port = 2552
  }
}
cluster {
  seed-nodes = [
    "akka.tcp://mySys@127.0.0.1:2552"
    "akka.tcp://mySys@127.0.0.1:2553"
    "akka.tcp://mySys@127.0.0.1:2554"]
  auto-down-unreachable-after = 20s
  }
}
testactor1{
  akka{
    actor {
      provider = "akka.cluster.ClusterActorRefProvider"
    }
    remote {
      log-remote-lifecycle-events = off
      netty.tcp {
        hostname = "127.0.0.1"
        port = 2554
      }
    }
    cluster {
    roles.1 = "testActor"
      seed-nodes = [
        "akka.tcp://mySys@127.0.0.1:2552"
        "akka.tcp://mySys@127.0.0.1:2553"
        "akka.tcp://mySys@127.0.0.1:2554"]
      auto-down-unreachable-after = 20s
    }
  }
}
testactor2{
  akka{
    actor {
      provider = "akka.cluster.ClusterActorRefProvider"
    }
    remote {
      log-remote-lifecycle-events = off
      netty.tcp {
        hostname = "127.0.0.1"
        port = 2553
      }
    }
    cluster {
    roles.1 = "testActor"
      seed-nodes = [
        "akka.tcp://mySys@127.0.0.1:2552"
        "akka.tcp://mySys@127.0.0.1:2553"
        "akka.tcp://mySys@127.0.0.1:2554"]
      auto-down-unreachable-after = 20s
    }
  }
}

现在的问题是,当启动路由器的进程被终止时,运行TestActor代码的actor没有收到任何消息(调度程序发送的消息),我本以为路由器将被部署在群集中的另一个种子节点和actor将被恢复.这可能吗?或者是否有其他方法来实现此流程并且没有单点故障?

解决方法

我认为,通过仅在一个节点上部署路由器,您将设置主从集群,其中主服务器根据定义是单点故障.

根据我的理解(查看docs),路由器可以是集群感知的,因为它可以在集群中的节点上部署(池模式)或查找(组模式)路由.路由器本身不会通过在集群中的其他位置生成来对故障作出反应.

我相信你有两个选择:

>利用多个路由器使您的系统更具容错能力.路由器可以在路由器之间共享(组模式)或不共享(池模式).
>使用Cluster Singleton模式 – 允许主从配置,主机将在故障情况下自动重新生成.关于您的示例,请注意通过在每个节点中部署actor(ClusterSingletonManager)来实现此行为.这个演员的目的是确定所选的大师是否需要重生并在哪里.对于像您设置的群集感知路由器,这些逻辑都不适用.

您可以在此Activator sample中找到多个群集设置的示例.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读