您的位置:首页 > 编程语言 > Java开发

Spring Cloud 学习笔记——入门、特征、配置

2017-09-19 16:08 726 查看


Spring Cloud 学习笔记(一)——入门、特征、配置

[TOC]


0 放在前面


0.1 参考文档

http://cloud.spring.io/spring-cloud-static/Brixton.SR7/
https://springcloud.cc/
http://projects.spring.io/spring-cloud/


0.2 maven配置

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
</dependencies>



0.3 简介

Spring Cloud为开发人员提供了快速构建分布式系统中的一些通用模式(例如配置管理,服务发现,断路器,智能路由,微代理,控制总线,一次性令牌,全局锁,领导选举,分布式 会话,群集状态)。 分布式系统的协调引出样板模式(boiler plate patterns),并且使用Spring Cloud开发人员可以快速地实现这些模式来启动服务和应用程序。 它们可以在任何分布式环境中正常工作,包括开发人员自己的笔记本电脑,裸机数据中心和受管平台,如Cloud
Foundry。
Version: Brixton.SR7


1 特征

Spring Cloud专注于为经典用例和扩展机制提供良好的开箱即用
分布式/版本配置
服务注册与发现
路由选择
服务调用
负载均衡
熔断机制
全局锁
领导人选举和集群状态
分布式消息


2 原生云应用程序

原生云是应用程序开发的一种风格,鼓励在持续交付和价值驱动领域的最佳实践。

Spring Cloud的很多特性是基于Spring Boot的。更多的是由两个库实现:Spring Cloud Context and Spring Cloud Commons。


2.1 Spring Cloud Context: 应用上下文服务

Spring Boot关于使用Spring构建应用有硬性规定:通用的配置文件在固定的位置,通用管理终端,监控任务。建立在这个基础上,Spring Cloud增加了一些额外的特性。


2.1.1 引导应用程序上下文

Spring Cloud会创建一个“bootstrap”的上下文,这是主应用程序的父上下文。对应的配置文件拥有最高优先级,并且,默认不能被本地配置文件覆盖。对应的文件名bootstrap.yml或bootstrap.properties。
可通过设置
spring.cloud.bootstrap.enabled=false
来禁止bootstrap进程。


2.1.2 应用上下文层级结构

当用
SpringApplication
SpringApplicationBuilder
创建应用程序上下文时,bootstrap上下文将作为父上下文被添加进去,子上下文将继承父上下文的属性。
子上下文的配置信息可覆盖父上下文的配置信息。


2.1.3 修改Bootstrap配置文件位置

spring.cloud.bootstrap.name
(默认是bootstrap),或者
spring.cloud.bootstrap.location
(默认是空)


2.1.4 覆盖远程配置文件的值

spring.cloud.config.allowOverride=true

spring.cloud.config.overrideNone=true

spring.cloud.config.overrideSystemProperties=false


2.1.5 定制Bootstrap配置

/META-INF/spring.factories
的key为
org.springframework.cloud.bootstrap.BootstrapConfiguration
,定义了Bootstrap启动的组件。
在主应用程序启动之前,一开始Bootstrap上下文创建在spring.factories文件中的组件,然后是
@Beans
类型的bean。


2.1.6 定制Bootstrap属性来源

关键点:spring.factories、PropertySourceLocator


2.1.7 环境改变

应用程序可通过
EnvironmentChangedEvent
监听应用程序并做出响应。


2.1.8 Refresh Scope

Spring的bean被@RefreshScope将做特殊处理,可用于刷新bean的配置信息。
注意
需要添加依赖“org.springframework.boot.spring-boot-starter-actuator”
目前我只在@Controller测试成功
需要自己发送POST请求
/refresh

修改配置文件即可


2.1.9 加密和解密

Spring Cloud可对配置文件的值进行加密。

如果有"Illegal key size"异常,那么需要安装JCE。


2.1.10 服务点

除了Spring Boot提供的服务点,Spring Cloud也提供了一些服务点用于管理,注意都是POST请求
/env
:更新
Environment
、重新绑定
@ConfigurationProperties
跟日志级别
/refresh
重新加载配置文件,刷新标记
@RefreshScope
的bean
/restart
重启应用,默认不可用
生命周期方法:
/pause
/resume


2.2 Spring Cloud Commons:通用抽象

服务发现、负载均衡、熔断机制这种模式为Spring Cloud客户端提供了一个通用的抽象层。


2.2.1 RestTemplate作为负载均衡客户端

通过
@Bean
@LoadBalanced
指定
RestTemplate
。注意URI需要使用虚拟域名(如服务名,不能用域名)。
如下:

@Configuration
public class MyConfiguration {

@LoadBalanced
@Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
}

public class MyClass {
@Autowired
private RestTemplate restTemplate;

public String doOtherStuff() {
String results = restTemplate.getForObject("http://stores/stores", String.class);
return results;
}
}



2.2.2 多个RestTemplate对象

注意
@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);
}
}



2.2.3 忽略网络接口

忽略确定名字的服务发现注册,支持正则表达式配置。


3 Spring Cloud Config

Spring Cloud Config提供服务端和客户端在分布式系统中扩展配置。支持不同环境的配置(开发、测试、生产)。使用Git做默认配置后端,可支持配置环境打版本标签。


3.1 快速开始

可通过IDE运行或maven运行。
默认加载property资源的策略是克隆一个git仓库(at spring.cloud.config.server.git.uri')。
HTTP服务资源的构成:
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties

application是SpringApplication的spring.config.name,(一般来说'application'是一个常规的Spring Boot应用),profile是一个active的profile(或者逗号分隔的属性列表),label是一个可选的git标签(默认为"master")。


3.1.1 客户端示例

创建以Spring Boot应用即可,添加依赖“org.springframework.cloud:spring-cloud-starter-config”。
配置application.properties,注意URL为配置服务端的地址
spring.cloud.config.uri: http://myconfigserver.com[/code] 


3.2 Spring Cloud Config 服务端

针对系统外的配置项(如name-value对或相同功能的YAML内容),该服务器提供了基于资源的HTTP接口。使用@EnableConfigServer注解,该服务器可以很容易的被嵌入到Spring
Boot 系统中。使用该注解之后该应用系统就是一个配置服务器。

@SpringBootApplication
@EnableConfigServer
public class ConfigApplicion {
public static void main(String[] args) throws Exception {
SpringApplication.run(ConfigApplicion.class, args);
}
}



3.2.1 资源库环境

{application} 对应客户端的"spring.application.name"属性
{profile} 对应客户端的 "spring.profiles.active"属性(逗号分隔的列表)
{label} 对应服务端属性,这个属性能标示一组配置文件的版本
如果配置库是基于文件的,服务器将从application.yml和foo.yml中创建一个
Environment
对象。高优先级的配置优先转成
Environment
对象中的
PropertySource


3.2.1.1 Git后端

默认的
EnvironmentRepository
是用Git后端进行实现的,Git后端对于管理升级和物理环境是很方便的,对审计配置变更也很方便。也可以
file:
前缀从本地配置库中读取数据。
这个配置库的实现通过映射HTTP资源的
{label}
参数作为git
label(提交id,分支名称或tag)。如果git分支或tag的名称包含一个斜杠 ("/"),此时HTTP URL中的label需要使用特殊字符串"(_)"来替代(为了避免与其他URL路径相互混淆)。如果使用了命令行客户端如 curl,请谨慎处理URL中的括号(例如:在shell下请使用引号''来转义它们)。
Git URI占位符

Spring Cloud Config Server支持git库URL中包含针对{application}和 {profile}的占位符(如果你需要,{label}也可包含占位符, 不过要牢记的是任何情况下label只指git的label)。所以,你可以很容易的支持“一个应用系统一个配置库”策略或“一个profile一个配置库”策略。
模式匹配和多资源库

spring:
cloud:
config:
server:
git:
uri: https://github.com/spring-cloud-samples/config-repo repos:
simple: https://github.com/simple/config-repo special:
pattern: special*/dev*,*special*/dev*
uri: https://github.com/special/config-repo local:
pattern: local*
uri: file:/home/configsvc/config-repo


如果 {application}/{profile}不能匹配任何表达式,那么将使用“spring.cloud.config.server.git.uri”对应的值。在上例子中,对于 "simple" 配置库, 匹配模式是simple/* (也就说,无论profile是什么,它只匹配application名称为“simple”的应用系统)。“local”库匹配所有application名称以“local”开头任何应用系统,不管profiles是什么(来实现覆盖因没有配置对profile的匹配规则,“/*”后缀会被自动的增加到任何的匹配表达式中)。
Git搜索路径中的占位符
spring.cloud.config.server.git.searchPaths

3.2.1.2 版本控制后端文件系统使用

伴随着版本控制系统作为后端(git、svn),文件都会被
check
out
clone
 到本地文件系统中。默认这些文件会被放置到以config-repo-为前缀的系统临时目录中。在Linux上,譬如应该是
/tmp/config-repo-<randomid>
目录。有些操作系统routinely
clean out放到临时目录中,这会导致不可预知的问题出现。为了避免这个问题,通过设置
spring.cloud.config.server.git.basedir
spring.cloud.config.server.svn.basedir
参数值为非系统临时目录。

3.2.1.3 文件系统后端

使用本地加载配置文件。

需要配置:
spring.cloud.config.server.native.searchLocations
spring.profiles.active=native


路径配置格式:
classpath:/,
classpath:/config,file:./, file:./config

3.2.1.4 共享配置给所有应用

基于文件的资源库

在基于文件的资源库中(i.e. git, svn and native),这样的文件名
application*
命名的资源在所有的客户端都是共享的(如
application.properties, application.yml, application-*.properties,etc.)。
属性覆盖

“spring.cloud.config.server.overrides”添加一个Map类型的name-value对来实现覆盖。

例如

spring:
cloud:
config:
server:
overrides:
foo: bar


会使所有的配置客户端应用程序读取foo=bar到他们自己配置参数中。


3.2.2 健康指示器

通过这个指示器能够检查已经配置的
EnvironmentRepository
是否正常运行。

通过设置
spring.cloud.config.server.health.enabled=false
参数来禁用健康指示器。


3.2.3 安全

你可以自由选择任何你觉得合理的方式来保护你的Config Server(从物理网络安全到OAuth2 令牌),同时使用Spring Security和Spring Boot 能使你做更多其他有用的事情。
为了使用默认的Spring Boot HTTP Basic 安全,只需要把Spring Security 增加到classpath中(如org.springframework.boot.spring-boot-starter-security)。默认的用户名是“user”,对应的会生成一个随机密码,这种情况在实际使用中并没有意义,一般建议配置一个密码(通过 security.user.password属性进行配置)并对这个密码进行加密。


3.2.4 加密与解密

如果远程属性包含加密内容(以{cipher}开头),这些值将在通过HTTP传递到客户端之前被解密。
使用略


3.2.5 密钥管理

配置服务可以使用对称(共享)密钥或者非对称密钥(RSA密钥对)。
使用略


3.2.6 创建一个测试密钥库


3.2.7 使用多密钥和循环密钥


3.2.8 加密属性服务


3.3 可替换格式服务

配置文件可加后缀".yml"、".yaml"、".properties"


3.4 文本解释服务

/{name}/{profile}/{label}/{path}


3.5 嵌入配置服务器

一般配置服务运行在单独的应用里面,只要使用注解
@EnableConfigServer
即可嵌入到其他应用。


3.6 推送通知和总线

添加依赖
spring-cloud-config-monitor
,激活Spring
Cloud 总线,
/monitor
端点即可用。
当webhook激活,针对应用程序可能已经变化了的,配置服务端将发送一个
RefreshRemoteApplicationEvent


3.7 客户端配置


3.7.1 配置第一次引导

通过
spring.cloud.config.uri
属性配置Config
Server地址


3.7.2 发现第一次引导

如果用的是Netflix,则用
eureka.client.serviceUrl.defaultZone
进行配置。


3.7.3 配置客户端快速失败

在一些例子里面,可能希望在没有连接配置服务端时直接启动失败。可通过
spring.cloud.config.failFast=true
进行配置。


3.7.4 配置客户端重试

添加依赖
spring-retry
spring-boot-starter-aop
,设置
spring.cloud.config.failFast=true
。默认的是6次重试,初始补偿间隔是1000ms,后续补偿为1.1指数乘数,可通过
spring.cloud.config.retry.*
配置进行修改。


3.7.5 定位远程配置资源

路径:
/{name}/{profile}/{label}

"name" = ${spring.application.name}
"profile" = ${spring.profiles.active} (actually Environment.getActiveProfiles())
"label" = "master"
label对于回滚到之前的版本很有用。


3.7.6 安全

通过
spring.cloud.config.password
spring.cloud.config.username
进行配置。

 


4 Spring Cloud Netflix

Spring Cloud 通过自动配置和绑定到Spring环境和其他Spring编程模型惯例,为Spring Boot应用程序提供Netflix OSS集成。 通过几个简单的注释,可以快速启用和配置应用程序中的常见功能模块,并使用久经考验的Netflix组件构建大型分布式系统。 提供的功能模块包括服务发现(Eureka),断路器(Hystrix),智能路由(Zuul)和客户端负载均衡(Ribbon)。


4.1 服务发现:Eureka客户端

服务发现是microservice基础架构的关键原则之一。Eureka是Netflix服务发现的一种服务和客户端。


4.1.1 注册到Eureka

当一个客户端注册到Eureka,它提供关于自己的元数据(诸如主机和端口,健康指标URL,首页等)Eureka通过一个服务从各个实例接收心跳信息。如果心跳接收失败超过配置的时间,实例将会正常从注册里面移除。

可以使用
@EnableEurekaClient
@EnableDiscoveryClient
注解。

配置
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
属性,注意修改URL地址。

确保
spring.application.name
有默认值。

注:
@EnableEurekaClient
只能用于Eureka,
@EnableDiscoveryClient
能用于zookeeper等其他注册组件。

@EnableEurekaClient
使其成为Eureka实例(被其他服务发现)和客户端(能发现其他服务)注册到应用里面。可通过
eureka.instance.*
进行相关配置的修改。


4.1.2 对Eureka服务的身份验证

如果其中一个
eureka.client.serviceUrl.defaultZone
的url已经把凭证嵌入到它里面,那么HTTP基本的身份验证将会被自动添加到你的eureka客户端(curl风格,如
http://user:password@localhost:8761/eureka
)。
对于更复杂的需求,可以创建一个带“@Bean”注解的“DiscoveryClientOptionalArgs”类型并且为它注入“ClientFilter”实例。


4.1.3 健康指标和状态页面

健康指标和状态页面分别对应一个Eureka实例的“/health”和“/info”。


4.1.4 注册一个安全应用

若要用HTTPS,需要设置两个标记,分别是
EurekaInstanceConfig
,即
eureka.instance.[nonSecurePortEnabled,securePortEnabled]=[false,true]


4.1.5 Eureka 健康检查

默认情况下,Eureka使用客户端心跳来确定一个客户端是否活着(状态为“UP”)。


4.1.6 Eureka给客户端和实例的元数据

有标准的元数据,如主机名、IP地址、端口号、状态页面和健康检查。额外的元数据可以被添加到实例注册在
eureka.instance.metadataMap
里面。

在 Cloudfoundry 使用 Eureka

Cloudfoundry有总的路由,所有在同个应用的实例有相同的主机名。

在AWS上使用Eureka

定制
EurekaInstanceConfigBean


修改Eureka实例ID

通过
eureka.instance.instanceId
进行配置。


4.1.7 使用EurekaClient

使用
@EnableDiscoveryClient
(或
@EnableEurekaClient
),使它从Eureka
Server发现服务实例。

注:不要在
@PostConstruct
方法或
@Scheduled
方法使用EurekaClient(或任何ApplicationContext还没被启动的地方)。


4.1.8 代替原生的Netflix EurekaClient

Spring Cloud已经支持Feign(一个REST客户端构建)跟Spring RestTemplate(使用逻辑Eureka服务标识符(VIPs)代替物理的URL)。


4.1.9 为什么注册一个服务这么慢?

实例默认与注册中心持续30秒的周期心跳(通过客户的
serviceUrl
)。当实例、服务端和客户端全都在它们的缓存里面拥有相同的元数据(这可能还需要3次心跳),那么服务对于客户端的discovery将变为不可用。可通过
eureka.instance.leaseRenewalIntervalInSeconds
这个修改配置,可以加快这一进程的客户端连接到其他服务。


4.2 服务发现: Eureka Server

例子,添加依赖
spring-cloud-starter-eureka-server


@SpringBootApplication
@EnableEurekaServer
public class Application {
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).web(true).run(args);
}
}


服务端有一个带UI的首页,HTTP API端点在
/eureka/*
下提供标准的Eureka功能。


4.2.1 高可用

Eureka服务端没有后台存储,但是服务实例在注册里面全都得发送心跳去保持注册更新(在内存里操作)客户端们也有一份内存缓存着eureka的注册信息。


4.2.2 标准模式

eureka.client.registerWithEureka=false
eureka.client.fetchRegistry=false
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/


4.2.3 节点感知

运行多个Eureka Servers。

Eureka甚至可以更有弹性和可用的运行多个实例,并让他们互相注册。事实上,这也是默认的行为,因此所有你需要让它工作的,只要添加一个有效的节点serviceUrl,例如:

---
spring:
profiles: peer1
eureka:
instance:
hostname: peer1
client:
serviceUrl:
defaultZone: http://peer2/eureka/ 
---
spring:
profiles: peer2
eureka:
instance:
hostname: peer2
client:
serviceUrl:
defaultZone: http://peer1/eureka/[/code] 
然后通过不同的“profile”进行运行不同的Eureka Server。


4.2.4 IP偏好

设置
eureka.instance.preferIpAddress=true
使应用注册到eureka的是IP地址而不是主机名。


4.3 断路器:Hystrix

Netflix创建了一个库实现断路器模式,名为Hystrix。一个低水平的服务群中一个服务挂掉会给用户导致级联失效的。当调用一个特定的服务达到一定阈值(在Hystrix里默认是5秒内20个失败),断路器开启并且调用没有成功的。开发人员能够提供错误原因和开启一个断路由回调。

例子,需添加依赖
org.springframework.cloud.spring-cloud-starter-hystrix


@SpringBootApplication
@EnableCircuitBreaker
public class Application {

public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).web(true).run(args);
}

}

@Component
public class StoreIntegration {

@HystrixCommand(fallbackMethod = "defaultStores")
public Object getStores(Map<String, Object> parameters) {
//do stuff that might fail
}

public Object defaultStores(Map<String, Object> parameters) {
return /* something useful */;
}
}


经测试,失败就直接调用defaultStores()方法了。


4.3.1 传播安全上下文或使用 Spring Scopes

如果你想一些线程的本地的上下文传播到一个@HystrixCommand,默认声明将不会工作,因为他在线程池里执行命令。(在超时的情况下)。你可以切换Hystrix去使用同个线程让调用者使用一些配置,或直接在注解中,让它去使用不同的“隔离策略”。举例:

@HystrixCommand(fallbackMethod = "stubMyService",
commandProperties = {
@HystrixProperty(name="execution.isolation.strategy", value="SEMAPHORE")
}
)
...


如果你使用
@SessionScope
@RequestScope
同样适用。你会知道你要这么做,因为一个runtime异常说他不能找到作用域上下文。


4.3.2 健康指标

连接的断路器的状态也暴露在应用程序的
/health
端点中。


4.3.3 Hystrix 指标流

添加依赖
org.springframework.boot.spring-boot-starter-actuator
,使
/hystrix.stream
流作为一个管理端点。


4.4 断路器: Hystrix仪表盘

Hystrix的主要作用是会采集每一个HystrixCommand的信息指标,把每一个断路器的信息指标显示的Hystrix仪表盘上。

环境需要
添加依赖
org.springframework.cloud.spring-cloud-starter-hystrix-dashboard

主类上注解
@EnableHystrixDashboard

访问
/hystrix

填写链接
http://host:port/hystrix.stream


4.4.1 Turbine



4.4.2 Turbine Stream



4.5 客户端负载均衡器:Ribbon

Ribbon是一个客户端负载均衡器,有很多控制HTTP和TCP客户端的行为,可使用
@FeignClient
注解。


4.5.1 自定义Ribbon客户端



4.5.2 在Eureka中使用Ribbon



4.5.3 示例: 没有Eureka时如何使用Ribbon



4.5.4 示例:禁用Eureka使用Ribbon



4.5.5 直接使用Ribbon的API

public class MyClass {
@Autowired
private LoadBalancerClient loadBalancer;

public void doStuff() {
ServiceInstance instance = loadBalancer.choose("stores");
URI storesUri = URI.create(String.format("http://%s:%s", instance.getHost(), instance.getPort()));
// ... do something with the URI
}
}



4.6 声明REST客户端:Feign



4.7 外部配置:Archaius



4.8 路由和过滤器:Zuul

Zuul是Netflix出品的一个基于JVM路由和服务端的负载均衡器。
认证
Insights
压力测试
金丝雀测试(Canary Testing)
动态路由
服务迁移
负载削减
安全
静态响应处理
主动/主动交换管理


4.8.1 嵌入Zuul反向代理

Spring Cloud创建了一个嵌入式Zuul代理来缓和急需一个UI应用程序来代理调用一个或多个后端服务的通用需求,这个功能对于代理前端需要访问的后端服务非常有用,避免了所有后端服务需要关心管理CORS和认证的问题。



在Spring Boot主函数上通过注解
@EnableZuulProxy
来开启。


4.8.2 Cookies和敏感HTTP头


4.8.3 路由Endpoint

使用
@EnableZuulProxy
同时引入了Spring
Boot Actuator,默认将增加一个endpoint,提供http服务的
/routes


4.8.4 窒息模式和本地跳转

逐步替代旧的接口是一种通用的迁移现有应用程序或者API的方式,使用不同的具体实现逐步替换它们。Zuul代理是一种很有用的工具,因为你可以使用这种方式处理所有客户端到旧接口的请求。只是重定向了一些请求到新的接口。


4.8.5 通过Zuul上传文件


4.8.6 简单的嵌入Zuul


4.8.7 关闭Zuul过滤器


4.8.8 通过Sidecar进行多语言支持


4.9 RxJava with Spring MVC

Spring Cloud Netflix 包含 RxJava。

Spring Cloud Netflix提供并支持从Spring MVC Controllers返回
rx.Single
对象,还支持使用
rx.Observable
对象。


4.10 指标:Spectator, Servo, and Atlas

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: