Spring Cloud Commons 主要包括如下模块的接口和默认实现:

其中的限流策略以及重试策略是没有天然带的,但是其他模块的实现一般会带上这些功能。我们先从服务发现相关接口开始分析
服务发现相关
核心接口DiscoveryClient
DiscoveryClient
public interface DiscoveryClient extends Ordered {
int DEFAULT_ORDER = 0;
//描述
String description();
//通过 serviceId 获取服务实例
List<ServiceInstance> getInstances(String serviceId);
//获取所有服务的名称
List<String> getServices();
@Override
default int getOrder() {
return DEFAULT_ORDER;
}
}
DiscoveryClient 扩展了 Ordered
接口,这个和之前提到的@Order
注解的作用是一样的。
服务实例的信息包括:

public interface ServiceInstance {
//实例id,并不是必须的
default String getInstanceId() {
return null;
}
//服务id,用于区分不同微服务
String getServiceId();
//服务实例提供服务的地址
String getHost();
//服务实例提供服务的端口
int getPort();
//是否使用的是 HTTPS
boolean isSecure();
//提供服务的 URI 地址
URI getUri();
//一些元数据信息
Map<String, String> getMetadata();
//使用的传输协议,例如 http,https 等等
default String getScheme() {
return null;
}
}
Spring Cloud 从 Feinchley 版本之后,越来越重视异步 Reactor 编程与 WebFlux,所以所有同步的接口基本上都有对应的异步接口,这里的DiscoveryClient
对应的就是ReactiveDiscoveryClient
:
public interface ReactiveDiscoveryClient extends Ordered {
int DEFAULT_ORDER = 0;
//描述
String description();
//通过 serviceId 获取服务实例,这里返回的是 Flux,究竟如何使用会在后面的例子中详细阐明
Flux<ServiceInstance> getInstances(String serviceId);
//获取所有服务的名称,这里返回的是 Flux,究竟如何使用会在后面的例子中详细阐明
Flux<String> getServices();
@Override
default int getOrder() {
return 0;
}
}
如何通过配置文件配置服务实例?
使用 SimpleDiscoveryClient
与 SimpleReactiveDiscoveryClient
假设要调用的微服务的域名是固定的,我们可以直接通过将这些域名写入配置文件。这个场景一般发生在:
- 基于 Kubernetes ingress nginx 与 coredns 的内网域名解析负载均衡
- 外网统一提供服务的域名
我们通过一个例子来说明下 SimpleDiscoveryClient
与 SimpleReactiveDiscoveryClient
,这里的代码可以从这里下载,首先引入依赖:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.1</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2020.0.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
编写application.yml
,这里列举了SimpleDiscoveryClient
与SimpleReactiveDiscoveryClient
所有可能的配置:
spring:
cloud:
discovery:
client:
# SimpleDiscoveryClient与SimpleReactiveDiscoveryClient的配置
simple:
instances:
#微服务1
service1:
#实例1
- host: instance1 #地址
port: 8080 #端口
instanceId: 'instance1:8080' #可以不填,实例id
#实例2
- uri: 'https://instance2:443' #指定了 scheme 为 https,host 为 instance2,端口为443
#微服务2
service2:
#实例3
- host: instance3 #地址
port: 80 #端口
instanceId: ${spring.cloud.discovery.client.simple.instances.service2[0].host}:${spring.cloud.discovery.client.simple.instances.service2[0].port} #可以不填,实例id
#实例4
- uri: 'https://instance4:8080' #指定了 scheme 为 https,host 为 instance4,端口为8080
# 指定 SimpleDiscoveryClient的排序顺序为1,默认是0,越小越优先
order: 1
# actuator 配置
management:
endpoint:
health:
# health 接口总是输出详细信息
show-details: always
endpoints:
jmx:
exposure:
# jmx 不暴露任何 actuator 接口
exclude: '*'
web:
exposure:
# http 暴露所有 actuator 接口
include: '*'
我们配置了四个不同实例:
