文档结构  
翻译进度:已翻译     翻译赏金:0 元 (?)    ¥ 我要打赏

对于可能读过我的上一篇关于Docker + NATS for Microservices的文章的读者,你可能会想起我们深入研究了利用NATS使用Docker Compose的方法。

那篇博文在DockerCon之前的几天完成,正如预期,Docker在DockerCon上发布了很多有意思的消息。在那一周宣布的主要事情之一是Docker 1.12。

1.12包括了 Swarm模式,能够用于组装一个Docker引擎集群,并在其上运行载荷。

在这篇博客中,我们分享一个例子,介绍如何使用Docker 1.12中的一些新特性来搭建一个NATS集群,以供我们的运行的客户进行连接。

第 1 段(可获 1.53 积分)

需求

  • Docker Engine 1.12
  • Docker Swarm 集群中至少一个管理节点和一对工作节点可用 https://docs.docker.com/engine/swarm/
  • 最新版本的NASTS server, 它支持客户端的集群自动发现。 这样,如果我们添加更多的节点到群集,客户端会动态地知道完整的拓扑结构。很棒的应用!

步骤 1

我们首先需要给集群创建一个覆盖网络, 这里命名为 nats-cluster-example, 随即用最新的Docker初始化一个NATS server:

docker network create --driver overlay nats-cluster-example
docker service create --network nats-cluster-example \
                             --name nats-cluster-node-1 nats:0.9.4 -DV

 

 

第 2 段(可获 1.04 积分)

步骤 2

接下来,我们确定一下NATS服务跑在了Docker Swarm中的哪一个节点上,并确认其IP:

  docker service ps nats-cluster-node-1
  ID                         NAME                   IMAGE       NODE    DESIRED STATE  CURRENT STATE           ERROR
  b81qv4ljs7g7b52vmnlojktug  nats-cluster-node-1.1  nats:0.9.4  node-2  Running        Running 32 seconds ago

  docker network inspect nats-cluster-example
  [
      {
          "Name": "nats-cluster-example",
          "Id": "944z42rg2hjwgsv9xubmomvi5",
          "Scope": "swarm",
          "Driver": "overlay",
          "EnableIPv6": false,
          "IPAM": {
              "Driver": "default",
              "Options": null,
              "Config": [
                  {
                      "Subnet": "10.0.1.0/24",
                      "Gateway": "10.0.1.1"
                  }
              ]
          },
          "Internal": false,
          "Containers": {
              "e0d105ed7703aa5de939861f75087671c96128fbe799bf6ba38cd15c55aaef07": {
                  "Name": "nats-cluster-node-1.1.0j0wde7hbqn735eqgpslkxowf",
                  "EndpointID": "e798782eaac9bbd36decf3c6e5defd56faa88a3c7a09df608ffd1f2ce1969ed8",
                  "MacAddress": "02:42:0a:00:01:03",
                  "IPv4Address": "10.0.1.3/24",
                  "IPv6Address": ""
              }
          },
          "Options": {
              "com.docker.network.driver.overlay.vxlanid_list": "258"
          },
          "Labels": {}
      }
  ]

在Docker Swarm的node-2上,我们看到NATS服务已经跑起来了:

  docker logs e0b4d7b2f7f3
  [1] 2016/08/15 11:31:41.680139 [INF] Starting nats-server version 0.9.4
  [1] 2016/08/15 11:31:41.680217 [DBG] Go build version go1.6.3
  [1] 2016/08/15 11:31:41.680259 [INF] Starting http monitor on 0.0.0.0:8222
  [1] 2016/08/15 11:31:41.680348 [INF] Listening for client connections on 0.0.0.0:4222
  [1] 2016/08/15 11:31:41.680377 [DBG] Server id is JngwpOevXl1rhAovFO8Su6
  [1] 2016/08/15 11:31:41.680386 [INF] Server is ready
  [1] 2016/08/15 11:31:41.680731 [INF] Listening for route connections on 0.0.0.0:6222
 
第 3 段(可获 0.44 积分)

步骤 3

接下来,我们将创建另一个服务通过覆盖网络连接到该服务器;注意,我们有一个初始的IP连接到服务器:

docker service create --name ruby-nats --network nats-cluster-example wallyqs/ruby-nats:ruby-2.3.1-nats-v0.8.0 -e '
  NATS.on_error do |e|
    puts "ERROR: #{e}"
  end
  NATS.start(:servers => ["nats://10.0.1.3:4222"]) do |nc|
    inbox = NATS.create_inbox
    puts "[#{Time.now}] Connected to NATS at #{nc.connected_server}, inbox: #{inbox}"

    nc.subscribe(inbox) do |msg, reply|
      puts "[#{Time.now}] Received reply - #{msg}"
    end

    nc.subscribe("hello") do |msg, reply|
      next if reply == inbox
      puts "[#{Time.now}] Received greeting - #{msg} - #{reply}"
      nc.publish(reply, "world")
    end

    EM.add_periodic_timer(1) do
      puts "[#{Time.now}] Saying hi (servers in pool: #{nc.server_pool}"
      nc.publish("hello", "hi", inbox)
    end
  end
'
第 4 段(可获 0.36 积分)

步骤 4

现在我们通过更多的docker services命令可以来添加更多的节点到集群中:

docker service create --network nats-cluster-example \
			   --name nats-cluster-node-2 nats:0.9.4 -DV -cluster nats://0.0.0.0:6222 -routes nats://10.0.1.3:6222

添加多副本的描述如下:

docker service scale ruby-nats=3

然后在我们的Docker Swarm集群中确认一下分布情况:

docker service ps ruby-nats
ID                         NAME         IMAGE                                     NODE    DESIRED STATE  CURRENT STATE          ERROR
25skxso8honyhuznu15e4989m  ruby-nats.1  wallyqs/ruby-nats:ruby-2.3.1-nats-v0.8.0  node-1  Running        Running 2 minutes ago  
0017lut0u3wj153yvp0uxr8yo  ruby-nats.2  wallyqs/ruby-nats:ruby-2.3.1-nats-v0.8.0  node-1  Running        Running 2 minutes ago  
2sxl8rw6vm99x622efbdmkb96  ruby-nats.3  wallyqs/ruby-nats:ruby-2.3.1-nats-v0.8.0  node-2  Running        Running 2 minutes ago 

 

第 5 段(可获 0.39 积分)

在向集群中增加更多NATS服务器节点后的示例输入如下所示——请注意client已经通过自动发现动态感知到了更多节点加入到集群中!

[2016-08-15 12:51:52 +0000] Saying hi (servers in pool: [{:uri=>#<URI::Generic nats://10.0.1.3:4222>, :was_connected=>true, :reconnect_attempts=>0}]
[2016-08-15 12:51:53 +0000] Saying hi (servers in pool: [{:uri=>#<URI::Generic nats://10.0.1.3:4222>, :was_connected=>true, :reconnect_attempts=>0}]
[2016-08-15 12:51:54 +0000] Saying hi (servers in pool: [{:uri=>#<URI::Generic nats://10.0.1.3:4222>, :was_connected=>true, :reconnect_attempts=>0}]
[2016-08-15 12:51:55 +0000] Saying hi (servers in pool: [{:uri=>#<URI::Generic nats://10.0.1.3:4222>, :was_connected=>true, :reconnect_attempts=>0}, {:uri=>#<URI::Generic nats://10.0.1.7:4222>, :reconnect_attempts=>0}, {:uri=>#<URI::Generic nats://10.0.1.6:4222>, :reconnect_attempts=>0}]

在增加更多的可以应答的工作者后的示例输出(忽略了自身的回复):

[2016-08-15 16:06:26 +0000] Received reply - world
[2016-08-15 16:06:26 +0000] Received reply - world
[2016-08-15 16:06:27 +0000] Received greeting - hi - _INBOX.b8d8c01753d78e562e4dc561f1
[2016-08-15 16:06:27 +0000] Received greeting - hi - _INBOX.4c35d18701979f8c8ed7e5f6ea
第 6 段(可获 0.6 积分)

结论

Docker Engine内建的Docker Swarm 模式可以非常方便的部署分布式系统,该系统通过覆盖网络使用NATS进行内部组件的通讯,并且通过一个负载均衡器暴露给外部通讯。这项功能与最新NATS版本中的集群发现功能组合,使微服务工作变得轻而易举,并提供了非常好的灵活性和扩展性。

想参与NATS社区和了解更多吗?我们将很高兴收到你的来信,并回答你的任何问题!

第 7 段(可获 1.14 积分)

文章评论