SpringCloud 知识整理

SpringCloud 知识点梳理

第二章 构建spring cloud

SpringBoot目录结构

  • src/main/java:主程序入口

  • src/main/resources:配置目录

  • src/test:单元测试目录

Springboot依赖

Starter POMs 是一系列轻便的依赖包,是一套一站式的Spring相关技术的解决方案。

SpringBoot的StarterPOMs采用 spring-boot-starter-*命名,*表示一个特别的功能模块。

我们用到的POMs有:

  • spring-boot-starter-web:全栈Web开发模块

  • spring-boot-starter-test:通用测试模块

配置详解

springboot 的默认配置文件位置为 src/main/resources/application.properties

自定义参数

在application.yaml中

1
2
3
book:
name: springboot
author: charles

在java中

1
2
3
4
5
6
@Component
@Data
public class Book{
@Value("${book.name})
private String name;
}

@value 属性在加载配置时支持两种表达式:

  • PlaceHolder方式,格式如上,为${*}

  • SpEL表达式,格式为#{*}

多环境配置

多环境配置的文件名需要满足 application-{profiles}.yaml的格式,其中profile对应你的环境表示:

  • dev:开发

  • test:测试

  • prod:生产

加载那个环境需要在application.yaml中设置spring.profile.active=*属性

加载顺序

springboot属性加载顺序如下:

  1. 在命令行中传入的参数。

  2. SPRING APPLICATION JSON中的属性。SPRING APPIATION JSON是以JSON格式配置在系统环境变量中的内容

  3. Java.comp/env中的JNDI属性

  4. Java的系统属性,可以通过System.getProperties ()获得的内容

  5. 操作系统的环境变量

  6. 通过random.*配置的随机属性

  7. 位于当前应用 jar包之外,针对不同{profile}环境的配置文件内容,例如application- {profile} .properties或是YAML定义的配置文件。

  8. 位于当前应用jar包之内,针对不同{profile}环境的配置文件内容,例如aplication- {profilel} .properties 或是YAML定义的配置文件。

  9. 位于当前应用jar包之外的application.properties和YAML配置内容

  10. 位于当前应用jar包之内的application. properties和YAML配置内容。

  11. @Configuration注解修改的类中,通过@PropertySource 注解定义的属性。

  12. 应用默认属性,使用SpringApplication setDefautProperties定义的内容

优先级按上面的顺序由高到低

actuator

要想使用actuator需要添加依赖:spring-boot-starter-actuator,然后在application添加如下配置以暴露全部端点:

1
2
3
4
5
management:
endpotints:
web:
exposure:
include: '*'

actuator的原生断点分为三类:

  • 应用配置类

    • /beans:获取上下文所有的Bean,每个Bean都包含以下信息

      • scope:作用域

      • type:java类型

      • resource:class文件的具体路径

      • dependencies:依赖的bean的名称

    • /configprops:配置属性

      • profix:属性前缀

      • properties:各个属性的名称和值

    • /env:用来获取应用所有可用的环境属性报告

    • /mapping:用来返回所有springMVC控制器的映射关系

  • 度量指标类

    • /metrics:返回当前应用的各种重要指标

    • /health:用来获取应用的各类健康指标信息,当项目较为简单时,只标识出应用的状态

      • UNKNOWN:未知状态,503

      • UP:正常,200

      • DOWN:失败,503

      • OUT_OF_SERVICE:不提供对外服务,200

  • 操作控制类

    • /shutdown:只提供了这一个,不支持get请求

第三章 服务治理 Alibaba Nacos

常见方案

Spring Cloud Eureka:既包含了服务端组件,又包含了客户端组件,并且服务端与客户端均通过java编写

zookeeper:一个开源的分布式应用程序协调服务,是Chubby的一个开源实现,是Hadoop和Hbase的重要组件

Consul:所以一个服务网络的解决方案,他是一个分布式的高可用的系统,而且开发使用都很简便。它提供了一个功能齐全的控制平面,它的主要特点是:服务发现、健康检查、键值存储、安全服务通信、多数据中心

Nacos:帮助发现、配置和管理微服务

Nacos

修改端口:默认端口8848,可以进入nacos/conf目录修改application.propertoesserver.port属性

启动:运行startup.cmd -m standalone(单例模式运行)

访问:默认账号密码都是nacos

注册服务提供者

1
2
3
4
5
6
spring:
application:
name: #要注册到注册中心的服务名称
cloud:
nacos:
server-addr: localhost:8848 #服务端地址

服务发现与消费

1
2
3
4
5
@Bean
@LoadBalanced
public RestTemplete restTemplete(){
// ...
}

第四章 负载均衡 Ribbon

SpringCloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,他基于Netflix Ribbon实现。

虽然它只是一个工具类框架,不像服务注册中心、配置中心、API网关那样需要独立部署,但是它几乎存在在每一个SpringCloud构建的微服务和基础设施中。

客户端负载均衡与服务端负载均衡最大的不同点在于服务清单所存储的位置。

  • 服务提供者只需要启动多个服务实例并注册到一个注册中心或是多个相关联的服务注册中心

  • 服务消费者直接通过调用被@LoadBalanced注解修饰过的RestTemplate来实现面向服务的接口调用

分析

负载均衡器应该具备这样几种能力:

  • ServiceInstance choose(String serviceId):根据传入的服务名从负载均衡器中挑选一个对应服务的实例

  • T excute(String serviceId, LoadBalancerRequest request):使用从负载均衡器中挑选出的服务实例来执行请求内容

  • URI reconstuctURI(ServiceInstance instance, URI origianl):为系统构建合适的hostzport形式的URI

负载均衡器

  • AbstractLoadBalancer 是 ILoadBanlancer 接口的抽象实现,在该抽象类中定义了一个关于服务实例的分组枚举类ServerGroup

  • BaseLoadBalancer 是 Ribbon负载均衡器的基础实现类

  • DynamicServerListLoadBalancer类是继承于BaseLoadBalancer类,他是对基础负载均衡器的扩展

  • ZoneAwareLoadBalancer 负载均衡器是对 DynamicServerListLoadBalancer的扩展

负载均衡策略

  • AbstractLoadBalancerRule,负载均衡器策略抽象类,在该抽象类中定义了负载均衡器ILoadBalancer对象

  • ClientConfigEnabledRoundRobinRule,该策略较为特殊,一般不直接使用它,因为它本身并没有实现什么特殊的处理逻辑,他在内部定义了一个RoundRobinRule策略

  • PredicateBaseRule,是一个抽象策略,继承了ClientConfigEnabledRoundRobinRule,从其命名中可以看出来这个一个基于Predicate实现的策略

内置负载均衡规则类规则描述
RoundRobinRule简单轮询服务列表来选择服务器。它是Rbbon默认的负载均衡规则。
AvailabilityFilteringRule对以下两种服务器进行忽略: (1) 在默认情况下,这台服务器如果3次连接失败,这台服务器就会被设置为短路”状态。短路状态将持续30秒,如果再次连接失败,短路的持续时间就会几何级地增加。(2) 并发数过高的服务器。如果一个服务器的并发连接数过高,配置了AvailabiliyFilteringRule规则的客户端也会将其忽略。
WeightedResponseTimeRule为每一个服务器赋予一个权重值。 服务器响应时间越长,这个服务器的权重就越小。这个规则会随机选择服务器,这个权重值会影响服务器的选择。
ZoneAvoidanceRule以区域可用的服务器为基础进行服务器的选择。使用Zone对服务器进行分类,这个Zome可以理解为个机房、一个机架等。而后再对Zome内的多个服务做轮询
BestvailableRule忽略那些短路的服务器,并选择并发数较低的服务器。
RandomRule随机选择一个可用的服务器
RetryRule重试机制的选择逻辑
NacosRule支持优先调用同个集群实例的 rbbon负载均衡规则

配置详解

自动化配置

Ribbon能够自动配置下面这些接口的实现

  • IClientConfig: Ribon的客户端配置, 默认采用com.netflix.client.config.DefaultlCientCnfigimpl实现

  • IRule: Ribbon的负载均衡策略,默认采用com.netflix.loadbalancer,ZoneAvoidanceRule实现,该策略能够在多区域环境下选出最佳区域的实例进行访问。

  • IPing: Ribbon的实例检查策略,默认采用com.netfix.loadbalancer.DummyPing实现,该检查策略是一个特殊的实现,实际上它并不会检查实例是否可用,而是始终返回true,默认认为所有服上面务实例都是可用的。

  • ServerList: 服务实例清单的维护机制,默认采用com.netfix.loadbalancer.ConfigurationBasedServerList实现。

  • ServerListFilter: 服务实例清单过滤机制,默认采用org.springrameworkcloud.netflix.ribbon.ZomeAwareKiadBakabcer实现,该策略能够优先过滤出与请求调用方处于同区域的服务实例。

  • lLoadBalancer: 负载均衡器,默认采用com.netflix.loadbalancer.ZoneAwareloadBalancer实现,它具备了区域感知的能力。

针对一些个性化需求可以在springboot中创建对应的实现实例即可覆盖默认配置,比如

1
2
3
4
@Bean
public Irule rule(){
return new NacosRule();
}

参数配置

对于RIbbon的配置有两种:

  • 全局配置:使用ribbon.<key> = <value>格式进行配置

  • 指定客户端配置:<client>.ribbon.<key>=<value>的格式进行配置

IRule配置

1
2
3
userservice:
ribbon:
NFLoadBalancerRuleClassName: <value> # 负载均衡规则类全名

饥饿加载

1
2
3
4
5
ribbon:
eager-load:
enabled:true
client:
- userservice

与Nacos结合

1
2
3
4
5
6
7
8
spring:
application:
name: userservice #服务名称
cloud:
nacos:
server-addr: <value> #服务端地址
discovery:
cluster-name: <value> # 区域集群名称

重试机制

1
2
3
4
5
6
7
userservice:
ribbon:
ConnectTimeout: 200 #链接超时时间
ReadTimeout: 200 #请求超时时间
OkToRetryOnAllOperations: true #是否对所有操作都允许重试
MaxAutoRetriesNextServer: 2 # 切换实例的重试次数
MaxAutoRetries: 1 # 当前实例的重试次数

第五章 服务容错保护 Hystrix

快速入门:

1
@EnableCircuitBreaker //启动断路器

分析

命令执行

  • execute() 同步执行,从依赖的服务返回个单一的结果对象,或是在发生错误的时候抛出异常

  • queue() 异步执行, 直接返回一个Future对象,其中包含了服务执行结束时要返回单一结果对象。

  • observe() 返回来自依赖项的响应的Observable对象,它代表了操作的多个结果,它是一个hot Observable

  • toObservable() 同样会返回 Observable 对象,也代表了操作的多个结果,但它返回的是一个cold Observable。

断路器是否打开

  • 如果断路器是打开的,那么Hystrix不会执行命令,而是转到fallback处理逻辑

  • 如果断路器关闭,则会检测是否有可用资源执行命令

请求方法

  • HystrixCommand.run() 返回一个单一的结果或抛出异常

  • HystrixObservableCommand,constuct() 返回一个Observable 对象来发射多个结果或通过 onError 发送错误通知

计算断路器健康度

Hystrix会将 成功 、 失败 、 拒绝 、 超时等信息报告给断路器

fallback处理

  • execute() : 抛出异常。

  • queue(): 正常返回Future对象,但是当调用get 0来获取结果的时候会抛出异常。

  • observe(): 正常返回Observable 对象,当订阅它的时候,将立即通过调用订阅者的onError方法来通知中止请求。

  • tobservable(): 正常返回Obsevable对象,当订阅它的时候, 将通过调用订阅者的onError方法来通知中止请求。

成功的响应

  • exeoute() 以与queue 相同的方式获取一个Future,然后在这个Future 上调用get()获取由Observable发出的单个值

  • queue() 将Obervable转换为一个BlockingObservable,以便它可以被转换为一个Future然后返回这个Future

  • observe () 在toObservable()产生原始Observable 之后立即订阅它,让命令能够马上开始异步执行,井返回一个 Observable对象,当调用它的subscribe时,将重新产生结果和通知给订阅者。

  • toObservable() 返回最原始的Observable,必须通过订阅它才会真正触发命令的执行流程。

断路器

三个抽象方法:

  • allowRequest():每个Hystrix的命令的请求都通过他去判断是否被执行

  • isOpen():返回当前断路器是否打开

  • markSuccess():闭合断路器

创建请求命令

1
2
3
4
5
6
@GetMapping("/{param}")
@HystrixCommand(fallbackMethod = "showAppInfoFallback")
public String showAppInfo(@PathVariable("param") String params){
String url = "...";
return restTemplate.getForObject(url,String.class);
}

定义服务降级

1
2
3
public String showAppInfoFallback(String param){
return "busy";
}
1
2
3
4
5
6
7
/**
* 服务降级方法
*/
@HystrixCommand(fallbackMethod = "showAppInfoCallback")
public String ShowAppInfoFallback(String param){
...
}

异常获取

注解配置方式的实现非常简单,只需要fallback实现方法的参数中增加Throwable对象的定义,这样在方法内部就可以获取除法服务降级的具体异常内容了

1
2
3
public String showAppInfoFallBack(String param,Throwable exception){
// ...something
}

@Hystrix注解

1
2
3
4
5
6
@HystrixCommand(fallbackMethod = "..."
ignoreException = {Exception.class}
commandKey = "..."
groupKey = "..."
threadPoolKey = "..."
                )

请求缓存

注解描述属性
@CacheResult该注解用来标记请求命令返回的结果cacheKeyMethod应该被缓存,它必须与@HystrixCommand注解结合使用cacheKeyMethod
@CacheRemove该注解用来让请求命令的缓存失效,失效的缓存根据定义的Key决定commandKey,cacheKeyMethod
@CacheKey该注解用来在请求命令的参数上标记,使其作为缓存的Key值,如果没有标注则会使用所有参数。如果同时还使用了@CacheResult和@CacheRemove注解的cacheKeyMethod方法指定缓存Key的生成,那么该注解将不会起作用value

设置请求缓存

1
@CacheResult

定义一个filter

1
HystrixRequestContext context = HystrixRequestContext.initializeContext();

定义缓存key

1
2
3
4
5
6
7
8
9
@HystrixCommand(fallbackMethod = "showAppInfoCallback")
@CacheResult(CacheKeyMethod = "cacheKey")
public User getUserInfo(@PathVariable("id") @CacheKey String id){
// something
}

public String cacheKey(String id){
return id;
}

缓存清理

@CacheRemove注解的commandKey属性是必须要指定的,它用来指明需要使用请求缓存的请求命令,因为只有通过该属性的配置,Hystrix才能知道正确的请求命令缓存位置、

注解请求合并

@HystrixCollapser

请求合并的额外开销

  • 请求命令本身的延迟

  • 延迟时间窗内的并发量

属性详解

4个不同优先级别的配置(优先级由低到高):

  • 全局数认值:如果没有设置下面三个级别的属性,那么这个属性就是默认值。由于该属性通过代码定义,所以对于这个级别,我们主要关注它在代码中定义的默认值即可。

  • 全同配置属性:通过在配置文件中定义全局属性值,在应用启动时或在与SpringCloud Comfig和Spring Cloud Bus实现的动态刷新配置功能配合下,可以实现对“全局默认值”的覆盖以及在运行期对“全局默认值”的动态调整

  • 实例默认值。通过代码为实例定义的默认值。通过代码的方式为实例设置属性值来覆盖默认的全同配置。

  • 实例配置属性。通过配置文件来为指定的实例进行属性配置,以覆盖前面的三个默认值

Command属性

属性级别默认值、配置方式、配置属性
全局默认值THRAD
全局配置属性Hystrix.command.default.execution.isolation.strategy
实例默认值可通过@HystrixProperty(name = “excution.isolation.strategy” value = “THREAD”)
实例配置属性hystrix.command.HystrixCommandKey.execution.isolation.strategy

Hystrix 仪表盘

为启动类加上@EnableHystrixDashboard, 启用Hystrix DashBoard功能

Hystrix DashBoard 支持三种不同的监控方式,分别是:

  • 默认的集群监控,通过URL http://hostname:port/turbine.stream开启

  • 指定的集群监控,通过URL http://hostname:port/turbine.stream?cluster=[clusterName]开启

  • 单体应用的监控,通过URL http://hostname:port/hystrix.stream开启

监控界面各项元素的意义:

实心圆:颜色表示健康程度,大小表示请求流量

曲线:用来记录两分钟内流量的相对变化

Turbine集群监控

通过启动类加@EnableTurbine注解开启

第六章 声明式服务调用 Feign

启用Feign:在启动类添加@EnableFeignClients注解

定义服务接口,定义一个接口(Interface),通过@FeignClient注解指定服务名来绑定服务,然后再使用Spring MVC注解来绑定具体该服务提供的REST接口(这里服务名不区分大小写)

参数绑定

1
2
3
4
5
6
7
8
// 获取参数
public String hello(@RequestParam("name") String name){}
// 获取路径变量
public String hello(@PathVariable("id") String name){}
// 获取header
public String hello(@RequestHeader String name){}
// 获取body
public String hello(String name){@RequestBody User user}

配置

Ribbon

全局配置

1
2
3
4
5
6
7
ribbon:
NFLoadBalancerRuleClassName: * #负载均衡规则全类名
ConnectTimeout: 200 #链接超时时间
ReadTimeout: 200 #请求超时时间
OkToRetryOnAllOperations: true #是否对所有操作都允许重试
MaxAutoRetriesNextServer: 2 # 切换实例的重试次数
MaxAutoRetries: 1 # 当前实例的重试次数

指定服务配置

1
2
3
4
5
6
7
8
userservice:
ribbon:
NFLoadBalancerRuleClassName: * #负载均衡规则全类名
ConnectTimeout: 200 #链接超时时间
ReadTimeout: 200 #请求超时时间
OkToRetryOnAllOperations: true #是否对所有操作都允许重试
MaxAutoRetriesNextServer: 2 # 切换实例的重试次数
MaxAutoRetries: 1 # 当前实例的重试次数

Hystrix

全局配置

1
2
3
4
5
6
7
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 5000

禁用Hystrix

通过feign.hystrix.enable = false 来关闭Hystrix或 hystrix.command.default.execution.timeout.enabled = false来关闭熔断功能

如果要局部禁用,需要使用@Scope("protoype")注解来指定配置实例

服务降级配置

1
2
3
4
@FeignClient(value = "userservice", fallback= UserClientFallback.class)
public interface UserClient{
...
}

请求压缩

1
2
3
4
5
6
feign:
compression:
request:
enable: true
response:
enable: false

可以针对请求的数据类型以及触发压缩的大小下限进行设置

1
2
3
4
5
6
feign:
compression:
request:
enable: true
mime-types: text/html, application/xml. application/json
min-request-size: 1024 # 设置触发压缩的大小下限

日志配置

Feign的Logger级别有下面四种:

  • NONE:不记录任何信息

  • BASIC:金鸡路请求方法、URL以及响应码和执行时间

  • HEADERS:除了BASIC之外还记录请求和响应头

  • FULL:记录所有请求与响应的明细

全局配置

1
2
3
4
5
6
7
8
feign:
client:
config:
metaDataClient:
connect-timeout: 3000
read-timeout: 3000
default:
loggerLevel: FULL

局部配置

1
2
3
4
5
6
7
8
feign:
client:
config:
metaDataClient:
connect-timeout: 3000
read-timeout: 3000
userservice: # 服务名称
loggerLevel: BASIC

Java配置类

1
2
3
4
5
6
public class UserClientConfig(){
@Bean
public Logger.Level feignLoggerLevel(){
return Logger.Level.FULL;
}
}

SpringCloud 知识整理
2023/06/11/subject/SpringCloud/
作者
charlesix59
发布于
2023年6月11日
许可协议