我正在尝试使用Netflix Eureka来帮助管理服务。我首先开发了一个简单的eureka服务器,然后开发了两个服务:客户端和服务器。服务器提供客户端将调用的REST端点。
当我在localhost上运行所有程序时,它们都能很好地工作。服务在eureka服务器上注册自己,客户端成功调用服务器。当我在浏览器中打开http://localhost:8761
时,得到的是我期望看到的:
然后,我决定通过将这些应用程序分离到不同的机器(这些虚拟机由无业游民管理)上使其更加现实。据我所知,服务器和客户端正在向eureka服务器注册自己,但是我无法让客户端成功调用服务器。
根据我在搜索中发现的内容,传递给RestTemplate
实例以进行REST调用的URL只需要指定要调用的服务的“ ID”即可。不需要主机名或IP地址或端口-就是这样吗?
似乎很近,但是没有用。我想知道原因(以及获得有效的方法)。
这是代码。
Eureka服务器
EurekaServiceApplication.java
@EnableEurekaServer
@SpringBootApplication
public class EurekaServiceApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServiceApplication.class, args);
}
}
application.yml:
server:
port: 8761
eureka:
client:
register-with-eureka: false
fetch-registry: false
logging:
level:
com:
netflix:
eureka: OFF
discovery: OFF
再简单不过了。
服务器
ApplicationMain.java:
@EnableDiscoveryClient
@SpringBootApplication
public class ApplicationMain {
public static void main(String[] args) {
SpringApplication.run(ApplicationMain.class, args);
}
}
Server.java:
@Service
public class Server {
private final Logger logger = LogManager.getLogger();
@Autowired
private ConfigurableApplicationContext context;
public String getID() {
return "server";
}
}
ServerController.java:
@RestController
@RequestMapping("/v1/server")
public class ServerController {
@Autowired
private Server service;
@Autowired
private DiscoveryClient dicoveryClient;
@GetMapping(value = "/id", produces = {MediaType.APPLICATION_JSON_VALUE})
public DeferredResult<ResponseEntity<GeneralResponse>> getID() {
DeferredResult<ResponseEntity<GeneralResponse>> result = new DeferredResult<>();
GeneralResponse genResp = new GeneralResponse();
genResp.setMessage(service.getID());
result.setResult(ResponseEntity.ok(genResp));
return result;
}
@RequestMapping("/instances")
public List<ServiceInstance> instances() {
return dicoveryClient.getInstances("SERVER");
}
}
bootstrap.yml:
spring:
application:
name: server
application.yml:
server:
port: 8091
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka
客户
ApplicationMain.java:
@EnableDiscoveryClient
@SpringBootApplication
public class ApplicationMain {
public static void main(String[] args) {
SpringApplication.run(ApplicationMain.class, args);
}
}
Client.java:
@Service
public class Client {
private final Logger logger = LogManager.getLogger();
@Autowired
private RestTemplate restTemplate;
@Scheduled(fixedRateString = "10000")
public void callServer() {
String url = "http://server/v1/server/id";
ResponseEntity<GeneralResponse> response =
restTemplate.getForEntity(url, GeneralResponse.class);
logger.info("response: {}", response.getBody().getMessage());
}
}
bootstrap.yml:
spring:
application:
name: client
application.yml:
server:
port: 8092
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka
对于在三台不同的计算机上运行这些应用程序的情况,我编辑服务器和客户端的application.yml
,将localhost
更改为运行eureka服务器的计算机的IP地址。
这是客户端上抛出的异常:
2019-11-27 14:34:11.991 INFO 11807 --- [ scheduling-1] c.n.l.BaseLoadBalancer : Client: server instantiated a LoadBalancer: DynamicServerListLoadBalancer:{NFLoadBalancer:name=server,current list of Servers=[],Load balancer stats=Zone stats: {},Server stats: []}ServerList:null
2019-11-27 14:34:12.000 INFO 11807 --- [ scheduling-1] c.n.l.DynamicServerListLoadBalancer : Using serverListUpdater PollingServerListUpdater
2019-11-27 14:34:12.038 INFO 11807 --- [ scheduling-1] c.n.c.ChainedDynamicProperty : Flipping property: server.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
2019-11-27 14:34:12.041 INFO 11807 --- [ scheduling-1] c.n.l.DynamicServerListLoadBalancer : DynamicServerListLoadBalancer for client server initialized: DynamicServerListLoadBaActive connections count: 0;servCircuit breaker tripped count: 0;host:80Active connections per server: 0.0;]{defaultzone=[Zone:defaultzone; Instance },Server stats: average resp time:0.0;1;90 percentile resp time:0.0;tion95 percentile resp time:0.0;ST 1min resp time:0.0;nectiomax resp time:0.0;ure costddev resp time:0.0]
]}ServerList:org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList@af0e207
2019-11-27 14:34:12.098 ERROR 11807 --- [ scheduling-1] o.s.s.s.TaskUtils$LoggingErrorHandler : Unexpected error occurred in scheduled task.
org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://server/v1/server/id": Connection refused (Connection refused); nested exception is java.net.ConnectException: Connection refused (Connection refused)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:744) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:670) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.web.client.RestTemplate.getForEntity(RestTemplate.java:338) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at com.example.Client.callServer(Client.java:66) ~[client-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_232]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_232]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_232]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_232]
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84) ~[spring-context-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) [spring-context-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_232]
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) [?:1.8.0_232]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [?:1.8.0_232]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [?:1.8.0_232]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_232]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_232]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_232]
Caused by: java.net.ConnectException: Connection refused (Connection refused)
at java.net.PlainSocketImpl.socketConnect(Native Method) ~[?:1.8.0_232]
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) ~[?:1.8.0_232]
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) ~[?:1.8.0_232]
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) ~[?:1.8.0_232]
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) ~[?:1.8.0_232]
at java.net.Socket.connect(Socket.java:607) ~[?:1.8.0_232]
at java.net.Socket.connect(Socket.java:556) ~[?:1.8.0_232]
at sun.net.NetworkClient.doConnect(NetworkClient.java:180) ~[?:1.8.0_232]
at sun.net.www.http.HttpClient.openServer(HttpClient.java:463) ~[?:1.8.0_232]
at sun.net.www.http.HttpClient.openServer(HttpClient.java:558) ~[?:1.8.0_232]
at sun.net.www.http.HttpClient.<init>(HttpClient.java:242) ~[?:1.8.0_232]
at sun.net.www.http.HttpClient.New(HttpClient.java:339) ~[?:1.8.0_232]
at sun.net.www.http.HttpClient.New(HttpClient.java:357) ~[?:1.8.0_232]
at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1226) ~[?:1.8.0_232]
at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1162) ~[?:1.8.0_232]
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:1056) ~[?:1.8.0_232]
at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:990) ~[?:1.8.0_232]
at org.springframework.http.client.SimpleBufferingClientHttpRequest.executeInternal(SimpleBufferingClientHttpRequest.java:76) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.http.client.InterceptingClientHttpRequest$InterceptingRequestExecution.execute(InterceptingClientHttpRequest.java:108) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.cloud.client.loadbalancer.LoadBalancerRequestFactory.lambda$createRequest$0(LoadBalancerRequestFactory.java:59) ~[spring-cloud-commons-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.execute(RibbonLoadBalancerClient.java:112) ~[spring-cloud-netflix-ribbon-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.execute(RibbonLoadBalancerClient.java:94) ~[spring-cloud-netflix-ribbon-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor.intercept(LoadBalancerInterceptor.java:55) ~[spring-cloud-commons-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.http.client.InterceptingClientHttpRequest$InterceptingRequestExecution.execute(InterceptingClientHttpRequest.java:92) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.http.client.InterceptingClientHttpRequest.executeInternal(InterceptingClientHttpRequest.java:76) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:735) ~[spring-web-5.1.8.RELEASE.jar:5.1.8.RELEASE]
... 16 more
更新:
ClientConfig.java:
@Configuration
@EnableScheduling
public class ClientConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
更新:
我的工作环境中已有一个Web代理,过去已知该代理会导致连接问题。经过更多研究后,我发现有一些eureka属性可以指定代理服务器。
因此,我设置了以下eureka属性,以查看是否有帮助。没有。
eureka:
client:
register-with-eureka: false
fetch-registry: false
proxy-host: <proxy server>
proxy-port: <proxy port>
答案 0 :(得分:0)
您必须将RestTemplate @Bean
声明为@LoadBalanced
@LoadBalanced
@Bean
RestTemplate restTemplate(){
return new RestTemplate();
}
您在@LoadBalanced
上有@Autowired RestTemplate
注解,什么也没做