Dalston
分布式/版本配置
服务注册和发现
路由
服务之间的调用
负载均衡
断路器Circuit Breaker
分布式消息
Cloud Native 应用
Cloud Native是一种应用开发方式,鼓励采用持续交付和价值驱动开发的实践。
使用声明编程并管理和监控。
启动应用程序上下文:
Spring Cloud通过一个启动上下文来进行操作,该上下文是主应用程序的父级上下文。
它负责从外部源加载配置属性,将属性解密到本地的外部配置文件里。
启动上下文和主程序上下文共享Environment环境变量类属性,Environment是所有Spring应用程序都使用的外部属性存储。
启动上下文获取的外部属性具备较高的优先级,所以默认情况下,本地定义的配置不能覆盖它。
bootstrap.yml
spring:
applicaiton:
name: foo
cloud:
config:
uri: ${SPRING_CONFIG_URI:http://localhost:8888}
如果我们应用程序需要任何应用程序特有的配置信息,则在bootstrap.yml或者主程序配置application.yml文件中设置spring.application.name是个好办法。
我们还可以通过在系统属性里设置spring.cloud.bootstrap.enabled=false 来关闭启动进程。
应用程序上下午的层级结构:
如果我们从SpringApplication或者SpringApplicationBuilder来创建一个应用程序上下文对象,那么启动上下文会自动被添加为它们的父对象。
子上下文会继承父上下文定义的属性源和描述,所以此时主程序的上下文会比没有Spring Cloud配置时多很多内容,这些内容包括:
1.bootstrap:一个可选的组合属性源CompositePropertySource,只要有任何PropertySourceLocators在启动上下文中存在,并且有非空的属性,则它都会具备较高的优先级。
2.applicationConfig:[classpath:bootstrap.yml]只要我们定义了该文件,那么它定义的属性都会被用来定义启动上下文,并且添加到它子上下文中。
Spring Cloud Commons:Common Abstractions
服务发现,负载平衡和断路器等模式被借用到通用抽象层,可以被所有的Spring Cloud 客户端消费使用。从而使其与具体实现分离。
比如服务发现,我们可以使用Eureka或者Consul实现。
@EnableDiscoveryClient
该标签会通过查找META-INF/spring.factories来获取DiscoveryClient接口的实现。
DiscoveryClient的实现会将一个配置类添加到spring.factories的org.springframework.cloud.client.discovery.EnableDiscoveryClient 键下面。
比如Spring Cloud Netflix Eureka,Spring Cloud Consul Discovery和Spring Cloud Zookeeper Discovery 等实现。
http://cloud.spring.io/spring-cloud-netflix/
http://cloud.spring.io/spring-cloud-consul/
http://cloud.spring.io/spring-cloud-zookeeper/
默认情况下,DiscoveryClient会自动注册本地Spring Boot服务到远程发现服务,我们可以通过在@EnableDiscoveryClient标签中设置autoRegister=false 来关闭。
ServiceRegistry:服务寄存器
该接口提供了register(Registration)和deregister(Registration)方法来为我们提供自定义注册服务。 Registration只是一个标记接口。
@Configuration
@EnableDiscoveryClient(autoRegister=false)
public class MyConfiguration{
private ServiceRegistry registry;
public MyConfiguration(ServiceRegistry registry){
this.registry = registry;
}
public void registry(){
Registration registration = constructRegistration();
this.registry.register(registration);
}
}
ServiceRegistry 自动注册
默认情况下,ServiceRegistry实现会自动注册运行的服务。
要关闭该行为,有两种方法:设置@EnableDiscoveryClient(autoRegister=false)
还可以通过设置spring.cloud.service-registry.auto-registration.enabled=false 配置项来完成。
服务注册的监控端点:
/service-registry ,该页面依赖于Spring应用程序上下文中的Registration bean。
通过调用/service-registry/instance-status会返回Registration的状态。
通过POST该URL可以为当前的Registration赋新值。
Spring RestTemplate 作为负载平衡客户端:
RestTemplate可以用ribbon自动配置。
要创建一个负载平衡的RestTemplate,只需要创建一个标记@Bean的 RestTemplate并添加@LoadBalanced标签即可。
@Configuration
public class MyConfiguration {
@LoadBalanced
@Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
}
调用RestTemplate
public class MyClass {
@Autowired
private RestTemplate restTemplate;
public String doOtherStuff() {
String results = restTemplate.getForObject("http://stores/stores", String.class);
return results;
}
}
这里的URI需要使用虚拟主机名(比如服务名,而不是真正的主机名)。
Ribbon客户端常用语创建一个完整的物理地址。
https://github.com/spring-cloud/spring-cloud-netflix/blob/master/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonAutoConfiguration.java
重试失败的请求:
一个实现负载平衡的RestTemplate可以配置重新获取失败请求。其默认情况下,该功能是关闭的。
我们可以在应用程序的类目录下添加Spring Retry(https://github.com/spring-projects/spring-retry)。
RestTemplate会受益于Ribbon的关于重新获取失败请求的配置值。
我们可以通过设置spring.cloud.loadbalancer.retry.enabled=false来关闭该功能。
我们可以使用client.ribbon.MaxAutoRetries,client.ribbon.MaxAutoRetriesNextServer和client.ribbon.OkToRetryOnAllOperations等属性对其进行配置。
https://github.com/Netflix/ribbon/wiki/Getting-Started#the-properties-file-sample-clientproperties
上面提到的client应该用我们的Ribbon client的name替换。
多RestTemplate对象:
如果我们不想使用负载平衡的RestTemplate直接正常创建相应的@Bean即可。要使用其负载平衡功能则需要添加@LoadBalanced标签。
可以使用@Primary来突出优选注入。
@Configuration
public class MyConfiguration {
@LoadBalanced
@Bean
RestTemplate loadBalanced() {
return new RestTemplate();
}
@Primary
@Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
}
public class MyClass {
@Autowired
private RestTemplate restTemplate;
@Autowired
@LoadBalanced
private RestTemplate loadBalanced;
public String doOtherStuff() {
return loadBalanced.getForObject("http://stores/stores", String.class);
}
public String doStuff() {
return restTemplate.getForObject("http://example.com", String.class);
}
}
忽略网络接口:
有时候忽略特定的命名网络接口可以使它们从服务发现注册中排除(比如运行在一个Docker容器中)。
我们可以设置一个正则表达式列表来排除不希望的网络接口。
下面例子的配置会忽略docker0 接口和所有以“veth”开头的网络接口。
application.yml
spring:
cloud:
inetutils:
ignoredInterfaces:
- docker0
- veth.*
我们还可以通过正则表达式来强制使用特定的网络地址
application.yml
spring:
cloud:
inetutils:
preferredNetworks:
- 192.168
- 10.0
还可以强制只是用一些本地地址:
application.yml
spring:
cloud:
inetutils:
useOnlySiteLocalInterfaces: true