Java 从单个主机注册Spring Boot Eureka客户端的多个实例
更新 中的自述已更新,以在已接受的答案中演示解决方案Java 从单个主机注册Spring Boot Eureka客户端的多个实例,java,spring,spring-boot,netflix-eureka,Java,Spring,Spring Boot,Netflix Eureka,更新 中的自述已更新,以在已接受的答案中演示解决方案 我正在使用一个基于的Spring Boot Eureka服务注册和发现的简单示例 如果我启动一个客户端实例,它将正确注册,并且它可以通过DiscoveryClient看到自己。如果我用另一个名称启动第二个实例,它也可以工作 但是,如果我用相同的名称启动两个实例,仪表板只显示一个正在运行的实例,而DiscoveryClient只显示第二个实例 当我杀死第二个实例时,第一个实例通过仪表板和发现客户端再次可见 以下是关于我正在采取的步骤和我所看到
我正在使用一个基于的Spring Boot Eureka服务注册和发现的简单示例 如果我启动一个客户端实例,它将正确注册,并且它可以通过
DiscoveryClient
看到自己。如果我用另一个名称启动第二个实例,它也可以工作
但是,如果我用相同的名称启动两个实例,仪表板只显示一个正在运行的实例,而DiscoveryClient
只显示第二个实例
当我杀死第二个实例时,第一个实例通过仪表板和发现客户端再次可见
以下是关于我正在采取的步骤和我所看到的情况的更多细节:
Eureka服务器
启动服务器
cd eureka-server
mvn spring-boot:run
访问Eureka仪表板,网址为
请注意,尚未注册任何“实例”
尤里卡客户
启动客户机
cd eureka-client
mvn spring-boot:run
直接访问客户
/whoami
端点将显示客户端对其应用程序名称和端口的了解
{
"springApplicationName":"eureka-client",
"serverPort":"8080"
}
更新/instances
端点将需要一分钟,但最终应显示已在eureka Discovery client注册的eureka client
的所有实例
[
{
"host":"hostname",
"port":8080,
"serviceId":"EUREKA-CLIENT",
"uri":"http://hostname:8080",
"secure":false
}
]
现在,您还可以再次访问Eureka dashoboard,并在那里看到它的列表
启动另一个具有不同名称的客户端
您可以看到,通过执行以下操作将注册另一个客户端:
cd eureka-client
mvn spring-boot:run -Dspring.application.name=foo -Dserver.port=8081
/whoami
端点将显示名称foo
和端口8081
大约一分钟后,/instances
端点也将显示有关此foo
实例的信息
在Eureka仪表板上,现在将注册两个客户端
启动另一个同名客户机
现在,仅通过使用端口参数,尝试旋转另一个eureka客户端实例
:
cd eureka-client
mvn spring-boot:run -Dserver.port=8082
http://localhost:8082
显示了我们的期望
大约一分钟后,/instances
端点现在也会显示在端口8082上运行的实例,但由于某些原因,它不会显示在端口8080上运行的实例
如果我们在http://localhost:8080
我们现在也只看到在8082上运行的实例(尽管很明显,8080上的实例正在运行,因为这正是我们所要求的
Eureka仪表板仅显示运行的Eureka客户端的1个实例
这是怎么回事
让我们尝试终止在8082上运行的实例,看看会发生什么
当我们在8080上查询/instances
时,它仍然只显示8082上的实例
但一分钟后,它消失了,我们又看到了8080上的实例
问题是,为什么我们不在运行eureka客户端的两个实例时都看到它们呢?对于本地部署,请尝试在eureka客户端.properties中配置{namespace}.instanceId属性(或者在基于Spring云的设置中为正确的yaml文件配置eureka.instance.metadataMap.instanceId)。它深深植根于Eureka server计算应用程序列表和比较PeerAwareInstanceRegistryImpl的InstanceInfo的方式-当没有更多具体数据(例如:实例元数据可用)时,他们会尝试从主机名获取id
不过,我不建议将其用于AWS部署,因为混淆instanceId会给您带来麻烦,无法确定哪台计算机承载特定服务-另一方面,我怀疑您是否会在一台计算机上承载两个相同的服务,对吗?,以便通过设置唯一的euraka在管理门户中显示所有实例。Eureka配置文件中的instance.hostname
主机名用作在com.netflix.discovery.shared.Application中存储InstanceInfo的密钥(因为未设置UniqueIdentifier)。因此您必须使用唯一的主机名。在这种情况下测试ribbon时,您会发现负载不会平衡
下面是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}}
这是Eureka中以前的一个bug,您可以在中查看更多信息。谢谢,我以前没有看到它,但它看起来实际上是的一个副本(我需要设置的属性中的小错误,应该是Eureka.instance.metadataMap.instanceId
)我用mvn spring boot启动了第二个实例:run-Dserver.port8082-Deureka.instance.metadataMap.instanceId=instance2
,它现在显示在仪表板和来自发现客户端的响应中。我找到了{namespace}.instanceId
将在今天起与eureka主分支一起工作,而不是eureka.instance.metadataMap.instanceId
。可能它已被弃用并最终被删除-IMHO名称空间更健壮。我将在基础impl中验证它。感谢更新。