簡體   English   中英

帶有 Eureka DiscoveryClient 的 Spring Boot 應用程序無法啟動

[英]Spring Boot app with Eureka DiscoveryClient fails to start

我正在嘗試編寫一個簡單的 Spring Boot 應用程序,它可以 (1) 向 Netflix Eureka 服務器注冊,以及 (2) 查詢 Eureka 服務器以檢索其他注冊服務的詳細信息。

我的客戶端類有一個com.netflix.discovery.DiscoveryClient類型的@Autowired字段,用於與 Eureka 交談並查詢它以了解其他服務。 在我的@EnableDiscoveryClient我有注釋@EnableDiscoveryClient

@SpringBootApplication
@EnableDiscoveryClient
public class AppBootstrap {

    public static void main(String[] args) {
        SpringApplication.run(AppBootstrap.class, args);
    }

}

在 src/main/resources 下的application.yml文件中,我有:

eureka:
    instance:
         lease-renewal-interval-in-seconds: 10
         lease-expiration-duration-in-seconds: 20
         prefer-ip-address: true
         secure-port: 443
         non-secure-port: 80
         metadata-map:
             instanceId: my-test-instance
    client:
         service-url:
             defaultZone: http://localhost:9080/eureka/
         registry-fetch-interval-seconds: 6
         instance-info-replication-interval-seconds: 6
         register-with-eureka: true
         fetch-registry: true
         heartbeat-executor-thread-pool-size: 5
         eureka-service-url-poll-interval-seconds: 10

當我啟動我的應用程序時,該服務無法啟動,引發了一個根植於以下位置的異常:

引起:java.lang.AbstractMethodError: org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean.getInstanceI d()Ljava/lang/String; 在 com.netflix.appinfo.providers.EurekaConfigBasedInstanceInfoProvider.get(EurekaConfigBasedInstanceInfoProvider .java:53) 在 com.netflix.appinfo.ApplicationInfoManager.initComponent(ApplicationInfoManager.java:90) ... 25 更多

我不知道這里發生了什么。 有任何想法嗎? 我相信即使我的 Eureka 配置不正確,該應用程序仍應啟動,但它在啟動時失敗了。

其次,我是否使用了正確的 DiscoveryClient? 理想情況下,我想讓它變得通用,以便我可以將它與 Eureka、Consul 或 ZooKeeper 一起用作示例。 我發現文檔並不能很好地說明使用這些 Spring Cloud / Netflix 發現組件時到底需要什么。

您可以使用

org.springframework.cloud.client.discovery.DiscoveryClient

然后您可以使用 discoveryClient.getInstances 獲取實例列表

ServiceInstance instance = discoveryClient.getInstances(service).get(0);
instance.getUri().toString();

如果您使用其他組件,如 RestTemplate、Ribbon 等,則只需在 URL 中使用服務名稱(在 eureka 中注冊的名稱)

restTemplate.getForObject("http://PRODUCTSMICROSERVICE/products/{id}", Product.class, id)

你可以在這里看到更多

https://spring.io/blog/2015/01/20/microservice-registration-and-discovery-with-spring-cloud-and-netflix-s-eureka

當我使用 discoveryclient 在任何函數之外的類中獲取信息時,我收到了自動裝配錯誤。 所以我使用 eureka 來找出我的服務的端口,因為端口被描述為 0 因此服務在作為 spring 啟動應用程序啟動時動態地選擇端口。 我需要以編程方式知道端口。 在控制器中,我以錯誤的方式使用了如下代碼

public class HelloController {

private static final Logger LOG = LoggerFactory.getLogger(HelloController.class);

@Autowired
private DiscoveryClient discoveryClient;

int port = discoveryClient.getLocalServiceInstance().getPort();


@RequestMapping("/hello/{id}")
public String  sayhello(@PathVariable String id)
{
    String s ="A very nice and warm welcome to the world "+id;
            LOG.info(String.format("calling helloservice for %s",id));
    LOG.info(String.format("calling helloservice for port %d",port));
    return s;
} 

一旦我將端口代碼放入 sayhello 方法中,錯誤就消失了。 所以正確的取回端口的方法如下

public class HelloController {

private static final Logger LOG = LoggerFactory.getLogger(HelloController.class);

@Autowired
private DiscoveryClient discoveryClient;



@RequestMapping("/hello/{id}")
public String  sayhello(@PathVariable String id)
{
    String s ="A very nice and warm welcome to the world "+id;
    int port = discoveryClient.getLocalServiceInstance().getPort();
    LOG.info(String.format("calling helloservice for %s",id));
    LOG.info(String.format("calling helloservice for port %d",port));
    return s;
}

如果我們使用最新版本的 Spring Boot,那么我們不需要在主類中定義 @EnableDiscoveryClient 或 @EnableEurekaClient 。 當我們在 pom.xml 中添加依賴項時,Spring 會在后台發生這種情況

請確保您的文件具有以下基本信息。

pom.xml

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>2020.0.0-SNAPSHOT</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

根據選擇的application.properties或 YAML 文件

spring.application.name=eureka-client

eureka.client.service-url.defaultZone: ${EUREKA_URI:http://localhost:8761/eureka}
eureka.instance.prefer-ip-address= true
server.port= 8082

Application.java 中的主類中不需要更改或@Annotations

在此處查看我的GIT 存儲庫以獲取工作代碼。

添加 application.yml 文件這些設置;

我們的產品應用程序運行在這個端口

服務器:端口:8482

我們的服務將通過自己的服務名稱注冊

彈簧:應用程序:名稱:產品服務

# To be register we assign eureka service url
eureka:
   client:
     service-url :
        defaultZone:
            ${EUREKA_URI:http://localhost:8481/eureka} # add your port where your eureka server running
   instance :
      prefer-ip-address : true

# Logging file path
logging :
   file :
      path : target/${spring.application.name}.log

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM