DiscoveryClient
springCloud提供的DiscoveryClient接口,抽象了服务发现的功能,只要实现了这个接口就能接入SpringCloud的体系中。
org.springframework.cloud.client.discovery.DiscoveryClient
public interface DiscoveryClient extends Ordered {
/**
* Default order of the discovery client.
*/
int DEFAULT_ORDER = 0;
/**
* A human-readable description of the implementation, used in HealthIndicator.
* @return The description.
*/
String description();
/**
* Gets all ServiceInstances associated with a particular serviceId.
* @param serviceId The serviceId to query.
* @return A List of ServiceInstance.
*/
List<ServiceInstance> getInstances(String serviceId);
/**
* @return All known service IDs.
*/
List<String> getServices();
/**
* Can be used to verify the client is valid and able to make calls.
* <p>
* A successful invocation with no exception thrown implies the client is able to make
* calls.
* <p>
* The default implementation simply calls {@link #getServices()} - client
* implementations can override with a lighter weight operation if they choose to.
*/
default void probe() {
getServices();
}
/**
* Default implementation for getting order of discovery clients.
* @return order
*/
@Override
default int getOrder() {
return DEFAULT_ORDER;
}
}
getServices()从服务器获取服务列表,getInstances(String serviceId)通过服务id获取具体服务。
Producer作为服务提供者,新建Controller添加:
@RequestMapping("/hello")
public String hello() {
return "hello," + port;
}
作为服务。
新建Consumer模块作为消费者,和Producer相同,只是配置的端口和spring.application.name不同,Consumer的application.properties:
server.port=8001
spring.application.name=consumer
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
在Consumer新建MyController类处理请求。并自动注入SpringCloud提供的DiscoveryClient。
@RequestMapping("/serviceList")
public List<String> serviceList() {
return discoveryClient.getServices();
}
访问http://localhost:8001/serviceList,看到返回的服务列表:
@RequestMapping("/getInstances")
public List<ServiceInstance> getInstances() {
return discoveryClient.getInstances("producer");
}
访问http://localhost:8001/getInstances,看到:
可以看到具体的服务信息,比如ip地址,主机,端口,scheme,等,还有元数据metadata等。有了这些信息就可以调用服务了。还需要准备远程调用的工具,这里选用RestTemplate。增加bean:
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
以上的Bean要放在配置类中并加@Configuration注解。
现在获取服务并调用服务:
@RequestMapping("/client1")
public String client1() {
List<ServiceInstance> producer = discoveryClient.getInstances("producer");
if (producer != null && !producer.isEmpty()) {
ServiceInstance serviceInstance = producer.get(0);
String url = serviceInstance.getScheme()+"://"+serviceInstance.getHost()+":"+ serviceInstance.getPort();
String forObject = restTemplate.getForObject(url + "/hello", String.class);
return forObject;
}
return null;
}
访问http://localhost:8001/client1,可以看到hello,8000。这里是选取了第一个服务,负载均衡决定选择调用哪个服务。也可以模拟负载均衡。