java 从单个主机注册 Spring Boot Eureka Client 的多个实例
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36253363/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Register multiple Instances of a Spring Boot Eureka Client from a single host
提问by mcwumbly
UPDATE
更新
The README in this repohas been updated to demonstrate the solution in the accepted answer.
此 repo 中的 README已更新,以演示已接受答案中的解决方案。
I'm working with a simple example of a Spring Boot Eureka service registration and discovery based on this guide.
我正在使用一个基于本指南的 Spring Boot Eureka 服务注册和发现的简单示例。
If I start up one client instance, it registers properly, and it can see itself through the DiscoveryClient
. If I start up a second instance with a different name, it works as well.
如果我启动一个客户端实例,它会正确注册,并且可以通过DiscoveryClient
. 如果我使用不同的名称启动第二个实例,它也能正常工作。
But if I start up two instances with the same name, the dashboard only shows 1 instance running, and the DiscoveryClient
only shows the second instance.
但是如果我启动了两个同名的实例,仪表板只显示 1 个正在运行的实例,并且DiscoveryClient
只显示第二个实例。
When I kill the 2nd instance, the 1st one is visible again through the dashboard and the discovery client.
当我杀死第二个实例时,第一个实例再次通过仪表板和发现客户端可见。
Here are some more details about the steps I'm taking and what I'm seeing:
以下是有关我正在采取的步骤以及我所看到的更多详细信息:
Eureka Server
尤里卡服务器
Start the server
启动服务器
cd eureka-server
mvn spring-boot:run
Visit the Eureka dashboard at http://localhost:8761
在http://localhost:8761访问 Eureka 仪表板
Note that there are no 'Instances' yet registered
请注意,还没有注册“实例”
Eureka Client
尤里卡客户端
Start up a client
启动客户端
cd eureka-client
mvn spring-boot:run
Visit the client directly at http://localhost:8080/
直接访问客户端http://localhost:8080/
The /whoami
endpoint will show the client's self-knowledge of its application name and port
该/whoami
终端将展示其应用程序名称和端口的客户端的自知之明
{
"springApplicationName":"eureka-client",
"serverPort":"8080"
}
The /instances
endpoint will take up to a minute to update, but should eventually show all the instances of eureka-client
that have been registered with the Eureka Discovery Client.
该/instances
端点将需要长达一分钟更新,但最终应该会显示所有的情况下,eureka-client
已登记的尤里卡发现客户端。
[
{
"host":"hostname",
"port":8080,
"serviceId":"EUREKA-CLIENT",
"uri":"http://hostname:8080",
"secure":false
}
]
You can also visit the Eureka dashoboard again now and see it listed there.
您现在还可以再次访问 Eureka 仪表板并查看它列在那里。
Spin up another client with a different name
使用不同的名称启动另一个客户端
You can see that another client will be registred by doing the following:
您可以通过执行以下操作看到另一个客户端将被注册:
cd eureka-client
mvn spring-boot:run -Dspring.application.name=foo -Dserver.port=8081
The /whoami
endpoint will show the name foo
and the port 8081
.
该/whoami
终端将显示名称foo
和端口8081
。
In a minute or so, the /instances
endpoint will show the information about this foo
instance too.
/instances
大约一分钟后,端点也会显示有关此foo
实例的信息。
On the Eureka dashboard, two clients will now be registered.
在 Eureka 仪表板上,现在将注册两个客户端。
Spin up another client with the samename
自旋向上的另一端用同样的名字
Now try spinning up another instance of eureka-client
by only over-riding the port parameter:
现在尝试eureka-client
仅通过覆盖端口参数来启动另一个实例:
cd eureka-client
mvn spring-boot:run -Dserver.port=8082
The /whoami
endpoint for http://localhost:8082
shows what we expect.
的/whoami
端点http://localhost:8082
显示了我们的期望。
In a minute or so, the /instances
endpoint now shows the instance running on port 8082 also, but for some reason, it doesn't show the instance running on port 8080.
在一分钟左右,/instances
端点现在也显示在端口 8082 上运行的实例,但由于某种原因,它没有显示在端口 8080 上运行的实例。
And if we check the /instances
endpoint on http://localhost:8080
we also now only see the instance running on 8082 (even though clearly, the one on 8080 is running since that's what we're asking for.
如果我们检查/instances
端点,http://localhost:8080
我们现在也只能看到在 8082 上运行的实例(尽管很明显,8080 上的实例正在运行,因为这是我们所要求的。
The Eureka dashboard only shows 1 instance of eureka-client
running.
Eureka 仪表板仅显示 1 个eureka-client
正在运行的实例。
What's going on here?
这里发生了什么?
Let's try killing the instance running on 8082 and see what happens.
让我们尝试杀死在 8082 上运行的实例,看看会发生什么。
When we query /instances
on 8080, it still only shows the instance on 8082.
当我们/instances
在8080上查询时,它仍然只显示8082上的实例。
But a minute later, that goes away and we just see the instance on 8080 again.
但是一分钟后,这种情况消失了,我们再次看到了 8080 上的实例。
The question is, why don't we see both instances of eureka-client
when they are both running?
问题是,为什么我们看不到eureka-client
它们都在运行的两个实例?
采纳答案by bad_habit
For local deployments, try to configure {namespace}.instanceId property in eureka-client.properties(or eureka.instance.metadataMap.instanceId for proper yaml file in case of Spring Cloud based setup). It's deeply rooted in the way Eureka server calculates application lists and compares InstanceInfo for the PeerAwareInstanceRegistryImpl - when no more concrete data (e.g.: instance metadata is available) they try to get the id from the hostname..
对于本地部署,尝试在 eureka-client.properties 中配置 {namespace}.instanceId 属性(或 eureka.instance.metadataMap.instanceId 在基于 Spring Cloud 的设置的情况下为正确的 yaml 文件)。它深深植根于 Eureka 服务器计算应用程序列表和比较 PeerAwareInstanceRegistryImpl 的 InstanceInfo 的方式 - 当没有更多具体数据(例如:实例元数据可用)时,它们会尝试从主机名中获取 id..
I wouldn't recommend it for AWS deployment though, cause messing around with instanceId will bring you trouble figuring out which machine hosts a particular service - on the other hand I doubt that you'll hosts two identical services on one machine, right?
不过,我不建议将它用于 AWS 部署,因为搞乱 instanceId 会让您无法确定哪台机器托管特定服务 - 另一方面,我怀疑您是否会在一台机器上托管两个相同的服务,对吧?
回答by Chuan CC
In order to get all instances show up in the admin portal by setting unique euraka.instance.hostname in your Eureka configuration file.
为了通过在 Eureka 配置文件中设置唯一的 euraka.instance.hostname 来让所有实例显示在管理门户中。
The hostname is used as key for storing the InstanceInfo in com.netflix.discovery.shared.Application (since no UniqueIdentifier is set). So you have to use unique hostnames. When you test ribbon in this scenario you would see that the load won't be balanced.
主机名用作在 com.netflix.discovery.shared.Application 中存储 InstanceInfo 的键(因为没有设置 UniqueIdentifier)。所以你必须使用唯一的主机名。在这种情况下测试功能区时,您会看到负载不会平衡。
Following application.yml is example:
以下 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}}
It's a bug before in Eureka, you can check further information in https://github.com/codecentric/spring-boot-admin/issues/134
这是Eureka之前的一个错误,您可以在https://github.com/codecentric/spring-boot-admin/issues/134中查看更多信息