Docker容器双向联通与高可用的Eureka Server

在《4.7 Eureka Server的高可用》中,我们构建了一个双节点的Eureka Server集群,本节我们使用Compose来编排这个Eureka Server集群。该双节点的Eureka配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
spring:
application:
name: microservice-discovery-eureka-ha
---
spring:
profiles: peer1 # 指定profile=peer1
server:
port: 8761
eureka:
instance:
hostname: peer1 # 指定当profile=peer1时,主机名是peer1
client:
serviceUrl:
defaultZone: http://peer2:8762/eureka/ # 将自己注册到peer2这个Eureka上面去
---
spring:
profiles: peer2
server:
port: 8762
eureka:
instance:
hostname: peer2
client:
serviceUrl:
defaultZone: http://peer1:8761/eureka/

以下是步骤:

(1) 执行mvn clean package docker:build 构建Docker镜像。

(2) 编写docker-compose.yml,如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
version: "2" # 表示使用docker-compose.yml的Version 2 file format编写
services:
microservice-discovery-eureka-ha1:
hostname: peer1 # 指定hostname
image: itmuch/microservice-discovery-eureka-ha:0.0.1-SNAPSHOT
links:
- microservice-discovery-eureka-ha2
ports:
- "8761:8761"
environment:
- spring.profiles.active=peer1
microservice-discovery-eureka-ha2:
hostname: peer2
image: itmuch/microservice-discovery-eureka-ha:0.0.1-SNAPSHOT
links:
- microservice-discovery-eureka-ha1
ports:
- "8762:8762"
environment:
- spring.profiles.active=peer2

从文件内容我们可以看到,我们定义了两个服务:microservice-discovery-eureka-ha1和microservice-discovery-eureka-ha2,它们的hostname分别是peer1和peer2。然后通过links标签相互连接。

(3) 执行

1
docker-compose up

命令启动。然而,控制台会输出类似以下的异常:

1
ERROR: Circular dependency between microservice-discovery-eureka-ha1 and microservice-discovery-eureka-ha2

从异常可知,发生了循环依赖。如何解决这个问题呢?

解决循环依赖

该问题有很多解决方案,例如使用ambassador pattern,使用外部的DNS容器等,本节用多个容器共享一个网络的方式解决该问题,以下是配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
version: "2"
services:
peer1: # 默认情况下,其他服务可以使用服务名称连接到该服务。因此,对于peer2的节点,它需要连接http://peer1:8761/eureka/,因此需要配置该服务的名称是peer1。
image: itmuch/microservice-discovery-eureka-ha:0.0.1-SNAPSHOT
networks:
- eureka-net
ports:
- "8761:8761"
environment:
- spring.profiles.active=peer1
peer2:
image: itmuch/microservice-discovery-eureka-ha:0.0.1-SNAPSHOT
hostname: peer2
networks:
- eureka-net
ports:
- "8762:8762"
environment:
- spring.profiles.active=peer2
networks:
eureka-net:
driver: bridge

参考文档

(1) 解决循环依赖的总结:http://www.dockone.io/article/929

(2) ambassador pattern官方介绍:https://docs.docker.com/engine/admin/ambassador_pattern_linking/

(3) StackOverflow上对该问题的深入探讨:http://stackoverflow.com/questions/29307645/how-to-link-docker-container-to-each-other-with-docker-compose

(4)Github上的相关Issue: https://github.com/docker/compose/issues/666