从单个主机注册Spring Boot Eureka Client的多个实例

mcw*_*bly 8 java spring spring-boot netflix-eureka

UPDATE

此repo中的README 已更新,以在接受的答案中演示解决方案.


我正在使用基于本指南的Spring Boot Eureka服务注册和发现的简单示例.

如果我启动一个客户端实例,它会正确注册,并且可以通过它看到自己DiscoveryClient.如果我使用不同的名称启动第二个实例,它也可以正常工作.

但是,如果我启动两个具有相同名称的实例,则仪表板仅显示1个正在运行的实例,并且DiscoveryClient仅显示第二个实例.

当我杀死第二个实例时,第一个实例再次通过仪表板和发现客户端可见.

以下是我正在采取的步骤以及我所看到的步骤的更多细节:

尤里卡服务器

启动服务器

cd eureka-server
mvn spring-boot:run
Run Code Online (Sandbox Code Playgroud)

访问位于http:// localhost:8761的Eureka仪表板

请注意,尚未注册"实例"

尤里卡客户

启动客户端

cd eureka-client
mvn spring-boot:run
Run Code Online (Sandbox Code Playgroud)

直接访问客户端http:// localhost:8080 /

/whoami终端将展示其应用程序名称和端口的客户端的自知之明

{
  "springApplicationName":"eureka-client",
  "serverPort":"8080"
}
Run Code Online (Sandbox Code Playgroud)

/instances端点将需要长达一分钟更新,但最终应显示的所有实例eureka-client已与尤里卡发现客户端注册.

[   
    {
      "host":"hostname",
      "port":8080,
      "serviceId":"EUREKA-CLIENT",
      "uri":"http://hostname:8080",
      "secure":false   
    } 
]
Run Code Online (Sandbox Code Playgroud)

您现在也可以再次访问Eureka dashoboard,并在那里看到它.

使用其他名称启动另一个客户端

您可以通过执行以下操作看到另一个客户端将被注册:

cd eureka-client
mvn spring-boot:run -Dspring.application.name=foo -Dserver.port=8081
Run Code Online (Sandbox Code Playgroud)

/whoami终端将显示名称foo和端口8081.

在一分钟左右,/instances端点也将显示有关此foo实例的信息.

在Eureka仪表板上,现在将注册两个客户端.

使用相同的名称启动另一个客户端

现在尝试eureka-client通过仅覆盖port参数来启动另一个实例:

cd eureka-client
mvn spring-boot:run -Dserver.port=8082
Run Code Online (Sandbox Code Playgroud)

/whoami端点http://localhost:8082显示了我们的期望.

在一分钟左右,/instances端点现在也显示在端口8082上运行的实例,但由于某种原因,它不显示在端口8080上运行的实例.

如果我们检查/instances端点,http://localhost:8080我们现在也只看到在8082上运行的实例(尽管很明显,8080上的那个正在运行,因为那是我们要求的.

Eureka仪表板仅显示1个eureka-client运行实例.

这里发生了什么?

让我们尝试杀死在8082上运行的实例,看看会发生什么.

当我们/instances在8080上查询时,它仍然只显示8082上的实例.

但是一分钟之后,它消失了,我们再次看到8080上的实例.

问题是,为什么我们不看到它们eureka-client何时运行的两个实例?

bad*_*bit 7

对于本地部署,请尝试在eureka-client.properties(或eureka.instance.metadataMap.instanceId)中配置{namespace} .instanceId属性,以获取基于Spring Cloud的设置的正确yaml文件.它深深植根于Eureka服务器计算应用程序列表的方式,并比较了PeerAwareInstanceRegistryImpl的InstanceInfo - 当没有更具体的数据(例如:实例元数据可用)时,他们尝试从主机名中获取id.

我不建议将其用于AWS部署,因为使用instanceId会导致您无法确定哪台计算机托管特定服务 - 另一方面我怀疑您将在一台计算机上托管两个相同的服务,对吧?


Chu*_* CC 5

通过在Eureka配置文件中设置唯一的euraka.instance.hostname,可以在管理门户中显示所有实例.

主机名用作在com.netflix.discovery.shared.Application中存储InstanceInfo的密钥(因为没有设置UniqueIdentifier).所以你必须使用独特的主机名.在此方案中测试功能区时,您会看到负载不会平衡.

以下是application.yml的例子:

server:
  port: ${PORT:0}

info:
  component: example.server

logging:
  level:
    com.netflix.discovery: 'OFF'
    org.springframework.cloud: 'DEBUG'

eureka:
  instance:
    leaseRenewalIntervalInSeconds: 1
    leaseExpirationDurationInSeconds: 1
    metadataMap:
      instanceId: ${spring.application.name}:${spring.application.instance_id:${random.value}}
    instanceId: ${spring.application.name}:${spring.application.instance_id:${random.value}}
Run Code Online (Sandbox Code Playgroud)

这是Eureka之前的一个错误,您可以在https://github.com/codecentric/spring-boot-admin/issues/134查看更多信息.