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。这里是选取了第一个服务,负载均衡决定选择调用哪个服务。也可以模拟负载均衡。

posted @ 2023-03-25 13:25  shigp1  阅读(109)  评论(0编辑  收藏  举报