我正在使用Ribbon Load Balancer处理Spring Boot Eureka客户端应用程序。
我在Eureka注册了两个名为" TEST"的服务器实例。在客户端,我有以下代码从Eureka获取服务器。
@Configuration
@ComponentScan
@EnableAutoConfiguration
@EnableEurekaClient
@RestController
public class EurekaConsumerApplication {
@Autowired
DiscoveryClient discoveryClient;
@Autowired
RestTemplate restTemplate;
@RequestMapping(value = "/",method = RequestMethod.GET)
String consumer(){
InstanceInfo instance = discoveryClient.getNextServerFromEureka("TEST", false);
URI uri = UriComponentsBuilder.fromUriString(instance.getHomePageUrl() + "baseDir")
.build()
.toUri();
String baseDir = restTemplate.getForObject(uri, String.class);
return baseDir;
}
public static void main(String[] args) {
SpringApplication.run(EurekaConsumerApplication.class, args);
}
}
application.yml
spring:
application:
name: consumer
info:
component: Consumer to fetch configuration
server:
port: 8090
eureka:
instance:
leaseRenewalIntervalInSeconds: 3
metadataMap:
instanceId: ${vcap.application.instance_id:${spring.application.name}:${spring.application.instance_id:${random.value}}}
client:
# Default values comes from org.springframework.cloud.netflix.eurek.EurekaClientConfigBean
region: default
registryFetchIntervalSeconds: 5
instanceInfoReplicationIntervalSeconds: 5
initialInstanceInfoReplicationIntervalSeconds: 5
serviceUrl:
defaultZone: http://localhost:8761/eureka/
availabilityZones:
default: ${APPLICATION_DOMAIN:${DOMAIN:defaultZone}}
但是,当我使用以下命令命中restful端点时,它会出错:
curl http://localhost:8090/
这是错误:
{"exception":"java.lang.IllegalStateException","message":"org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalStateException: No instances available for Samarths-MacBook-Pro.local","path":"/"}
堆栈跟踪:
2015-07-22 14:37:35.005 INFO 13841 --- [tp1334391583-19] c.netflix.loadbalancer.BaseLoadBalancer : Client:Samarths-MacBook-Pro.local instantiated a LoadBalancer:DynamicServerListLoadBalancer:{NFLoadBalancer:name=Samarths-MacBook-Pro.local,current list of Servers=[],Load balancer stats=Zone stats: {},Server stats: []}ServerList:null
2015-07-22 14:37:35.009 INFO 13841 --- [tp1334391583-19] c.n.l.DynamicServerListLoadBalancer : DynamicServerListLoadBalancer for client Samarths-MacBook-Pro.local initialized: DynamicServerListLoadBalancer:{NFLoadBalancer:name=Samarths-MacBook-Pro.local,current list of Servers=[],Load balancer stats=Zone stats: {},Server stats: []}ServerList:org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList@681eda37
2015-07-22 14:37:35.029 WARN 13841 --- [tp1334391583-19] o.eclipse.jetty.servlet.ServletHandler :
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalStateException: No instances available for Samarths-MacBook-Pro.local
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:978)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:808)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669)
at org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration$ApplicationContextHeaderFilter.doFilterInternal(EndpointWebMvcAutoConfiguration.java:295)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:102)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:85)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.eclipse.jetty..ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:68)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
at org.eclipse.jetty.server.Server.handle(Server.java:499)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:310)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257)
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalStateException: No instances available for Samarths-MacBook-Pro.local
at org.springframework.cloud.netflix.ribbon.RibbonClientHttpRequestFactory.createRequest(RibbonClientHttpRequestFactory.java:64)
at org.springframework.http.client.support.HttpAccessor.createRequest(HttpAccessor.java:76)
at org.springframework.web.client.Rlate.doExecute(RestTemplate.java:565)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:545)
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:253)
at com.securityscorecard.eureka.consumer.EurekaConsumerApplication.consumer(EurekaConsumerApplication.java:53)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:776)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:705)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
... 38 common frames omitted
看起来我的服务器列表是空的。
答案 0 :(得分:17)
您自动装配的RestTemplate
已连接到功能区。因此,您手动查找,然后RestTemplate
正在尝试查找传入功能区的主机名。您有两种选择:1)不要使用netflix DiscoveryClient
并将serviceId作为逻辑主机名传递给功能区(http://TEST/myservice
),2)不要使用autowired {{ 1}},为你的班级创建一个新的。我的选择是#1。
答案 1 :(得分:5)
我得到了这个工作。我必须做的唯一改变就是我使用RestTemplate api的方式。
错误代码:
@Autowired
RestTemplate restTemplate;
@RequestMapping(value = "/",method = RequestMethod.GET)
String consumer(){
String baseDir = restTemplate.getForObject("TEST", String.class);
return baseDir;
}
工作代码:
@Autowired
RestTemplate restTemplate;
@RequestMapping(value = "/",method = RequestMethod.GET)
String consumer(){
String baseDir = restTemplate.getForObject("http://TEST", String.class);
return baseDir;
}
解决方案:
restTemplate.getForObject的第一个参数应该具有URL的格式。域名应该是您要发现的服务的名称。
Ex:http://TEST。这里,TEST是我在eureka注册表中注册的服务器的名称
答案 2 :(得分:2)
这个问题已经得到解答,但我找到了一个看似整洁的解决方法并解决了我们的问题。
首先声明一个新的@Component类,并在其中创建一个返回RestTemplate的方法:
@Component
public class RestTemplateComponentFix{
@Autowired
SomeConfigurationYouNeed someConfiguration;
@LoadBalanced
public RestTemplate getRestTemplate() {
// TODO set up your restTemplate
rt.setRequestFactory( new HttpComponentsClientHttpRequestFactory() );
return rt;
}
}
之后只需在您的类中自动装配restTemplateComponentFix,何时需要其余模板调用restTemplate()方法。像这样:
@Service
public class someClass{
@Autowired
RestTemplateComponentFix restTemplateComponentFix;
public void methodUsingRestTemplate(){
// Some code...
RestTemplate rt = restTemplateComponentFix.getRestTemplate();
// Some code...
}
}
之后,您可以使用以下内容进行单元测试:
RestTemplate rt = Mockito.mock(RestTemplate.class)
when(restTemplateComponentFix.getRestTemplate()).thenReturn(rt);
when(rt.someMethod()).thenReturn(something);
答案 3 :(得分:0)
从@LoadBalanced
删除RestTemplate
注释对我来说很有效。
P.S:@LoadAnnotation
应该仅应用于作为发现服务器的Eureka Server。