该笔记为本人学习SpringCloud时总结的,对应视频来自尚硅谷
视频地址为:https://www.bilibili.com/video/BV18E411x7eT
文章目录
springcloud
第一讲
什么是微服务?
微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。每个服务运行其独立的进程中,服务与服务间采用轻量级的通信机制互相协作(通常是基于Http协议的RESTful API)。每个服务都围绕着基本业务进行构建,并且能够被独立的部署到生产环境、类环境等。另外,应当尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建
满足哪些纬度?
- 服务注册与发现
- 服务调用
- 服务熔断
- 负载均衡
- 服务降级
- 服务消息队列
- 配置中心管理
- 服务网关
- 服务监控
- 全链路追踪
- 自动化构建部署
- 服务定时任务调度操作
支撑起这些纬度的具体技术?
SpringCloud=分布式微服务架构的一站式解决方案,是多种微服务架构落地技术的集合体
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vrJL9ElM-1595411658264)(https://gitee.com/CainLong/images/raw/master/NSGK%@_M6K8PZZMGQE}0ESM.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zEFWkSVj-1595411658267)(file:///D:\QQ\1422234087\Image\C2C\VAB7MP{B19[XXMA%L)]PNY$Y.png)
- 服务注册与发现
- EUREKA
- 服务负载与调用
- NETFLIX OSS RIBBON
- 服务负载与调用
- NETFLIX FEIGN
- 服务熔断降级
- HySTRIX
- 服务网关
- NETFLIX Zuul
- 服务分布式配置
- Spring Cloud Config
- 服务开发
- Spring Boot
第二讲
组件停更说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E1IzArjl-1595411658269)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200622184811932.png)]
第三讲
第四讲
微服务架构编码搭建
支付模块
- 建module
- 改pom
- 写yml
- 主启动
- 业务类
微服务调试最好在Run Dashboard空间,不在Run空间里
热部署—只允许开发阶段
开发过程开启热部署功能,代码修正。
-
子工程添加依赖
-
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency>
-
-
父工程添加插件
-
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <fork>true</fork> <addResources>true</addResources> </configuration> </plugin> </plugins> </build>
-
-
idea setting
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OZ4roPJR-1595411658274)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200623142628158.png)]
-
按下 ctrl+shift+alt+/ 点击注册
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GZgz1IG0-1595411658276)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200623142803975.png)]
消费者订单模块
只需要编写Controller层代码和实体类代码,那最初先靠什么来完成两个模块间的传输的?答案是HttpClient,不过我们使用RestTemplate来进行调用,其实他就是封装了一层HttpClient,它提供了多种便捷访问远程Http服务的方法,是一种简单便捷的访问restful服务模板类,是Spring提供的用于访问Rest服务的客户端模板工具集
那么RestTemplate的使用方式是怎样的呢?使用RestTemplate访问restful接口非常的简单粗暴无脑。(url,requestMap,ResponseBean.class)这三个参数分别代表REST请求地址、请求参数、HTTP响应转换被转换成的对象类型
测试出现问题,在支付模块中,参数没加@RequestBody的话,其中的数据是为空的
工程重构
系统中有重复部分,重构,相似的地方拿出来
新建一个子工程,供多个工程调用
第五讲–服务注册中心
为什么要有服务注册中心?方便服务之间的调度、协调和管理
Eureka
Eureka基础知识
什么是服务治理
Spring Cloud封装了Netflix公司开发的Eureka模块来实现服务治理
在传统的rpc远程调用框架中,管理每个服务与服务之间依赖关系比较复杂,管理比较复杂,所以需要服务治理,管理服务与服务之间的依赖,可以实现服务调用、负载均衡、容错等,实现服务发现与注册。
什么是服务注册
Eureka采用了CS的设计架构,Eureka Server作为服务注册功能的服务器,它是服务注册中心。而系统中的其他微服务,使用Eureka的客户端连接到Eureka Server并维持心跳连接。这样系统的维护人员就可以通过Eureka Server来监控系统中各个微服务是否正常运行。
在服务注册与发现中,有一个注册中心。当服务器启动的时候,会把当前自己服务器的信息,比如服务地址通讯地址等以别名方式注册到注册中心中。另一方(消费者|提供者),以该别名的方式去注册中心上获取到实际的服务通讯地址,然后再实现本地RPC调用RPC远程调用框架核心设计思想:在于注册中心,因为使用注册中心管理没个服务于服务之间的一个依赖关系(服务治理概念)。在任何rpc远程框架中,都会有一个注册中心(存放服务地址相关信息(接口地址))
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0iS2E1ax-1595411658277)(https://gitee.com/CainLong/images/raw/master/20200623154826.png)]
单点故障,所以能配多个的就配多个集群
Eureka两组件
Eureka包含两个组件:Eureka Server 和 Eureka Client
Eureka Server提供服务注册服务
各个微服务节点通过配置启动后,会在Eureka Server中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观看到。
EurekaClient通过注册中心进行访问
是一个java客户端,用于简化Eureka Server的交互,客户端同时也具备一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在应用启动后,将会向Eureka Server发送心跳(默认周期为30秒)。如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)
EurekaServer服务端安装
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7KQLecfq-1595411658278)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200623164011308.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MMPCPcb5-1595411658279)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200623164145461.png)]
Eureka集群原理说明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5AlLLdmg-1595411658280)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200623165304276.png)]
问题:微服务RPC远程服务调用最核心的是什么?
那必然就是高可用呀,试想你的注册中心就只有一个的话,加入它出故障了,那么整个系统的服务环境就都不能用了,所以
解决办法就是:搭建Eureka注册中心集群,实现负载均衡+故障容错
Eureka集群环境构建
集群搭建的一个原理就是:互相注册,相互守望。
对内互相注册,对外暴露出一个整体
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QL84MYqs-1595411658280)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200623171721227.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cREAkA5q-1595411658281)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200623171736890.png)]
两个Eureka注册中心集群搭建完成
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h5ZrYEjD-1595411658283)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200623172316359.png)]
将两个微服务注册进注册中心
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GHpoqG3F-1595411658284)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200623174946459.png)]
服务模块集群搭建完成
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1FtegDxw-1595411658285)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200623175015950.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8u3jADAp-1595411658286)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200623175032135.png)]
负载均衡算法,挨个轮询
actuator微服务信息完善
去掉主机名称,服务名称的修改
访问信息有ip信息提示
服务发现Discovery
对于注册进eureka里面的微服务,可以通过服务发现来获得该服务的信息
Eureka自我保护
故障现象:
保护模式主要用于一组客户端和Eureka Server之间存在网络分区场景下的保护,一旦进入保护模式,Eureka Server将会尝试保护其服务注册表中的信息,不再删除服务注册表中的数据,也就是不会注销任何微服务。
导致原因:
一句话:某时刻某一个微服务不可用了,Eureka不会立刻清理,依旧会对该服务的信息进行保存,属于CAP里面的AP分支
为什么会产生Eureka自我保护机制?
为了防止EurekaClient可以正常运行,但是与EurekaServer网络不通情况下,EurekaServer不会立刻将EurekaClient服务剔除
什么是自我保护模式?
默认情况下,如果EurekaServer在一定时间内没有接收到某个微服务实例的心跳,EurekaServer将会注销该实例(默认90秒)。但是当网络分区故障发生(延时、卡顿、拥挤)是,微服务与EurekaServer之间无法正常通信,以上行为可能变得非常危险了–因为微服务本身其实是健康的,此时本不应该注销这个微服务。Eureka通过“自我保护模式”来解决这个问题–当EurekaServer节点在短时间内丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uOj6pbpQ-1595411658287)(C:\Users\14222\Desktop\gqGr\typera\QQ�VGr20200624103742.png)]
怎么禁止自我保护
在eureka yml中配置[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x5daQfmP-1595411658288)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200624105630830.png)]
在客户端 yml中配置[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5uMCwdG3-1595411658289)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200624105701109.png)]
Zookeeper
SpringCloud整合Zookeeper代替Eureka
简介
zookeeper是一个分布式协调工具,可以实现注册中心功能
支付服务注册进zookeeper
Consul
简介
Consul是一套开源的分布式服务发现和配置管理系统,由HashiCorp公司用Go语言开发
提供了微服务系统中的服务治理、配置中心、控制总线等功能。这些功能中的每一个都可以根据需要单独使用,也可以一起使用以构建全方位的服务网格,总之Consul提供了一种完整的服务网格解决方案。
它具有很多优点。包括:基于raft协议,比较简洁;支持健康检查,同时支持Http和DNS协议 支持跨数据中心的WAN集群 提供图形界面 跨平台,支持Linux、Mac、Windows
功能
- 服务发现:提供HTTP和DNS两种发现方式
- 健康监测:支持多种方式,HTTP、TCP、Docker、Shell脚本定制化
- KV存储:Key、Value的存储方式
- 多数据中心:Consul支持多数据中心
- 可视化Web界面
三个注册中心的异同点
组件名 | 语言 | CAP | 服务健康检查 | 对外暴露接口 | Springcloud集成 |
---|---|---|---|---|---|
Eureka | Java | AP | 可配支持 | HTTP | 已集成 |
Consul | Go | CP | 支持 | HTTP/DNS | 已集成 |
Zookeeper | Java | CP | 支持 | 客户端 | 已集成 |
CAP:
最多只能同时较好的满足两个。
CAP理论核心是:一个分布式系统不可能同时很好的满足一致性,可用性和分区容错性这三个需求,因此,根据CAP原理将NoSql数据库分成了满足CA原则、满足CP原则和满足AP原则三大类:
CA - 单点集群,满足一致性、可用性的系统,通常在可扩展性上不太强大
CP - 满足一致性,分区容忍性的系统,通常性能不是特别高。Zookeeper/Consul
AP - 满足可用性,分区容忍性的系统,通常可能对一致性要求低一些。Eureka
CAP理论关注粒度是数据,而不是整体系统设计的策略
AP:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vXiVz8I0-1595411658290)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200628131230999.png)]
CP:当网络分区出现后,为了保证一致性,就必须拒接请求,否则无法保证一致性,结论:违背了可用性A的要求,只满足一致性和分区容错,即CP
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Iov7so2z-1595411658291)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200628131522736.png)]
Nacos
第六讲–Ribbon负载均衡服务调用
## Ribbon入门介绍
是什么?
Spring Cloud Ribbon是基于Netflix Ribbon实现的一套**客户端** 负载均衡的工具
简单的说,Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法和服务调用。Ribbon客户端组件提供一系列完善的配置项如连接超时、重试等。简单的说,就是在配置文件中列出Load Balancer(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器。我们很容易使用Ribbon实现自定义的负载均衡算法。
能干嘛?
做负载均衡
LB负载均衡(Load Balance)是什么?
简单的说就是将用户的请求平摊的分配到多个服务上,从而达到系统的HA(高可用)。
常见的负载均衡有软件Nginx、LVS、硬件F5等。
Ribbon本地负载均衡客户端 VS Nginx服务端负载均衡区别?
Nginx是服务器负载均衡,客户端所有请求都会交给Nginx,然后由Nginx实现转发请求。即负载均衡是由服务端实现的。
Ribbon本地负载均衡,在调用微服务接口的时候,会在注册中心上获取注册信息服务列表之后缓存到JVM本地,从而在本地实现RPC远程服务调用技术。
Nginx就比作医院的大门,Ribbon就比作科室,就比如你牙疼,挂牙科,但是牙科不可能就一个医生,所以Ribbon的作用就是“你挂哪一个牙科医生”
集中式LB
即在服务的消费方和提供方之间使用独立的LB设施(可以是硬件,如F5,也可以是软件,如Nginx),由该设施负责把访问请求通过某种策略转发至服务的提供方;
进程内LB
将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从地址中选择出一个合适的服务器。
Ribbon就属于进程内LB,它只是一个类库,集成于消费方进程,消费方通过它来获取提供方的地址。
一句话
Ribbon就是负载均衡+RestTemplate调用
Ribbon的负载均衡和Rest调用
架构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KtQr1NLU-1595411658292)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200628154112413.png)]
Ribbon在工作的时候分两步:
- 第一步先选择EurekaServer,它优先选择在同一个区域内负载较少的Server
- 第二步再根据用户指定的策略,在从Server取到的服务注册列表中选择一个地址。
- 其中Ribbon提供了多种策略:比如轮询、随机和根据响应时间加权。
深入RestTemplate
getForObject方法/getForEntity方法
返回对象为响应体中数据转化成的对象,基本可以理解为Json
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YnbSXRmS-1595411658294)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200628155817091.png)]
返回对象为ResponseEntity对象,包含了响应中的一些重要信息,比如响应头、响应状态码、响应体等
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BRQJOBVn-1595411658295)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200628155824069.png)]
postForObject/postForEntity
Get请求方法
POST请求方法
Ribbon默认自带的负载规则
###IRule:根据特定算法中从服务列表中选取一个要访问的服务
IRule是一个接口
/**
* Interface that defines a "Rule" for a LoadBalancer. A Rule can be thought of
* as a Strategy for loadbalacing. Well known loadbalancing strategies include
* Round Robin, Response Time based etc.
*
* @author stonse
*
*/
public interface IRule{
/*
* choose one alive server from lb.allServers or
* lb.upServers according to key
*
* @return choosen Server object. NULL is returned if none
* server is available
*/
public Server choose(Object key);
public void setLoadBalancer(ILoadBalancer lb);
public ILoadBalancer getLoadBalancer();
}
它有哪些落地实现类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7jzpujDY-1595411658296)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200628162203603.png)]
com.netflix.loadbalancer.RoundRobinRule:轮询
com.netflix.loadbalancer.RandomRule:随机
com.netflix.loadbalancer.RetryRule:先按照RoundRobinRule的策略来获取服务,如果获取服务失败则在指定时间内会进行重试
WeightResponseTimeRule:对RoundRobinRule的扩展,响应速度越快的实例选择权重越大,越容易被选择
BestAvailableRule:会先过滤由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务
AvailabilityFilteringRule:先过滤掉故障实例,再选择并发较小的实例
ZoneAvoidanceRule:默认规则,复合判断server所在区域的性能和server的可用性选择服务器
如何替换
写一个配置类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fdX2N6d7-1595411658297)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200628164033541.png)]
注意是在与启动类不同的包下声明的一个配置类,因为官方文档明确说明不要放在ComponentScan能扫描的本包下以及子包下。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CIFTh3yl-1595411658297)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200628164201622.png)]
再看启动类,name表示我要去注册中心找的服务名称,configuration表示我自己配置的负载均衡实现类,不用默认的。
Ribbon默认负载轮询算法原理
原理
负载均衡算法:rest接口第几次请求数 % 服务器集群总数量 = 实际调用服务器位置下标,每次服务重启动后rest接口计数从1开始。
List instances = disconveryClient.getInstances(“CLOUD-PAYMENT-SERVICE”);
如:List [0] instances = 127.0.0.1:8002
List [1] instances = 127.0.0.1:8001
8001+8002组合成为集群,它们共计2台机器,集群总数为2,按照轮询算法原理:
当总请求数为1时:1 % 2 = 1 对应下标位置为1,则获得服务地址为127.0.0.1:8001
当总请求数为2时:2 % 2 = 0 对应下标位置为0,则获得服务地址为127.0.0.1:8002
当总请求数为1时:3 % 2 = 1 对应下标位置为1,则获得服务地址为127.0.0.1:8001
当总请求数为1时:4 % 2 = 1 对应下标位置为0,则获得服务地址为127.0.0.1:8002
如此类推…
源码
import com.netflix.client.config.IClientConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
/**
* The most well known and basic load balancing strategy, i.e. Round Robin Rule.
*
* @author stonse
* @author Nikos Michalakis <nikos@netflix.com>
*
*/
public class RoundRobinRule extends AbstractLoadBalancerRule {
private AtomicInteger nextServerCyclicCounter;
private static final boolean AVAILABLE_ONLY_SERVERS = true;
private static final boolean ALL_SERVERS = false;
private static Logger log = LoggerFactory.getLogger(RoundRobinRule.class);
public RoundRobinRule() {
//原子整形类 初始值为0
nextServerCyclicCounter = new AtomicInteger(0);
}
public RoundRobinRule(ILoadBalancer lb) {
this();
setLoadBalancer(lb);
}
public Server choose(ILoadBalancer lb, Object key) {
if (lb == null) {
log.warn("no load balancer");
return null;
}
//注册中心的服务
Server server = null;
//重试次数
int count = 0;
while (server == null && count++ < 10) {
//活着的服务实例 也就是在注册中心显示up状态的
List<Server> reachableServers = lb.getReachableServers();
//所有服务实例
List<Server> allServers = lb.getAllServers();
//活着的服务实例的数量
int upCount = reachableServers.size();
//所有服务实例的数量
int serverCount = allServers.size();
if ((upCount == 0) || (serverCount == 0)) {
log.warn("No up servers available from load balancer: " + lb);
return null;
}
//下一次服务实例的位置下标,这里内部采用CAS+自旋锁来对索引下标定位
int nextServerIndex = incrementAndGetModulo(serverCount);
//根据索引下标得到服务实例
server = allServers.get(nextServerIndex);
if (server == null) {
/* Transient. */
Thread.yield();
continue;
}
if (server.isAlive() && (server.isReadyToServe())) {
return (server);
}
// Next.
server = null;
}
if (count >= 10) {
log.warn("No available alive servers after 10 tries from load balancer: "
+ lb);
}
return server;
}
/**
* Inspired by the implementation of {@link AtomicInteger#incrementAndGet()}.
*
* @param modulo The modulo to bound the value of the counter.
* @return The next value.
*/
private int incrementAndGetModulo(int modulo) {
for (;;) {
//初始为0
int current = nextServerCyclicCounter.get();
int next = (current + 1) % modulo;
if (nextServerCyclicCounter.compareAndSet(current, next))
return next;
}
}
@Override
public Server choose(Object key) {
return choose(getLoadBalancer(), key);
}
@Override
public void initWithNiwsConfig(IClientConfig clientConfig) {
}
}
手写
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cQ20yT3r-1595411658298)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200628180157312.png)]
package com.markus.springcloud.lb;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Author:markusZhang
* Date:Create in 2020/6/28 17:31
* todo:
*/
@Component
public class MyLB implements LoadBalancer {
private AtomicInteger atomicInteger = new AtomicInteger(0);
public final int getAndIncrement(){
int current;
int next;
do {
current = this.atomicInteger.get();
next = current >= 2147483647 ? 0:current+1;
}while(!this.atomicInteger.compareAndSet(current,next));
System.out.println("*****第几次访问,次数next: "+next);
return next;
}
@Override
public ServiceInstance instances(List<ServiceInstance> serviceInstances) {
int index = getAndIncrement() % serviceInstances.size();
return serviceInstances.get(index);
}
}
第七讲–OpenFeign服务接口调用
概述
是什么?
Feign是一个声明式WebService客户端。使用Feign能让编写WebService客户端更加简单。
它的使用方法是定义一个服务接口然后在上面添加注解。Feign也支持可拔插式的编码器和解码器。Spring Cloud对Feign进行了封装,使其支持了Spring MVC标准注解和HttpMessageConverters。Feign可以与Eureka和Ribbon组合使用以支持负载均衡
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7vuM6x2t-1595411658299)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200628181120528.png)]
能干啥?
Feign旨在使编写Java Http客户端变得更容易
前面在使用Ribbon+RestTemplate时,利用RestTemplate对http请求的封装处理,形成了一套模板化的调用方法。但是在实际开发中,由于对服务依赖的调用可能不止一处,往往一个接口会被多出调用,所以通常都会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用。所以,Feign在此基础上做了进一步封装,由它来帮助我们定义和实现依赖服务接口的定义。在Feign的实现下,我们只需要创建一个接口并使用注解的方式来配置它(以前是Dao接口上面标注Mapper注解,现在是一个微服务接口上面标注一个Feign相关注解即可),即可完成对服务提供方的接口绑定,简化了使用Spring cloud Ribbon时,自动封装服务调用客户端的开发量。
Feign集成了Ribbon
利用Ribbon维护了Payment的服务列表信息,并且通过轮询实现了客户端的负载均衡。而与Ribbon不同的是,通过Feign只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用
Feign 和 OpenFeign的区别
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FwlgPhRQ-1595411658300)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200628182711948.png)]
OpenFeign使用步骤
OpenFeign的服务调用
OpenFeign天生自带负载均衡
一句话:接口+注解
OpenFeign超时控制
演示一下超时的情况
服务端模块故意写一个超过3秒的业务,而OpenFeign客户端默认是只等待一秒钟,超时就直接返回报错
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MDlcdnDW-1595411658301)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200629152512701.png)]
为了避免这种情况,有时候我们需要设置Fiegn客户端的超时控制
###yml文件中开启配置
OpenFeign天生自带Ribbon,那么我们在超时控制的时候就交由Ribbon来解决
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ASZ297H3-1595411658302)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200629153353520.png)]
OpenFign日志打印功能
Feign提供了日志打印功能,我们可以通过配置来调整日志级别,从而了解Feign中Http请求的细节。
说白了就是对Feign接口的调用情况进行监控和输出
日志级别
- NONE:默认的,不显示任何日志;
- BASIC:仅记录请求方法、URL、响应状态码及执行时间;
- HEADERS:除了BASIC中定义的信息之外,还有请求和响应的头信息;
- FULL:除了HEADERS中定义的信息之外,还有请求和响应的正文及源数据。
yml配置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xT2XuhsD-1595411658303)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200629154342975.png)]
还需要再写一个配置类,注册Bean
@Configuration
public class FeignConfig {
@Bean
Logger.Level feignLoggerLevel(){
return Logger.Level.FULL;
}
}
第八讲–Hystrix断路器
停止更新,但出道即巅峰。它的服务降级、服务熔断、服务限流、服务隔离等等设计思想特别优秀
概述
###分布式系统面临的问题
复杂分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免地失败,比如网络卡顿、调用超时、程序出错等等
服务雪崩:多个微服务之间调用的时候,假设微服务A调用微服务B和微服务C,微服务B和微服务C又调用其它的微服务,这就是所谓的"扇出"。如果扇出的链路上某个微服务的调用响应时间过长或者不可用,对微服务A的调用就会占用越来越多的系统资源,进而引起系统崩溃,所谓的"雪崩效应"。
对于高流量的应用来说,单一的后端依赖可能会导致所有服务器上的所有资源都在几秒钟内饱和。比失败更糟糕的是,这些应用程序还可能导致服务之间的延迟增加,备份队列,线程和其他系统资源紧张,导致整个系统发生更多的级联故障。这些都表示需要对故障和延迟进行隔离和管理,以便多个依赖关系的失败,不能取消整个应用程序或系统。
所以,通常当你发现一个模块下的某个实例失败后,这时候这个模块依然还会接收流量,然后这个有问题的模块还调用了其他的模块,这样就会发生级联故障,或者叫雪崩。
是什么?
Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,Hystrix能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。
"断路器"本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个服务预期的、可处理的备选响应(FallBack),而不是长时间的等待或者抛出调用方法无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。
能干嘛?
服务降级
服务熔断
接近实时的监控
限流、隔离。。。
Hystrix重要概念
服务降级–fallback
服务器忙,请稍后再试,不让客户端等待并立刻返回一个友好提示,fallback。也就是要有一个兜底的方案
哪些情况会触发降级:
- 程序运行异常
- 超时
- 服务熔断触发服务降级
- 线程池/信号量打满也会导致服务降级
服务熔断–break
类比保险丝达到最大服务访问后,直接拒绝访问,拉闸限电,然后调用服务降级的方法并返回友好提示
就是保险丝:服务的降级->进而熔断->恢复调用链路
服务限流–flowlimit
秒杀高并发等操作,严禁一窝蜂的过来拥挤,大家排队,一秒钟N个,有序进行
hystrix案例
###服务降级
有两个接口响应服务,一个是立即返回,一个是等待3秒返回。正常情况下是ok的
在高并发情况下,观测结果,立即返回的那个请求也要转圈了。
原因就是:tomcat的默认的工作线程数被打满了,没有多余的线程来分解压力和处理。
结论:上面还是服务提供者8001自己测试,假如此时外部的消费者80也来访问,那消费者只能干等,最终导致消费端80不满意,服务端8001直接被拖死
上述结论:正因为有上述故障或不佳表现,才有我们的降级/容错/限流等技术诞生
如何解决?解决的要求
超时导致服务器变慢(转圈)–>超时不再等待
出错(宕机或程序运行出错)–>出错要有兜底
解决:
- 对方服务(8001)超时了,调用者(80)不能一直卡死等待,必须要有服务降级
- 对方服务(8001)宕机了,调用者(80)不能一直卡死等待,必须要有服务降级
- 对方服务(8001)OK,调用者(80)自己出故障或有自我要求(自己的等待时间小于服务提供者),自己处理降级
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wviTkzOg-1595411658304)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200629182926510.png)]
需要在启动类上方添加一个注解用于激活Hystrix 服务降级
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MA7D2YAg-1595411658305)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200629183026021.png)]
在客户端和服务端都做了服务降级之后,会出现一个问题,每个业务方法对应一个兜底的方法,会造成代码膨胀。兜底方法和业务方法放在一起会造成耦合度特别高,混乱
统一和自定义的分开
代码膨胀:
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sUYCyJGD-1595411658306)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200630112518664.png)]
- 通用的和独享的肚子分开,避免了代码膨胀,合理减少了代码量,O(∩_∩)O哈哈~
代码混乱:
- 我们在工作中经常会遇到的问题就是:程序出错、超时、宕机,前两个我们已经模拟过了,现在就模拟个宕机的,顺便来解决代码混乱的问题
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q6EiOpmX-1595411658307)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200630114032215.png)]
- 创建一个类,来实现Feign的接口,然后再FeignClient里添加fallback
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BLZgnzZG-1595411658308)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200630114127101.png)]
- 服务端已经宕机,我们消费端做了服务降级,不会去重试。我们自己设计兜底方案来处理。
服务熔断
断路器
就可以类比家里的保险丝
熔断是什么?
熔断机制是应对雪崩效应的一种微服务链路保护机制。当扇出链路的某个微服务出错不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回错误的响应信息。
当检测到该节点微服务调用响应正常后,恢复调用链路。
在Spring Cloud框架里,熔断机制通过Hystrix实现。Hystrix会监控微服务间调用的状况,当失败的调用到一定阈值,缺省是5秒内20次调用失败,就会启动熔断机制。熔断机制的注解是@HystrixCommand。
实操:
//=====服务熔断
@HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback",commandProperties = {
@HystrixProperty(name = "circuitBreaker.enabled",value = "true"),// 是否开启断路器
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"),// 请求次数
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10000"),//时间窗口期
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60"),//失败率达到多少后跳闸
})
public String paymentCircuitBreaker(@PathVariable("id") Integer id){
if (id<0){
throw new RuntimeException("******id 不能负数");
}
String serialNumber = IdUtil.simpleUUID();
return Thread.currentThread().getName()+"\t"+"调用成功,流水号:"+serialNumber;
}
public String paymentCircuitBreaker_fallback(@PathVariable("id")Integer id){
return "id 不能负数,请稍后再试 o(╥﹏╥)o id:"+id;
}
熔断的三种状态:
- 熔断打开:请求不再进行调用当前服务,内部设置时钟一般为MTTR(平均故障处理时间),当打开时长达到所设时钟则进入半熔断状态
- 熔断关闭:熔断关闭不会对服务进行熔断
- 熔断半开:部分请求根据规则调用当前服务,如果请求成功且符合规则则认为当前服务恢复正常,关闭熔断
短路器在什么情况下开始起作用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0ftcvszp-1595411658310)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200630143154799.png)]
涉及到断路器的三个重要参数:快照时间窗、请求总数阈值、错误百分比阈值
- 快照时间窗:断路器确定是否打开需要统计一些请求和错误数据,而统计的时间范围就是快照时间窗,默认为最近的10秒
- 请求总数阈值:在快照时间窗内,必须满足请求总数阈值才有资格熔断。默认为20,意味着在10秒内,如果该Hystrix命令的调用次数不足20次,即使所有的请求都超时或其他原因失败,短路器都不会打开。
- 错误百分比阈值:当请求总数在快照时间窗内超过了阈值,比如发生了30次调用,如果在这30次调用中,有15次发生了超时异常,也就是超过50%的错误百分比,在默认设定50%阈值情况下,这时候就会将断路器打开。
断路器开启或关闭的条件
- 当满足一定的阈值的时候(默认10秒内超过20个请求次数)
- 当失败率达到一定的时候(默认10秒内超过50%的请求失败)
- 到达以上阈值,断路器将会开启
- 当开启的时候,所有请求都不会进行转发
- 一段时间(默认是5秒),这个时候断路器是搬开状态,会让其中一个请求进行转发。如果成功,断路器会关闭,若失败,继续开启。重复4和5
断路器打开之后
- 再有请求调用的时候,将不会调用主逻辑,而是直接调用降级fallback。通过断路器,实现了自动地发现错误并将降级逻辑切换为主逻辑,减少响应延迟的效果。
- 原来的主逻辑要如何恢复呢?
- 对于这一问题,hystrix也为我们实现了自动恢复功能。
- 当断路器打开,对主逻辑进行熔断之后,hystrix会启动一个休眠时间窗,在这个时间窗内,降级逻辑是临时的成为主逻辑,当休眠时间窗到期,断路器将进入半开状态,释放一次请求到原来的主逻辑上,如果此次请求正常返回,那么断路器将继续闭合,主逻辑恢复,如果这次请求依然有问题,断路器继续进入到打开状态,休眠时间窗重新计时。
All配置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vBTc8CiC-1595411658312)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200630144623906.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-maR0c5hd-1595411658314)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200630144636666.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-11Yd4v9N-1595411658315)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200630144717967.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O87jKESP-1595411658316)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200630144734057.png)]
hystrix工作流程
服务监控hystrixDashboard
除了隔离依赖服务的调用以外,Hystrix还提供了准实时的调用监控(Hystrix Dashboard),Hystrix会持续地记录所有通过Hystrix发起的请求的执行信息,并以统计报表和图形的形式展示给用户,包括每秒执行多少请求多少成功,多少失败等。Netflix通过hystrix-metrics-event-stream项目实现了对以上指标的监控。Spring Cloud也提供了Hystrix Dashboard的整合,对监控内容转化成可视化界面
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c2Qb8SML-1595411658318)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200630151604383.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VxGDtdYq-1595411658319)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200630151619027.png)]
实心圆:共有两种含义。它通过颜色的变化代表了实例的健康程度,它的健康度从绿色<黄色<橙色<红色递减
该实心圆除了颜色的变化之外,它的大小也会根据实例的请求流量发生变化,流量越大,该实心圆就越大。所以通过该实心圆的展示,就可以在大量的实例中快速的发现故障实例和高压力实例。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vMpM30O3-1595411658320)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200630152108872.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zBNVWXXQ-1595411658321)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200630152116406.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xNXNRmCO-1595411658322)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200630152140817.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UMC2wIXs-1595411658323)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200630152223808.png)]
第九讲–zuul路由网关
不再讲
第十讲–Gateway新一代网关
概述简介
SpringCloud Gateway是SpringCloud的一个全新项目,基于spring5.0+springboot2.0和Project Reactor等技术开发的网关,它旨在为微服务提供一种简单有效的统一的API路由管理方式。
SpringCloud Gateway作为Spring Cloud生态系统中的网关,目标是替代Zuul,在spring Cloud 2.0以上版本中,没有对新版本的Zuul2.0以上最新高性能版本进行集成,仍然还是使用Zuul1.x非Reactor模式的老版本。而为了提升网关的性能,SpringCloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty。
SpringCloud Gateway的目标提供统一的路由方式且基于Filter链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流
能干嘛
- 反向代理
- 鉴权
- 流量控制
- 熔断
- 日志监控
- 。。。
在哪里
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SuqxZws4-1595411658324)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200630155325573.png)]
为什么有了Zuul,还要出Gateway
- Netflix不太靠谱,zuul2.0一直跳票,迟迟不发布
- SpringCloud Gateway具有如下特性
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qUXXFQJx-1595411658325)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200630155753017.png)]
- SpringCloud Gateway与Zuul的区别
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KFbP3bfU-1595411658326)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200630155828502.png)]
- zuul1.x模型
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BWFKGU3H-1595411658327)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200630160309036.png)]
- Gateway模型
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lqueNqpC-1595411658327)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200630160415777.png)]
三大核心概念
Route(路由):路由是构建网关的基本模块,它由ID,目标URI,一系列的断言和过滤器组成,如果断言为true,则匹配该路由
Predicate(断言):参考的是Java8的java.util.function.Predicate,开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由
Filter(过滤):指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t0bHu9Eh-1595411658328)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200630161306716.png)]
Gateway工作流程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NoDaRpzD-1595411658329)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200630161826431.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pqjjqni1-1595411658330)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200630161949881.png)]
核心逻辑:路由转发+执行过滤器链
入门配置
server:
port: 9527
spring:
application:
name: cloud-gateway
cloud:
gateway:
routes:
- id: payment_routh #payment_route #路由的ID,没有固定规则但要求唯一,建议配合服务名
uri: http://localhost:8001 #匹配后提供服务的路由地址
predicates:
- Path=/payment/get/** #断言,路径相匹配的进行路由
- id: payment_routh2 #payment_route #路由的ID,没有固定规则但要求唯一,建议配合服务名
uri: http://localhost:8001 #匹配后提供服务的路由地址
predicates:
- Path=/payment/lb/** #断言,路径相匹配的进行路由
eureka:
instance:
hostname: cloud-gateway-service
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c5GZh4WR-1595411658331)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200630164730944.png)]
Gateway配置路由的两种方式
第一种就是上面的yml配置
第二种是硬编码,通过Bean配置
@Configuration
public class GatewayConfig {
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder){
RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
routes.route("path_route_markus",
r -> r.path("/guonei").uri("http://news.baidu.com/guonei")).build();
return routes.build();
}
}
通过微服务名实现动态路由
默认情况下Gateway会根据注册中心注册的服务列表,以注册中心上微服务名为路径创建动态路由进行转发,从而实现动态路由的功能
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pZryKxbB-1595411658332)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200630172047754.png)]
Predicate的使用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-huicH2tm-1595411658333)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200630172744601.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YVGmnD5V-1595411658334)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200630172756975.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9S13Am0d-1595411658335)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200630172958325.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KUoaQ5De-1595411658336)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200630174713168.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MVHSrE3G-1595411658336)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200630175220751.png)]
常见的Route Predicate
- After Route Predicate:在什么时间点以后访问才给转发
- Before Route Predicate:在指定时间点以前访问才给转发
- Between Route Predicate:在指定时间段之间才能转发
- Cookie Route Predicate:需要两个参数,一个是Cookie name,一个是正则表达式。路由规则会通过获取对应的Cookie name值和正则表达式去匹配,如果匹配上,则执行该路由,如果匹配不上就不执行
- Header Route Predicate:两个参数,一个是属性名称和一个正则表达式,这个属性和正则表达式匹配则执行
- Host Route Predicate:指定主机
- Method Route Predicate:指定请求方法
- Path Route Predicate:
- Query Route Predicate:
- Query=username, \d+ #要有参数名称并且是正整数才能路由
Filter的使用
简介
路由过滤器可用于修改进入的Http响应,路由过滤器只能指定路由进行调用
springcloud Gateway内置了多种过滤器,他们都由Gateway Filter的工厂来产生
它的生命周期只有两个,pre–>post,在业务逻辑前和在业务逻辑后
种类有两个:单一过滤器31种之多,全局过滤器有10种
使用
其实在过滤器这块,常用的还是自定义过滤器。下面记录下怎么使用它
两个主要接口 Global Filter,Order
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H9p2JLm4-1595411658337)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200701144214214.png)]
能干嘛?
全局日志记录、统一网关鉴权、等等
第十一讲–SpringCloud Config
分布式配置中心
概述
分布式系统面临的问题:配置问题,系统中必定会出现大量的重复的配置文件
是什么:
- SpringCloud Config为微服务架构中的微服务提供集中化的外部配置支持,配置服务器为各个不同微服务应用的所有环境提供了一个中心化的外部配置
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LiueeMoi-1595411658338)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200701145224617.png)]
怎么玩:
- SpringCloud Config分为服务端和客户端两部分。
- 服务端也成为分布式配置中心,它是一个独立的微服务应用,用来连接配置服务器并为客户端提供获取配置信息,加密/解密信息等访问接口
- 客户端则是通过指定的配置中心来管理应用资源,以及与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息配置服务器默认采用git来存储配置信息,这样就有助于对环境配置进行版本管理,并且可以通过git客户端工具来方便的管理和访问配置内容。
能干嘛:
- 集中管理配置文件
- 不同环境不同配置,动态话的配置更新,分环境部署比如dev/test/prod/beta/release
- 运行期间动态调整配置,不再需要在每个服务部署的机器上编写配置文件,服务会向配置中心统一拉取配置自己的信息
- 当配置发生变动时,服务不需要重启即可感知到配置的变化并应用新的配置
- 将配置信息以REST接口的形式暴露–post、curl访问刷新均可…
Config服务端配置与测试
配置读取规则:
- /{label}/{application}-{profile}.yml
- master分支
- http://config-3344.com:3344/master/config-dev.yml
- http://config-3344.com:3344/master/config-test.yml
- http://config-3344.com:3344/master/config-prod.yml
- master分支
- /{application}-{profile}.yml
- /{application}/{profiile}/{lebel}
label:分支(branch)
name:服务名
profiles:环境(dev/test/prod)
Config客户端配置与测试
application.yml:是用户级的资源配置项
bootstrap.yml是系统级的,优先级更加高
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vJDOwDin-1595411658339)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200701160006315.png)]
新建一个模块,编写bootstrap.yml
server:
port: 3355
spring:
application:
name: cloud-client
cloud:
#Config客户端配置
config:
label: master # 分支名称
name: config # 配置文件名称
profile: dev # 读取后缀名称 上述3个综合:master分支上的config-dev.yml的配置文件被读取http://config-3344.com:3344/master/config-dev.yml
uri: http://localhost:3344 #配置中心地址
#服务注册到eureka地址
eureka:
client:
service-url:
defaultZone: http://eureka7001.com:7001/eureka
成功试下了客户端3355访问SpringCloud Config3344通过GitHub获取配置信息
问题来了,分布式配置的动态刷新问题
- linux运维修改GitHub上的配置文件内容做调整
- 刷新3344,发现ConfigServer配置中心立刻响应
- 刷新3355,发现ConfigClient客户端没有任何响应
- 3355没有变化除非自己重启或者重新加载
- 难道每次运维修改配置文件,客户端都需要重启???噩梦
##Config客户端之动态刷新
避免每次更新配置都要重启客户端微服务
在客户端yml中配置
# 暴露监控端点
management:
endpoints:
web:
exposure:
include: "*"
在业务Controller层上面打上@RefreshScope注解
测试发现没有生效?
解决:
- 需要运维人员发送Post请求刷新3355
- curl -X POST “http://localhost:3355/actuator/refresh”
没有重启客户端,刷新之后,发现生效了。
成功实现了客户端3355刷新到最新配置内容–避免了服务重启
想想还有什么问题?
- 假如有多个微服务客户端…
- 每个微服务都要执行一次post请求,手动刷新?
- 可否广播,一次通知,处处生效
- 我们想大范围的自动刷新,求方法
- 引入消息总线
第十二讲–SpringCloud Bus
消息总线
概述
上一讲解的加深和扩充—分布式自动刷新配置功能
是什么:
- Bus支持两种消息代理:RabbitMQ和Kafka
- SpringCloud Bus配合SpringCloud Config使用可以实现配置的动态刷新
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c6yGLy30-1595411658340)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200701164628559.png)]
- SringCloud Bus是用来将分布式系统的节点与轻量级消息系统链接起来的框架,它整合了Java的事件处理机制和消息中间件的功能。SpringCloud Bus目前支持RabbitMQ和Kafka
能干嘛:
- SpringCloud Bus能管理和传播分布式系统间的消息,就像一个分布式执行器,可用于广播状态更改、时间推送等,也可以当做微服务间的通信通道。
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-goSbwzmd-1595411658341)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200701165116297.png)]
为何被称为总线:
- 什么是总线:在微服务架构的系统中,通常会使用轻量级的消息代理来构建一个共用的消息主题,并让系统中所有微服务实例都连接上来。由于该主题中产生的消息会被所有实例监听和消费,所以称它为消息总线。在总线上的各个实例,都可以方便地广播一些需要让其他连接在该主题上的实例都知道的消息。
- 基本原理:ConfigClient实例都监听MQ中同一个topic(默认是SpringCloudBus)。当一个服务刷新数据的时候,它会把这个信息放入到topic中,这样其它监听同一Topic的服务就能得到通知,然后去更新自身的配置。
RabbitMQ环境配置
先安装Erlang
SpringCloud Bus动态刷新全局广播
设计思想
- 利用消息总线触发一个客户端/bug/refresh,而刷新所有的客户端的配置[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HxX8gbHh-1595411658342)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200710152006599.png)]
- 利用消息总线触发一个服务端ConfigServer的/bug/refresh端点,而刷新所有客户端的配置[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KQYaNChv-1595411658343)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200710152024840.png)]
- 图二的架构显示更加适合
- 打破了微服务的职责单一性
- 破坏了各个节点之间的对等性
- 有一定的局限性,例如微服务在迁移时,它的网络地址常常会发生变化,想自动刷新,会增加更多的修改
##SpringCloud Bus动态刷新定点通知
第十五讲–SpringCloud Alibaba简介
能干嘛?
- 服务限流降级:默认支持Servlet、Feign、 RestTemplate、 Dubbo 和RocketMQ限流降级功能的接入,可以在运行时通过控制台实时修改限流降级规则,还支持查看限流降级Metrics监控。
- 服务注册与发现:适配Spring Cloud服务注册与发现标准,默认集成了Ribbon的支持。
- 分布式配置管理:支持分布式系统中的外部化配置,配置更改时自动刷新。
- 消息驱动能力:基于Spring Cloud Stream为微服务应用构建消息驱动能力。
- 阿里云对象存储:阿里云提供的海量、安全、低成本、可靠的云存储服务。支持在任何应用、任何时间、任何地点存储和访问任意类型的数据。
- 分布式任务调度:提供秒级、精准、可靠、高可用的定时(基于Cron表达式)任务调度服务。同时提供分布式的任务执行模型,如网格任务。网格任务支持海量子任务均匀分配到所有Worker (schedulerx -client).上执行。
去哪下?
https://github.com/alibaba/spring-cloud-alibaba/blob/master/README-zh.md
第十六讲–SpringCloud Alibaba Nacos服务注册和配置中心
Nacos的简介和下载
为什么叫Nacos
前四个字母分别是Naming 和 Configuration,最后的s为Service
是什么
是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台
就是注册中心+配置中心的组合 ==== eureka+config+bus
能干嘛
替代Eureka做服务注册中心
替代Config做服务配置中心
去哪下
Nacos服务注册中心对比与提升
服务注册与发现框架 | CAP模型 | 控制台管理 | 社区活跃度 |
---|---|---|---|
Eureka | AP | 支持 | 低(2.x版本闭源) |
Zookeeper | CP | 不支持 | 中 |
Consul | CP | 支持 | 高 |
Nacos | AP/CP | 支持 | 高 |
据说Nacos在阿里巴巴内部有超过10万的实例运行,已经过了类似双十一等各种大型流量的考验
注意观察表里的Nacos,它是支持AP和CP的,但是不能支持CAP,在AP和CP之间可以来回切换
我们先来看看Nacos全景图所示
Nacos和CAP
C是所有节点在同一时间看到的数据是一致的; 而A的定义是所有的请求都会收到响应。
何时选择使用何种模式?
一般来说,如果不需要存储服务级别的信息且服务实例是通过nacos- client注册,并能够保持心跳上报,那么就可以选择AP模式。当前主流的服务如Spring doud和Dubbo服务,都适用于AP模式,AP模式为了服务的可能性而减弱了一致性, 因此AP模式下只支持注册临时实例。如果需要在服务级别编辑或者存储配置信息,那么CP是必须, K8S服务和DNS服务则适用于CP模式。CP模式下则支持注册持久化实例,此时则是以Raft协议为集群运行模式,该模式下注册实例之前必须先注册服务,如果服务不存在,则会返回错误。
Nacos之服务配置中心
Nacos之命名空间分组和DataID三者关系
问题1:
实际开发中,通常一个 系统会准备
dev开发环境
test测试环境
prod生产环境。
如何保证指定环境启动时服务能正确读取到Nacos.上相应环境的配置文件呢?
问题2:
一个大型分布式微服务系统会有很多微服务子项目,
每个微服务项目又都会有相应的开发环境、测试环境、预发环境、正式环境…
那怎么对这些微服务配置进行管理呢?
三者关系?为什么这么设计?
NameSpace+Group+DataID
1.是什么
类似java里面的package名和类名
最外层的namespace是可以用于区分部署环境的,Group和DataID逻辑上区分两个目标对象
2.三者情况
默认情况
Namespace=pulic,Group=DEFAULT_GROUP,默认Cluster是DEFAULT
Nacos默认的命名空间是public, Namespace主要用来实现隔离。
比方说我们现在有三个环境:开发测试、铲环境,我们就可以创建= E个Namespace,不同的Namespace之间是隔离的。
Group默认是DEFAULT_ GROUP, Group可以把不同的微服务划分到同一个分组里面去
Service就是微服务;一个Service可以包含多 个Cluster (集群),Nacos默认Cluster是DEFAULT, Cluster是对指定微服务的一个虚拟划分。
比方说为了容灾,将Service微服务分别部署在了杭州机房和广州机房,
这时就可以给杭州机房的Service微服务起一个集群名称(HZ),
给广州机房的Service微服务起一个集群名称 (GZ) , 还可以尽量让同-个机房的微服务互相调用,以提升性能。
后是Instance,就是微服务的实例。
3.分组方案
4.Namespace
Nacos集群和持久化配置(重要)
架构说明
问题
默认Nacos使用嵌入式数据库实现数据的存储。所以,如果启动多个默认配置下的Nacos节点,数据存储是存在一 致性问题的。为了解决这个问题,Nacos采用了集中式存储的方式来支持集群化部署,目前只支持MySQL的存储。
Nacos 持久化切换配置
找到nacos下的conf下的application.properities里面的注释去掉:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4RpPCyuy-1595411658356)(C:\Users\14222\AppData\Roaming\Typora\typora-user-images\image-20200722170002378.png)]
先去执行conf下的nacos-mysql.mysql语句,然后将上图这些原本注释掉的信息取消注释,重启nacos,成功。
Nacos+MySQL生产环境配置
推荐linux系统,预计需要1个Nginx+3个nacos注册中心+1个mysql
nacos下载linux版
集群配置步骤