代码之家  ›  专栏  ›  技术社区  ›  NikhilWanpal

springboot2+feign+eureka客户端无法将服务名称解析为URL

  •  0
  • NikhilWanpal  · 技术社区  · 6 年前

    尤里卡应用程序.yml

    spring:
      application:
        name: eureka-service
    server:
      port: 8761
    eureka:
      instance:
        hostname: localhost
        preferIpAddress: true
      client:
        registerWithEureka: false
        fetchRegistry: false
        serviceUrl:
          defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka
    

    spring:
      application:
        name: secondservice
    eureka:
      instance:
        hostname: ${spring.application.name}
        preferIpAddress: true
        instanceId: ${spring.application.name}:${spring.application.instance_id:${random.value}}
        statusPageUrlPath: ${server.servlet.context-path}/actuator/info
        healthCheckUrlPath: ${server.servlet.context-path}/actuator/health
        leaseRenewalIntervalInSeconds: 15
        leaseExpirationDurationInSeconds: 45
        metadata-map:
          server.servlet.context-path: ${server.servlet.context-path}
      client:
        enabled: true
        serviceUrl:
          defaultZone: http://localhost:8761/eureka
    

    我的 测试/模板服务的bootstrap.yml

    spring:
      application:
        name: templateservice
    eureka:
      instance:
        hostname: ${spring.application.name}
        preferIpAddress: true
        instanceId: ${spring.application.name}:${spring.application.instance_id:${random.value}}
        statusPageUrlPath: ${server.servlet.context-path}/actuator/info
        healthCheckUrlPath: ${server.servlet.context-path}/actuator/health
        leaseRenewalIntervalInSeconds: 15
        leaseExpirationDurationInSeconds: 45
        metadata-map:
          server.servlet.context-path: ${server.servlet.context-path}
      client:
        enabled: true
        serviceUrl:
          defaultZone: http://localhost:8761/eureka
    logging:
      level:
        com...MessageServiceClient: DEBUG
    

    外国客户

    @FeignClient(name = "secondservice", configuration = FeignConfig.class)
    public interface MessageServiceClient {
        @RequestMapping(method = RequestMethod.GET, value = "/dummy")
        public String getMessage();
    }
    

    我的服务级别:

    @Autowired MessageServiceClient messageServiceClient;
    @Autowired private LoadBalancerClient loadBalancer;
    public String getDummyMessage() {
        ServiceInstance instance = loadBalancer.choose("secondservice");
        URI secondServiceUri = URI.create(String.format("http://%s:%s", instance.getHost(), instance.getPort()));
    
        System.out.println(secondServiceUri); // logs http://192.168.0.205:8090, check log below
    
        return messageServiceClient.getMessage(); // throws 404??
    }
    

    在FeignConfig中,唯一要做的就是将日志级别设置为FULL。日志如下所示:

    2018-10-08 11:14:59.511  INFO [templateservice,,,] 16801 --- [onPool-worker-2] s.c.a.AnnotationConfigApplicationContext : Refreshing SpringClientFactory-secondservice: startup date [Mon Oct 08 11:14:59 IST 2018]; parent: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@451f35ad
    2018-10-08 11:14:59.683  INFO [templateservice,,,] 16801 --- [onPool-worker-2] f.a.AutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
    2018-10-08 11:15:00.042  INFO [templateservice,,,] 16801 --- [onPool-worker-2] c.netflix.config.ChainedDynamicProperty  : Flipping property: secondservice.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
    2018-10-08 11:15:00.095  INFO [templateservice,,,] 16801 --- [onPool-worker-2] c.n.u.concurrent.ShutdownEnabledTimer    : Shutdown hook installed for: NFLoadBalancer-PingTimer-secondservice
    2018-10-08 11:15:00.146  INFO [templateservice,,,] 16801 --- [onPool-worker-2] c.netflix.loadbalancer.BaseLoadBalancer  : Client: secondservice instantiated a LoadBalancer: DynamicServerListLoadBalancer:{NFLoadBalancer:name=secondservice,current list of Servers=[],Load balancer stats=Zone stats: {},Server stats: []}ServerList:null
    2018-10-08 11:15:00.189  INFO [templateservice,,,] 16801 --- [onPool-worker-2] c.n.l.DynamicServerListLoadBalancer      : Using serverListUpdater PollingServerListUpdater
    2018-10-08 11:15:00.287  INFO [templateservice,,,] 16801 --- [onPool-worker-2] c.netflix.config.ChainedDynamicProperty  : Flipping property: secondservice.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
    2018-10-08 11:15:00.291  INFO [templateservice,,,] 16801 --- [onPool-worker-2] c.n.l.DynamicServerListLoadBalancer      : DynamicServerListLoadBalancer for client secondservice initialized: DynamicServerListLoadBalancer:{NFLoadBalancer:name=secondservice,current list of Servers=[192.168.0.205:8090, 192.168.0.205:8090],Load balancer stats=Zone stats: {defaultzone=[Zone:defaultzone; Instance count:2;   Active connections count: 0;    Circuit breaker tripped count: 0;   Active connections per server: 0.0;]
    },Server stats: [[Server:192.168.0.205:8090;    Zone:defaultZone;   Total Requests:0;   Successive connection failure:0;    Total blackout seconds:0;   Last connection made:Thu Jan 01 05:30:00 IST 1970;  First connection made: Thu Jan 01 05:30:00 IST 1970;    Active Connections:0;   total failure count in last (1000) msecs:0; average resp time:0.0;  90 percentile resp time:0.0;    95 percentile resp time:0.0;    min resp time:0.0;  max resp time:0.0;  stddev resp time:0.0]
    ]}ServerList:org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList@3625959e
    http://192.168.0.205:8090
    2018-10-08 11:15:01.215  INFO [templateservice,,,] 16801 --- [erListUpdater-0] c.netflix.config.ChainedDynamicProperty  : Flipping property: secondservice.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
    2018-10-08 11:15:07.951 DEBUG [templateservice,,,] 16801 --- [onPool-worker-2] c.e.m.t.clients.MessageServiceClient     : [MessageServiceClient#getMessage] ---> GET http://secondservice/dummy HTTP/1.1
    2018-10-08 11:15:12.527 DEBUG [templateservice,,,] 16801 --- [onPool-worker-2] c.e.m.t.clients.MessageServiceClient     : [MessageServiceClient#getMessage] <--- HTTP/1.1 404 (4575ms)
    2018-10-08 11:15:12.559 ERROR [templateservice,7004692c56b2e643,7004692c56b2e643,false] 16801 --- [nio-8080-exec-4] o.s.c.s.i.web.ExceptionLoggingFilter     : Uncaught exception thrown
    

    问题是,这抛出一个404,当然是因为它试图命中的url是 http://secondservice/dummy ,而没有这样的事情。如果我 url 在假客户机上,它是有效的,但是尤里卡的意义是什么呢? 另外,当这起作用时,外国客户机会自动使用上下文路径吗?或者我必须在客户端的每个url中指定它?

    更新1 http://localhost:8761/eureka/apps/secondservice Response from Eureka to second service

    1 回复  |  直到 6 年前
        1
  •  8
  •   NikhilWanpal    6 年前

    找到了!它与发现无关,也与配置无关,这是因为feign不支持上下文路径!

    在尝试“哑巴”下来,我继续删除每一个配置到最低限度,以保持服务。当我删除第二个服务的上下文路径时,它突然起了作用。问题是,如果由其他服务设置,则Feign+Ribbon不支持自定义上下文路径。这是一个 old bug ,仍未修复。

    有两种可能的解决方案:

    1. 在外部客户机中添加上下文路径。所以基本上你的外国客户变成了:

    //这需要在这里为下面的格式是正确的

    @FeignClient(name = "secondservice/secondservice", configuration = FeignConfig.class)
    public interface MessageServiceClient {
        @RequestMapping(method = RequestMethod.GET, value = "/dummy")
        public String getMessage();
    }
    

    我个人不喜欢这两种解决方案。我喜欢有一个上下文路径,好吧,给一个url提供上下文,它就变得不言自明了。但它是其他服务(secondservice)的属性,应由该服务选择/更改。因此不应该在依赖服务中硬编码。我本想得到支持,但与此同时,我要:

    @FeignClient(name = "${dependencies.secondservice.url}")
    public interface MessageServiceClient {....}
    

    在application.properties中: dependencies.secondservice.url=secondservice/secondservice 这清楚地表明,该属性属于依赖项,而不是此服务。

    其他注意事项: 1.我可以追踪到 SynchronousMethodHandler#executeAndDecode response = client.execute(request, options); . 在此之前,url已解析。 2.正在记录的url: GET http://secondservice/secondservice/dummy 实际上是正确的URL,第一个 secondservice https://cloud.spring.io/spring-cloud-static/Finchley.SR1/single/spring-cloud.html#_using_ribbon . 注意传递给restemplate的url。这正是引发寻找替代原因的原因。

        2
  •  1
  •   CKE user3026927    5 年前

    我改变了 eureka.client.serviceUrl.defaultZone ,从两个服务属性文件。然后我换了 localhost 有IP地址,对我有用。