分布式(微服务、SpringCloud)基础理论
架构演进
单体架构**
所有业务功能,系统架构等等都在一个应用中
特点:
• 所有功能在一同一个项目中开发
• 使用同一种语言和 框架开发
• 开发、测试、部署以项目为单位
但业务功能越来越多的时候,单体应用的体量会变的越来越大
分布式SOA**
将业务拆分成多个应用,并且互相通信协作,形成了分布式的架构,每个小应用被称为“服务”
此时的分布式架构,是基于服务的架构,又称为SOA架构。Service Oriented Architure
MSA(微服务)**
以开发一组小型服务的方式来开发一个独立的应用系统。
每个小型服务都运行在自己的进程中,经常采用HTTP资源API这样轻量的机制来相互通信。
通过全自动的部署机制来进行独立部署
可以使用不同的语言来编写,并且可以使用不同的数据存储技术。
理论基础
分布式定义**
一组部署在同一个网络下的多个通过网络来通信和协调的组件,对外是一个系统
其他理解:•可以指多个不同组件分布在网络上互相协作,比如前例所说的电商网站
•也可以一个组件的多个副本组成集群,互相协作如同一个组件,比如数据存储服务中为了数据不丢失而采取的多个服务备份冗余,当数据修改时也需要通信来复制数据
CAP定理
C:Consistency 一致性
A:Availability 可用性
P:Partition tolerance 分区容错性
CAP三个特性不能同时满足
一致性: 数据一致性
分布式存储系统,三个节点,数据都是重复了,为了容灾(可用性),提高吞吐率
可用性:集群可用
在集群中一部分节点故障后,集群整体是否还能正常响应客户端的读写请求。(对数据更新具备高可用性)
分区容错性: 处理网络故障造成分区
系统必须能够处理组件之间因为通信失败(或者延迟)而造成分区的情况。
SpringCloud定义
分布式 <=> 微服务(更深入)
公共的、通用的、基础设施性质的、一系列功能 => Spring Cloud
• 服务调用: 通信
• 负载均衡
• 分布式事务
• 线程锁=>分布式锁
• 分布式session
• 分布式日志追踪
Spring Cloud与SpringBoot的关系
Spring Cloud(架构工具集)是一个伞形项目,有多个子项目组成,Spring Cloud的每个子项目都是使用SpringBoot实现的
spring-cloud-alibaba
服务限流降级
服务注册与发现
分布式配置管理
消息驱动能力
分布式事务
阿里云对象存储
分布式任务调度
阿里云短信服务
最终选型
服务发现:[a]Nacos
服务调用:OpenFeign
负载均衡:Ribbon
服务容错:[a]Sentinel
配置管理:[a]Nacos
服务网关:Zuul
SpringCloud 微服务工具集 ,逐步形成自己的标准及实现
• SpringCloudNetflix 是子项目,提供的开源的某些组件的实现
• 服务发现组件: Eureka
• 服务调用组件: Feign
• 服务容错组件: Hystrix
• SpringCloudAlibaba
• 服务发现组件:Nacos
• 服务调用组件:Dubbo
• 服务容错组件:Sentinel
• 分布式事务组件:Seata
服务发现
分布式架构: 分布在同一个网络上的一组组件,互相通信和协作
获取服务地址
发起服务调用
得到结果处理
服务发现
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201112021256535.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L215X3owODI5,size_16,color_FFFFFF,t_70#pic_center
服务发现:找到需要调用的服务的地址
• 简单粗暴:将地址硬编码进代码中
• 无法应对服务的变化(新增、故障或下线、变更)
• 服务发现的要求
• 自动定位发现服务
• 应对新增、故障下线、变更
• 对调用方透明
常见服务注册表
服务发现
步骤:
① 服务注册: 服务提供者(user)在应用启动时注册到服务注册表(nacos)
②拉取服务: 需要时拉取服务
③健康检查:服务注册表需要跟服务保持连接
④变更通知:服务发生改变时注册表通知客户端
RestTemplate服务调用
1.添加一个RestTemplate的Bean
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
//向指定地址发送http请求,并将返回的结果转换为Result的实例
Result result = restTemplate.getForObject(uri + "/isBalanceSufficient?userId=" + userId + "&amount=" + 200.00, Result.class);
log.info("{}",result);
请求方式
POST:可传对象
PUT:可传对象
GET:
DELETE:不可传对象