带有Docker容器的Akka集群

本文将向您展示如何构建包含单个akka集群应用程序的docker映像。 您将能够运行多个种子节点和多个群集节点。 可以在Github上找到该代码,并将其作为Typesafe Activator使用

如果您不知道docker或akka

Docker是devops世界中的一颗崭新的闪亮星。 它使您可以轻松地将映像部署到运行docker的任何操作系统,同时为容器映像内运行的应用程序提供隔离的环境。

Akka是构建并发,弹性,分布式和可伸缩软件系统的框架。 群集功能使您可以将Actor分布在多台计算机上,以实现负载平衡,故障转移以及横向扩展和横向扩展的能力。

大图景

这就是正在运行的应用程序的外观。 无论您的Docker容器在一天结束时将在何处运行。 左上方的数字描述了容器的开始顺序。

akka-docker-bigpicture

首先,您必须启动种子节点,它将种子“粘合”在一起。 在第一个节点启动之后,所有随后的种子节点都必须知道初始种子节点的ip地址,以建立单个群集。 本文中介绍的方法非常简单,但易于配置,因此您可以将其与其他调配技术(例如厨师,木偶或动物园管理员)一起使用。

接下来的所有开始节点都需要至少一个seed-node-ip才能加入集群。

应用程序配置

我们将部署一个小的akka​​应用程序,该应用程序仅记录集群事件。 入口点非常简单:

object Main extends App {
 
  val nodeConfig = NodeConfig parse args
 
  // If a config could be parsed - start the system
  nodeConfig map { c =>
    val system = ActorSystem(c.clusterName, c.config)
 
    // Register a monitor actor for demo purposes
    system.actorOf(Props[MonitorActor], "cluster-monitor")
 
    system.log info s"ActorSystem ${system.name} started successfully"
  }
 
}

棘手的部分是配置。 首先,需要将akka.remote.netty.tcp.hostname配置设置为docker ip地址。 端口配置并不重要,这要归功于docker,我们拥有唯一的IP地址。 您可以在此处阅读有关Docker网络的更多信息。 其次,种子节点应将自己添加到akka.cluster.seed-nodes列表中。 最后,一切都应该通过系统属性和环境变量进行配置。 多亏了Typesafe Config库,这是可以实现的(即使有些出汗)。

  1. 使用scopt和以下两个参数生成一个小的命令行解析器:
    –seed标志,该标志确定此节点开始时是否应充当种子节点
    ([IP]:[端口])...[IP]无界列表:[端口],它代表了种子节点
  2. 将配置分为三个文件
    1. 包含常用配置的application.conf
    2. node.cluster.conf仅包含特定于节点的配置
    3. node.seed.conf仅包含特定于种子节点的配置
  3. 一个NodeConfig类,它以正确的顺序编排所有设置和cli参数,并构建Typesafe Config对象。

仔细看看NodeConfig类。 核心部分是这样的:

// seed nodes as generated string from cli
(ConfigFactory parseString seedNodesString)
  // the hostname
  .withValue("clustering.ip", ipValue)
  // node.cluster.conf or node.seed.conf
  .withFallback(ConfigFactory parseResources configPath) 
  // default ConfigFactory.load but unresolved
  .withFallback(config)
  // try to resolve all placeholders (clustering.ip and clustering.port)
  .resolve

解析IP地址的部分有点棘手,但应该可以在默认docker环境中使用。 首先搜索eth0接口,然后返回第一个isSiteLocalAddress 。 以下范围内的IP地址是本地的172.16.xxx.xxx,172.31.xxx.xxx,192.168.xxx.xxx,10.xxx.xxx.xxx。

主要集群配置在application.confclustering部分内完成:

clustering {
  # ip = "127.0.0.1" # will be set from the outside or automatically
  port = 2551
  cluster.name = "application"
}

如果没有其他设置,ip地址将由上述算法填充。 您可以使用系统属性轻松覆盖所有设置。 例如,如果要在不使用docker的情况下在IDE中运行种子节点和群集节点,请像下面这样启动两者:

# the seed node
-Dclustering.port=2551 -Dclustering.ip=127.0.0.1 --seed
# the cluster node
-Dclustering.port=2552 -Dclustering.ip=127.0.0.1 127.0.0.1:2551

对于sbt,它看起来像这样:

# the seed node
sbt runSeed
# the cluster node
sbt runNode

构建

接下来,我们构建泊坞窗映像。 sbt-native-packager插件最近添加了实验性docker 支持 ,因此我们只需要将构建配置为docker-ready。 首先将插件添加到您的plugins.sbt中

addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "0.7.4")

现在,我们向build.sbt添加一些必需的设置。 您应该使用sbt 0.13.5或更高版本。

// adds start script and jar mappings
packageArchetype.java_application
 
// the docker maintainer. You could scope this to "in Docker"
maintainer := "Nepomuk Seiler"
 
// Short package description
packageSummary := s"Akka ${version.value} Server"

现在我们开始了。 启动sbt并运行docker :publishLocal ,将为您创建一个docker映像。 如果您想仔细查看创建的内容,Dockerfile位于target / docker中。

运行集群

现在是时候运行我们的容器了。 图像名称默认为name:version 。 对于我们的激活器,它是akka-docker:2.3.4 。 种子IP地址可能会有所不同。 您可以从种子节点的控制台输出中读取它。

docker run -i -t -p 2551:2551 akka-docker:2.3.4 --seed
docker run -i -t -p 2551:2551 akka-docker:2.3.4 --seed 176.16.0.18:2551
docker run -i -t -p 2551:2551 akka-docker:2.3.4 176.16.0.18:2551 176.16.0.19:2551
docker run -i -t -p 2551:2551 akka-docker:2.3.4 176.16.0.18:2551 176.16.0.19:2551

链接呢?

博客条目描述了使用docker构建akka集群的另一种方法。 我使用了一些想法,但是基本概念是建立在链接docker包含的基础之上。 这使您可以获得正在运行的种子节点的ip和端口信息。 虽然这种方法适用于单台主机,但在多台Docker机器上使用时似乎变得更加混乱

本博客中的设置仅需一件事:分配主机ip的集中方式。 如果您的种子节点不更改其IP地址,则可以基本上配置application.conf中已经存在的几乎所有内容。

翻译自: https://www.javacodegeeks.com/2014/08/akka-cluster-with-docker-containers.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值