目录
- 版本选择
- springcloud 组件
- 构建微服务
- Eureka 服务注册与发现【停更】
- Zookeeper 服务注册与发现
- Consul 服务注册与发现
- Ribbon 负载均衡服务调用
- OpenFeign 服务接口调用
- Hystrix 断路器【停更】
- Gateway 新一代网关
- SpringCloud Config 分布式配置中心【停更】
- SpringCloud Bus 消息总线【停更】
- SpringCloud Stream 消息驱动
- SpringCloud Sleuth 分布式请求链路跟踪
- SpringCloud Alibaba 入门简介
- SpringCloud Alibaba Nacos 服务注册和配置中心
- SpringCloud Alibaba Sentinel 实现熔断与限流
- SpringCloud Alibaba Seata 处理分布式事务
springcloud:https://spring.io/projects/spring-cloud
springcloud alibaba:https://spring.io/projects/spring-cloud-alibaba
springcloud alibaba github:https://github.com/alibaba/spring-cloud-alibaba
版本选择
- springcloud对应的springboot版本:https://spring.io/projects/spring-cloud#overview
- 详细版本约束:https://start.spring.io/actuator/info
- springcloud文档中使用的springboot版本:https://docs.spring.io/spring-cloud/docs/2020.0.3/reference/htmlsingle/
- springcloud alibaba对应springcloud和springboot版本:https://github.com/alibaba/spring-cloud-alibaba/wiki/版本说明
高版本禁用了bootstrap,需要引入pom spring-cloud-starter-bootstrap,然后springcloud的配置都必须放在bootstrap里
springcloud 组件
- springcloud官方文档:
- springboot官方文档:https://docs.spring.io/spring-boot/docs/2.4.8/reference/htmlsingle/
![](/i/l/?n=22&i=blog/1403018/202209/1403018-20220904150428506-1356039294.png)
构建微服务
- payment工程,controller调用service,service调用dao,查询和插入数据
- order工程,通过restTemplate访问payment工程的controller接口
热部署:
- 引入依赖devtools,注意打包时排掉
- 引入插件
- 配置idea
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!--热部署插件
1、添加依赖dev-tools
2、添加插件
3、修改idea配置 Ctrl + Shift + Alt + / 勾选第一个
-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.2.2.RELEASE</version>
<configuration>
<fork>true</fork>
<addResources>true</addResources>
</configuration>
</plugin>
</plugins>
</build>
Eureka 服务注册与发现【停更】
eureke有两个组件,server和client
停更说明:https://github.com/Netflix/eureka/wiki
使用总结:
- server,
@EnableEurekaServer
,修改配置 - client,
@EnableEurekaClient
,修改配置,@LoadBalanced + RestTemplate
配置eureka server
- 引入pom,引入这一个就可以了
1.x版本
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
2.x版本
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
- 修改配置文件,application.yml,配置eureka实例名、是否注册、是否从注册中心获取配置、服务url
- 启动类增加
@EnableEurekaServer
,@SpringBootApplication
- 访问:http://localhost:7001/
- 配置eureka集群
- 多个eureka server,配置中defaultZone写其他的eureka地址,这些eureka组成集群
配置client微服务注册到server
- 引入pom
1.x
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
2.x
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
- 修改配置文件,注册到server,地址为server配置中的地址
- 启动类增加
@EnableEurekaClient
- 先启动server,后启动注册的服务,访问:http://localhost:7001/ ,发现已经注册上了
使用@LoadBalanced访问eureka上注册的服务
order服务注册到eureka上之后,可以使用以下配置访问注册到eureka上的其他服务,使用@LoadBalanced
标注的restTemplate可以通过eureka上注册的服务名称访问到该服务,默认是轮询方式。
@Configuration
public class ApplicationConfig {
@Bean
@LoadBalanced //使restTemplate具有负载均衡的能力
public RestTemplate restTemplate() {
return new RestTemplateBuilder().build();
}
}
注意:如果使用了@LoadBalanced
,那么这个RestTemplate只能用来访问注册中心上的服务
actuator微服务信息完善
在eureka上注册的服务默认显示的是主机名:应用名:端口
,可以配置一个instance-id
以及prefer-ip-address
,这样就显示为了实例id,以及点击跳转时会使用ip地址。(使用主机名也可以访问本机)
注册上去的服务显示状态,是通过服务的actuator接口查询的
使用DiscoveryClient获取已注册的服务信息
对于注册进eureka里面的微服务,可以通过服务发现获取已注册服务的信息,比如服务名称、实例id、ip、端口等
没有使用@EnableDiscoveryClient
也可以注入
@Resource
private DiscoveryClient discoveryClient;
eureka自我保护机制
保护模式主要阿用于一组呵护的与eureka server直接存在网络分区场景下的保护,一旦进入保护模式,eureka server将会尝试保护其服务注册表中的信息,不在删除服务注册表中的数据,也就是不会注销任何服务
为什么会产生eureka自我保护机制:
- 为了防止eurekaClient可以正常运行,但是与eurekaServer网络不通的情况下,不会立即将eurekaClient服务删除
- 默认情况下,如果eurekaServer在一定时间内没有接受到某个微服务实例的心跳,将会注销该实例(默认90s),但是当网络分区故障时,微服务与eurekaServer无法正常通信,以上行为就变得非常危险了,因为微服务本身是健康的,此时不应该注销该微服务。
- eureka通过自我保护机制来解决这个问题,当短时间内丢失过多客户端时,那么这个节点就进入了自我保护模式。
- 输入CAP里面的AP分支
可用性
,分区容错性
关闭自我保护机制:
eureka.server.enable-self-preservation=false
- 调整服务发送心跳的间隔和失效时间
eureka.instance.lease-renewal-interval-in-seconds
eureka.instance.lease-expiration-duration-in-seconds
Zookeeper 服务注册与发现
- 引入
spring-cloud-starter-zookeeper-discovery
,注意排除zookeeper
,换上版本与实际zk版本相同的依赖 - 配置zk的连接信息即可注册到zk
- 注册的是一个临时节点
注意:
- 使用restTemplate访问时,名称必须与zk上注册的名称一致,大小写敏感,eureka大小写不敏感
- @EnableDiscoveryClient使用与不使用还没发现有什么区别
Consul 服务注册与发现
- 官网:https://www.consul.io/docs/intro
- 下载的文件中解压后只有一个文件consul
- 注册时需要打开配置
spring.cloud.consul.discovery.prefer-ip-address
才能健康检查通过,如果配置了server.servlet.context-path
注意修改consul的健康检查路径。健康检查通过,consumer才能调用 - 没有使用
@EnableDiscoveryClient
也可以正常调用
总结:
- 微服务提供者和消费者都注册到注册中心,然后消费者就可以通过注册中心进行访问提供者
- 微服务需要引入actuator以提供注册中心进行健康检查(自己使用一个接口应该也可以)
- 健康检查通过,才能被消费者调用
- CAP:一致性,可用性,分区容错性
- 在分布式架构下,P分区容错性是一定要保证的
- eureka是AP,高可用,分区容错,不保证一致性(自我保护机制)
- zookeeper、consul是CP,强一致性,分区容错,数据不一致时服务不可用
Ribbon 负载均衡服务调用
负载均衡:
- 集中式:在服务的消费方和提供方使用独立的LB设施,比如nginx,服务器端
- 进程内:将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己从这些地址中选择一个合适的服务器。
ribbon就属于进程内LB,只是一个类库,集成于消费方进程,消费者通过它获取服务提供方的地址
默认spring-cloud-starter-netflix-eureka-server
和spring-cloud-starter-netflix-eureka-client
已经引入了spring-cloud-starter-netflix-ribbon
,@LoadBalanced
注解就是使用ribbon默认的轮询算法
ribbon的路由算法:
- 默认是轮询
- 为某个微服务自定义路由算法,需要在主启动类扫描的包外配置其他路由算法,否则所有的客户端都使用同一个算法,达不到定制的目的
- 原理:客户端的ribbon,通过
DiscoveryClient
获取到所有的微服务,对于要访问的某个微服务,其实例列表为List<ServiceInstance>
,用该服务的请求次数 % 实例数获取要使用的实例索引,从而实现轮询。使用了自旋锁,在类RoundRobinRule
中
- 使用ribbon别的算法
- 在主启动扫描的包外,定义
@Configuration + @Bean
返回一个IRule
,然后在主启动类使用@RibbonClient(name = "foo", configuration = MyRule.class)
- 注意自定义配置类的名字不要和里面定义的bean名字冲突,要保证beanName的唯一性
- 要使用@Loadbalanced在RestTemplate上
- 使用restTemplate访问的微服务的名称要与@RibbonClient的name完全一致
- 在主启动扫描的包外,定义
- 不使用ribbon的算法,自定义路由算法
- 基本实现逻辑:自己通过
DiscoveryClient
获取到所有的微服务,根据自己访问的微服务名称,获取到该服务的所有实例,也可以获取到每个实例的URI,那么选择哪一个进行访问可以自行设计,用于给访问服务的restTemplate调用(注意这时restTemplate不需要用@LoadBalanced注解了,是普通的restTemplate) - 实现方式可以参数ribbon的设计逻辑,定义接口IRule等
- 基本实现逻辑:自己通过
OpenFeign 服务接口调用
Feign是一个声明式的web服务客户端,让编写web服务客户端变得非常容易,只需创建一个接口并在接口上添加注解即可。简化了原来的ribbon+restTemplate开发(restTemplate加注解@LoadBalanced)
依赖:spring-cloud-starter-openfeign
,该依赖中引入了ribbon
- Feign和OpenFeign的区别:OpenFeign在Feign的基础上支持了SpringMVC的注解
- 使用:
- 定义接口,在接口上使用注解@FeignClient,指明要访问的服务名称(相当于封装了RestTemplate),使用接口调用方法,相当于发送对应请求给服务,接口方法支持SpringMVC注解
- 超时控制:hystrix -> feign -> ribbon -> httpclient(只有连接超时配置)
- 默认
feign.hystrix.enabled=false
,如果开启,hystrix的默认超时是1s,注意要有fallback以及配置feignClient的@HystrixCommand
feign.client.config
可以配置默认的超时时间和某个feignClient的超时时间,如果没有配,则不开启ribbon.ReadTimeout
,ribbon超时配置,默认为1s- 如果配置了hystrix、feign、ribbon的超时配置,超时时间由较小者控制
- 默认
- 日志打印:
- 配置Logger.Level类型的bean,并在配置文件中修改feignClient接口的日志级别为debug
- feignClient的日志级别由4个,NONE,BASIC,HEADERS,FULL,默认NONE,具体输出内容由该级别控制,
logging.level
只是配置该接口的日志级别
Hystrix 断路器【停更】
Hystrix断路器是一个处理分布式系统的延迟和容错的开源库,保证在一个服务依赖出现问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。
断路器本身是一种开关装置,当某个服务发生故障之后,通过断路器的故障监控,向调用方返回一个符合预期的、可处理的备选响应(fallback),而不是长时间的等待或者抛出调用方无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要的占用,从而避免了故障在分布式系统中的蔓延、乃至雪崩。
- 服务降级:调用出现错误时调用其他处理流程,及时返回提示,而不是返回后台错误
- 服务熔断:调用在一定时间内出现一定百分比错误,打开熔断,不再调用原服务流程而是调用服务降级流程快速返回错误响应信息,一定时间后,如果调用服务正常(半开),关闭熔断,开启主流程
- 服务限流,后面介绍
使用hystrix:
- 主启动开启断路保护
@EnableCircuitBreaker
,或者@EnableHystrix
也是开启了断路保护,但使用的是hystrix,继承了@EnableCircuitBreaker - 对某个方法进行服务降级,该方法必须在1500ms内返回,否则调用降级方法
- 如果没有指定fallback方法则使用默认配置的fallback方法,使用
@DefaultProperties(defaultFallback = "getPaymentDefaultFallback")
放在类上 - hystrix默认超时时间1s
- 其他配置参数配置在
HystrixCommandProperties
抽象类中
- 如果没有指定fallback方法则使用默认配置的fallback方法,使用
@HystrixCommand(fallbackMethod = "getPaymentTimeoutFallback", commandProperties = {
@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="1500")
})
- 对某个方法进行服务熔断
//表示满足断路器条件时 开启断路器 进行断路保护 稍后请求如果正常 则关闭断路器
@HystrixCommand(fallbackMethod = "getPaymentCircuitBreakFallback",commandProperties = {
//是否开启断路器
@HystrixProperty(name = "circuitBreaker.enabled",value = "true"),
//请求次数 次数内计算一次 是否开启断路保护
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"),
//断路保护开启时 休眠时间 该时间内一直返回fallback 完全打开断路器
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10000"),
//计算时 是否满足失败率 满足则打开断路器
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60"),
})
- 其他配置
@HystrixCommand(fallbackMethod = "str_fallbackMethod",
groupKey = "strGroupCommand",
commandKey = "strCommand",
threadPoolKey = "strThreadPool",
commandProperties = {
// 设置隔离策略,THREAD 表示线程池 SEMAPHORE:信号池隔离
@HystrixProperty(name = "execution.isolation.strategy", value = "THREAD"),
// 当隔离策略选择信号池隔离的时候,用来设置信号池的大小(最大并发数)
@HystrixProperty(name = "execution.isolation.semaphore.maxConcurrentRequests", value = "10"),
// 配置命令执行的超时时间
@HystrixProperty(name = "execution.isolation.thread.timeoutinMilliseconds", value = "10"),
// 是否启用超时时间
@HystrixProperty(name = "execution.timeout.enabled", value = "true"),
// 执行超时的时候是否中断
@HystrixProperty(name = "execution.isolation.thread.interruptOnTimeout", value = "true"),
// 执行被取消的时候是否中断
@HystrixProperty(name = "execution.isolation.thread.interruptOnCancel", value = "true"),
// 允许回调方法执行的最大并发数
@HystrixProperty(name = "fallback.isolation.semaphore.maxConcurrentRequests", value = "10"),
// 服务降级是否启用,是否执行回调函数
@HystrixProperty(name = "fallback.enabled", value = "true"),
// 是否启用断路器
@HystrixProperty(name = "circuitBreaker.enabled", value = "true"),
// 该属性用来设置在滚动时间窗中,断路器熔断的最小请求数。例如,默认该值为 20 的时候,
// 如果滚动时间窗(默认10秒)内仅收到了19个请求, 即使这19个请求都失败了,断路器也不会打开。
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "20"),
// 该属性用来设置在滚动时间窗中,表示在滚动时间窗中,在请求数量超过
// circuitBreaker.requestVolumeThreshold 的情况下,如果错误请求数的百分比超过50,
// 就把断路器设置为 "打开" 状态,否则就设置为 "关闭" 状态。
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50"),
// 该属性用来设置当断路器打开之后的休眠时间窗。 休眠时间窗结束之后,
// 会将断路器置为 "半开" 状态,尝试熔断的请求命令,如果依然失败就将断路器继续设置为 "打开" 状态,
// 如果成功就设置为 "关闭" 状态。
@HystrixProperty(name = "circuitBreaker.sleepWindowinMilliseconds", value = "5000"),
// 断路器强制打开
@HystrixProperty(name = "circuitBreaker.forceOpen", value = "false"),
// 断路器强制关闭
@HystrixProperty(name = "circuitBreaker.forceClosed", value = "false"),
// 滚动时间窗设置,该时间用于断路器判断健康度时需要收集信息的持续时间
@HystrixProperty(name = "metrics.rollingStats.timeinMilliseconds", value = "10000"),
// 该属性用来设置滚动时间窗统计指标信息时划分"桶"的数量,断路器在收集指标信息的时候会根据
// 设置的时间窗长度拆分成多个 "桶" 来累计各度量值,每个"桶"记录了一段时间内的采集指标。
// 比如 10 秒内拆分成 10 个"桶"收集这样,所以 timeinMilliseconds 必须能被 numBuckets 整除。否则会抛异常
@HystrixProperty(name = "metrics.rollingStats.numBuckets", value = "10"),
// 该属性用来设置对命令执行的延迟是否使用百分位数来跟踪和计算。如果设置为 false, 那么所有的概要统计都将返回 -1。
@HystrixProperty(name = "metrics.rollingPercentile.enabled", value = "false"),
// 该属性用来设置百分位统计的滚动窗口的持续时间,单位为毫秒。
@HystrixProperty(name = "metrics.rollingPercentile.timeInMilliseconds", value = "60000"),
// 该属性用来设置百分位统计滚动窗口中使用 “ 桶 ”的数量。
@HystrixProperty(name = "metrics.rollingPercentile.numBuckets", value = "60000"),
// 该属性用来设置在执行过程中每个 “桶” 中保留的最大执行次数。如果在滚动时间窗内发生超过该设定值的执行次数,
// 就从最初的位置开始重写。例如,将该值设置为100, 滚动窗口为10秒,若在10秒内一个 “桶 ”中发生了500次执行,
// 那么该 “桶” 中只保留 最后的100次执行的统计。另外,增加该值的大小将会增加内存量的消耗,并增加排序百分位数所需的计算时间。
@HystrixProperty(name = "metrics.rollingPercentile.bucketSize", value = "100"),
// 该属性用来设置采集影响断路器状态的健康快照(请求的成功、 错误百分比)的间隔等待时间。
@HystrixProperty(name = "metrics.healthSnapshot.intervalinMilliseconds", value = "500"),
// 是否开启请求缓存
@HystrixProperty(name = "requestCache.enabled", value = "true"),
// HystrixCommand的执行和事件是否打印日志到 HystrixRequestLog 中
@HystrixProperty(name = "requestLog.enabled", value = "true"),
},
threadPoolProperties = {
// 该参数用来设置执行命令线程池的核心线程数,该值也就是命令执行的最大并发量
@HystrixProperty(name = "coreSize", value = "10"),
// 该参数用来设置线程池的最大队列大小。当设置为 -1 时,线程池将使用 SynchronousQueue 实现的队列,
// 否则将使用 LinkedBlockingQueue 实现的队列。
@HystrixProperty(name = "maxQueueSize", value = "-1"),
// 该参数用来为队列设置拒绝阈值。 通过该参数, 即使队列没有达到最大值也能拒绝请求。
// 该参数主要是对 LinkedBlockingQueue 队列的补充,因为 LinkedBlockingQueue
// 队列不能动态修改它的对象大小,而通过该属性就可以调整拒绝请求的队列大小了。
@HystrixProperty(name = "queueSizeRejectionThreshold", value = "5"),
}
)
openfeign使用hystrix进行服务降级:
- openfeign内置了hystrix,修改配置打开服务断路保护
feign.hystrix.enable=true
,可以对feignClient写fallback方法或fallbackFactory,新版本可能是feing.circuitbreaker.enable=true
- 此时feignClient会被一个hystrix circuit breaker wapper,hystrix默认超时时间1s
- 如果feign开启了断路保护,注意超时时间配置:hystrix -> feign -> ribbon三者控制
除了隔离依赖服务的调用以外,Hystrix还提供了准实时的调用监控(Hystrix Dashboard),Hystrix会持续地记录所有通过Hystrix发起的请求的执行信息,并以统计报表和图形的形式展示给用户,包括每秒执行多少请求多少成功,多少失败等。Netflix通过hystrix-metrics-event-stream项目实现了对以上指标的监控。Spring Cloud也提供了Hystrix Dashboard的整合,对监控内容转化成可视化界面。
- 引入pom
spring-cloud-starter-netflix-hystrix-dashboard
- 主启动添加
@EnableHystrixDashboard
,访问http://localhost:9001/hystrix
- 输入某个被监控服务地址
http://localhost:8010/hystrix.stream
- 被监控端添加servlet
@Bean
public ServletRegistrationBean getServlet() {
HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
registrationBean.setLoadOnStartup(1);
registrationBean.addUrlMappings("/hystrix.stream");
registrationBean.setName("HystrixMetricsStreamServlet");
return registrationBean;
}
说明:
Gateway 新一代网关
官方文档:https://docs.spring.io/spring-cloud-gateway/docs/2.2.9.RELEASE/reference/html/
Gateway是在Spring生态系统之上构建的API网关服务,基于Spring 5,Spring Boot 2和 Project Reactor等技术。
Gateway旨在提供一种简单而有效的方式来对API进行路由,以及提供一些强大的过滤器功能, 例如:熔断、限流、重试等
概念:
- 路由(Route),是构建网关的基本模块,由ID、目标URI、一系列断言和过滤器组成,如果断言为true,则匹配该路由
- 断言(Predicate),参考java8的java.util.function.Predicate,开发人员可以匹配http请求中的所有内容,如果与断言匹配则进行路由
- 过滤(Filter),指Spring框架中的Filter实例,使用过滤器,可以在请求被路由前或者之后堆请求进行修改
客户端向gateway发出请求,然后再gateway handler mapping中找到与请求相匹配的路由,将其发送到gateway web handler,handler在通过指定的过滤器链将请求发送到实际的服务执行业务逻辑,然后返回。过滤器可能在发送代理请求之前或之后执行业务逻辑。
filter生命周期有两个,pre和post,在pre类型的过滤器可以做参数校验、权限校验、流量监控、日志输出、协议转换等。在post类型的过滤器中可以做响应内容、响应头的修改。
filter的种类有两个,GatewayFilter,GlobalFilter
Predicate的使用:
- yaml配置
- 或者编码
Filter的使用:
- yaml配置
- 或者自定义
总结:断言和过滤组成路由
SpringCloud Config 分布式配置中心【停更】
官网文档:https://docs.spring.io/spring-cloud-config/docs/2.2.8.RELEASE/reference/html/
配置中心分为两个部分:server和client
server端:
- pom:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
- 主启动类加
@EnableConfigServer
- 配置可以配置为本地文件、jdbc、git、svn、redis...
- 本地文件配置
spring.profiles.active=native
spring.cloud.config.server.native.search-locations
配置文件搜索路径,如classpath:appconfig/{label}
,label占位符自动填充- 配置文件命名
name-profile.properties
或者使用yml格式
- 配置jdbc
spring.profiles.active=jdbc
- 配置
spring.datasource
或druid - 配置
spring.cloud.config.server.jdbc.sql=SELECT k, v from config_info where (application_name=? or application_name='application') and profile=? and label=?
,name为application的为全局配置,所有客户端都可以获取到
- 本地文件配置
client端:
- pom:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
</dependency>
- 配置文件需要使用bootstrap.yml,在系统启动时从配置中心获取配置启动
- 配置
spring.cloud.config
下的uri或者使用从注册中心访问配置中心,配置name/profile/master - 配置
management.endpoints.web.exposure.include
包含refresh,使用@RefreshScope
注解标注的组件里面的@Value
或者@ConfigurationProperties
标注的配置能够通过POST /actuator/refresh
对客户端进行配置刷新 - 需要引入actuator模块
注意:
- 高版本禁用了bootstrap,需要引入pom,spring-cloud-starter-bootstrap
- 如果引入了pom bootstrap,又使用注册中心访问配置中心,那么注册中心的配置也要放在bootstrap里面
问题:配置修改至少还要发POST请求才能更新,可以引入消息总线bus解决
SpringCloud Bus 消息总线【停更】
spring cloud Bus是用来将分布式系统的节点与轻量级详细系统连接起来的框架。
spring cloud Bus配合spring cloud Config实现配置的动态刷新,支持两种消息对象:RabbitMQ
,Kafka
什么是总线
在微服务架构的系统中,通常会使用轻量级的消息代理来构建一个共用的消息主题,并让系统中所有微服务实例都连接上来。由于该主题中产生的消息会被所有实例监听和消费,所以称它为消息总线。在总线上的各个实例,都可以方便地广播一些需要让其他连接在该主题上的实例都知道的消息。
基本原理
ConfigClient实例都监听MQ中同一个topic(默认是springCloudBus,config center作为MQ)。当一个服务刷新数据的时候,它会把这个信息放入到Topic中,这样其它监听同一Topic的服务就能得到通知,然后去更新自身的配置。
rabbitmq:https://www.cnblogs.com/bingmous/p/16537455.html
配置:
- 服务端pom添加bus-amqp,yaml添加rabbitmq暴露bus刷新配置的端点
- 客户端pom添加bus-amqp,yaml添加rabbitmq相关配置,host, port, username, password
- 修改配置后,curl -X POST "http://配置中心/actuator/bus-refresh" ,所有订阅mq的客户端的配置也都会更新
- 定点通知:curl -X POST "http://配置中心/actuator/bus-refresh/客户端名称:端口号" ,如果名称和端口号都是一样的呢?
SpringCloud Stream 消息驱动
Spring Cloud Stream 是一个构建消息驱动微服务的框架,屏蔽底层的消息中间件【目前支持Rabbitmq,Kafka】
使用binder,屏蔽底层的rabbitmq和kafka:
- 写数据:在类上使用@EnableBinding(Source.class) ,注入MessageChannel作为消息发送管道,调用send方法发送数据,yaml配置中通道名称为bindings.output
- 读数据:在类上使用@EnableBinding(Sink.class) ,在接收数据的方法上使用@StreamListener(Sink.INPUT),参数为Message,调用getPayload()接收数据,yaml配置中bindings.input
SpringCloud Sleuth 分布式请求链路跟踪
sleuth做链路跟踪,zipkin做展示
zipkin:https://zipkin.io/
sleuth:https://spring.io/projects/spring-cloud-sleuth
sleuth的链路追踪数据可以直接发送到zipkin,但是是放在zipkin的内存中,新数据会覆盖旧数据。也可以发送到kafka,可以配置zipkin消费数据到es,并使用es的链路追踪数据。
如果需要查看聚合关系,需要定时执行zipkin-dependencies的jar包,是一个本机的spark job,默认只支持jdk8执行,可以修改源码中的spark依赖版本和相关的只支持jdk8的依赖,修改源码中的一些api接口支持jdk11。
SpringCloud Alibaba 入门简介
dubbo -> springcloud -> springcloud alibaba
springboot -> springcloud -> springcloud alibaba 版本依赖关系:参考github wiki
SpringCloud Alibaba Nacos 服务注册和配置中心
Nacos: Dynamic Naming and Configuration Service
注册中心 + 配置中心 = eureka + config+ bus
支持ap 和 cp的切换
安装
- 版本:1.2.1
- 版本对应关系:版本说明 · alibaba/spring-cloud-alibaba Wiki · GitHub
- window 单机启动:startup.cmd -m standalone
- 访问:http://ip:8848/nacos/index.html
- 作为配置中心自动更新配置,可以分命名空间,组,ID
配置持久化只支持MySQL
高可用:Nginx集群 + Nacos集群 + 高可用MySQL集群
SpringCloud Alibaba Sentinel 实现熔断与限流
github:https://github.com/alibaba/Sentinel/releases
springcloud alibaba 2.1.0 springboot 2.2.2 springcloud Hoxton.SR1
- 服务雪崩
- 服务降级
- 服务熔断
- 服务限流
启动:java -jar sentinel-dashboard-1.7.0.jar,账号密码均为sentinel
流控,降级,热点key限流,系统规则
SpringCloud Alibaba Seata 处理分布式事务
github:https://github.com/seata/seata/releases
0.9.0版本与1.4.2版本差别很大,比如sql语句在安装文件中没有,配置文件也不一样了,需要参考官方文档
使用mysql,sql脚本的类型与pg不同