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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 01:09:10  来源:igfitidea点击:

Register multiple Instances of a Spring Boot Eureka Client from a single host

javaspringspring-bootnetflix-eureka

提问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 DiscoveryClientonly 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 /whoamiendpoint will show the client's self-knowledge of its application name and port

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

{
  "springApplicationName":"eureka-client",
  "serverPort":"8080"
}

The /instancesendpoint will take up to a minute to update, but should eventually show all the instances of eureka-clientthat 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 /whoamiendpoint will show the name fooand the port 8081.

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

In a minute or so, the /instancesendpoint will show the information about this fooinstance 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-clientby only over-riding the port parameter:

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

cd eureka-client
mvn spring-boot:run -Dserver.port=8082

The /whoamiendpoint for http://localhost:8082shows what we expect.

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

In a minute or so, the /instancesendpoint 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 /instancesendpoint on http://localhost:8080we 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-clientrunning.

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 /instanceson 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-clientwhen 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中查看更多信息