问题
I have written a spring boot micro-service and a REST client. The client is a part of another module and make RESTful calls to the micro-service. The micro-service registers with the Eureka registry and I want my client (Which is not a spring boot project) to use the Eureka to query and get the service endpoints.
My problem is since the client is not a Spring-Boot applications I can not use the annotations like @SpringBootApplication
, @EnableDiscoveryClient
and the DiscoveryClient
is not get auto wired to the application. Is there anyway to manually auto-wire the DiscoveryClient
bean to the client without using the annotations ?
回答1:
Well this is how I did It. Basically it is a lot easier than I anticipated. The following was copied from Netflix eureka project.
DiscoveryManager.getInstance().initComponent(new MyDataCenterInstanceConfig(), new DefaultEurekaClientConfig());
String vipAddress = "MY-SERVICE";
InstanceInfo nextServerInfo = null;
try {
nextServerInfo = DiscoveryManager.getInstance()
.getEurekaClient()
.getNextServerFromEureka(vipAddress, false);
} catch (Exception e) {
System.err.println("Cannot get an instance of example service to talk to from eureka");
System.exit(-1);
}
System.out.println("Found an instance of example service to talk to from eureka: "
+ nextServerInfo.getVIPAddress() + ":" + nextServerInfo.getPort());
System.out.println("healthCheckUrl: " + nextServerInfo.getHealthCheckUrl());
System.out.println("override: " + nextServerInfo.getOverriddenStatus());
System.out.println("Server Host Name "+ nextServerInfo.getHostName() + " at port " + nextServerInfo.getPort() );
Also you have to add a configuration file to the class path. Eureka client uses this file to read the information about the eureka servers.
eureka.preferSameZone=true
eureka.shouldUseDns=false
eureka.serviceUrl.default=http://localhost:8761/eureka/
eureka.decoderName=JacksonJson
Also you have to provide the eureka client as a dependency. Eureka1 supports JDK7 though some part of it has been built with JDK8. However I had to provide older versions of "archaius-core" and "servo-core" to make it run with JDK7.
<dependency>
<groupId>com.netflix.archaius</groupId>
<artifactId>archaius-core</artifactId>
<version>0.7.3</version>
</dependency>
<dependency>
<groupId>com.netflix.servo</groupId>
<artifactId>servo-core</artifactId>
<version>0.10.0</version>
</dependency>
Eureka2 fully supports JDK7.
回答2:
Either you use the netflix-eureka-client without spring-cloud and have to configure all by yourself (which means duplicating EurekaDiscoveryClientConfiguration)
Or you could run a sidecar service. The sidecar includes a zuul-proxy which would proxy the services discovered by eureka. Have a look int the Spring Cloud Docs - Polyglot support with Sidecar
回答3:
Wish accessing Eureka from legacy spring ( non-boot ) is also made simple like @EnableEureka and @EnableFeignClient
This is the closest I could get it working . This example is available in Eureka-examples in Git Hub
public class EurekaConfiguration {
private static ApplicationInfoManager applicationInfoManager;
private static EurekaClient eurekaClient;
private static synchronized ApplicationInfoManager initializeApplicationInfoManager(
EurekaInstanceConfig instanceConfig) {
if (applicationInfoManager == null) {
InstanceInfo instanceInfo = new EurekaConfigBasedInstanceInfoProvider(instanceConfig).get();
applicationInfoManager = new ApplicationInfoManager(instanceConfig, instanceInfo);
}
return applicationInfoManager;
}
private static synchronized EurekaClient initializeEurekaClient(ApplicationInfoManager applicationInfoManager,
EurekaClientConfig clientConfig) {
if (eurekaClient == null) {
eurekaClient = new DiscoveryClient(applicationInfoManager, clientConfig);
}
return eurekaClient;
}
public static EurekaClient getEurekaClient()
{
ApplicationInfoManager applicationInfoManager = initializeApplicationInfoManager(new MyDataCenterInstanceConfig());
EurekaClient client = initializeEurekaClient(applicationInfoManager, new DefaultEurekaClientConfig());
return eurekaClient;
}
}
My client
String vipAddress = "NLPService";
InstanceInfo nextServerInfo = null;
try {
nextServerInfo = EurekaConfiguration.getEurekaClient().getNextServerFromEureka(vipAddress, false);
} catch (Exception e) {
System.err.println("Cannot get an instance of example service to talk to from eureka");
System.exit(-1);
}
System.out.println("Found an instance of example service to talk to from eureka: "
+ nextServerInfo.getVIPAddress() + ":" + nextServerInfo.getPort());
String serviceBaseURL = "http://"+ nextServerInfo.getHostName()
+":"+nextServerInfo.getPort();
String nlpServiceURL = serviceBaseURL +"/nlp";
RestTemplate restTemplate = new RestTemplate();
NLPInputToBeTransformed input = new NLPInputToBeTransformed();
input.setInputText(" Test Input ");
NLPResponse nlpResponse = restTemplate.postForObject
(nlpServiceURL, input, NLPResponse.class, new HashMap<>());
System.out.println( " Service Response " + nlpResponse.getTags());
来源:https://stackoverflow.com/questions/35409492/eureka-service-discovery-without-spring-boot