微服务架构编程思想
单体架构:
传统企业采用单体架构
- 纵向拆分:三层架构(control、services、dao)
- 横向拆分:业务间相互独立,划分不同模块(注册模块、登录模块、支付模块等)
缺点:
- 单点故障(一个服务挂了拖累整个系统)。
- 不同服务不能单独扩展
微服务架构
特点:微服务架构是一种思想,架构就是为了解耦,实际的开发方式是分布式系统开发。我们将单体架构项目按服务拆分,单个服务部署在单独的节点上,项目仍然使用三层架构。(单个服务仍可继续拆分即领域驱动设计ddd,例如订单里面包含的商品可以进行继续拆分)
- 具体开发方式:SpringBoot+SpringCloud
- SpringCloud是一个编程模型,不是框架,微服务开发的一种标准即一系列的接口
- SpringCloud NetFlix
- SpringCloud Alibaba
微服务架构满足条件与解决问题:
三大指标
高可用:服务一直可用。
高性能:响应快一点,更快一点。(单体性能最高,但是扛不住并发)
高并发:系统承载能力。
如何应对高并发?
垂直扩展:加内存,升级cpu
水平扩展:多买服务器
计算密集型或内存密集型(redis)
Nginx(轮询、hash一致性、权重等)
Mysql问题
单体故障
性能瓶颈:b+tree索引,分页16kb,IO检索次数,索引存储空间等问题,因此单表数据不能超过2100w条
分库分表方式 User_xx.user_xx
数据库 User_0 192.168.1.1 数据表 user_0 ...... user_9 数据库 User_1 192.168.1.2 数据表 user_0 ...... user_9
- 产生问题:
1. 数据库间同步问题
1. 主从同步
2. 读写分离
3. 两台服务器,主主同步->主键冲突(数据库步长解决问题)
4. 多台服务器,主主同步->分布式主键(雪花算法)
1. 插入:分布式主键可以根据相关算法保存到对应的库和对应的表中
2. 查询
1. 产生聚合查询问题(可能某个人订单分布在不同库不同编号表里面)
1. 物理查询:select * from user查询
2. 逻辑查询:
1. 通过中间件直接拆分为
select * from user_0;
......
select * from user_*;
2. 在数据库之上加入分布式数据库中间件,非侵入式配置
1. MyCat(2w并发后有问题)
2. Sharding-Sphere(推荐)
5. 多活数据中心
1. 两地三活
2. 两地多活
6. 异地多活数据中心
2. 数据库去中心化:单库->单点故障->去中心化
- 四大问题
1. 这么多服务,客户端如何访问?
- 网关
- **Zuul**网关(反向代理,代理访问,同步并阻塞):所有从设备或网站来的请求都会经过Zuul到达后端的Netflix应用程序。Zuul提供了动态路由、监控、弹性负载和安全功能。
- Spring Cloud Gateway
- 服务注册中心:观察者模式(注册中心和网关存在异步通信机制,挂了会通知网关)
- **Eureka** Server注册中心
- 检测心跳,健康检查
2. 这么多服务,服务与服务间怎么通讯?
- 同步:
1. HTTP对外=》**Feign**
2. RCP对内=》Dubbo
- 异步:
1. MQ消息队列
3. 这么多服务,服务如何治理?
- 注册中心
- 链路追踪
- 日志收集ELK
4. 这么多服务,服务挂了怎么办?
- 熔断:隔离熔断,服务降级
1. **Hystrix**
- 负载均衡
1. **Ribbon**
-
一些常用组件区别
- Zookeeper:分布式协调机制,分布式锁(一般Redis做分布式锁更好用,支持红锁Redlock(解决脑裂问题)) 。不能拿来做注册中心,只是里面包含了观察者模式,性能非常低,早期Dubbo没有注册中心,所以拿ZK来做注册中心。
- Dubbo:只是一个通讯框架,不包含网关、熔断、治理[注册中心]
- Spring Cloud:编程模型->一系列接口
- Spring Cloud Netflix 一站式服务解决方案
- Spring Cloud Alibaba 一站式服务解决方案
分布式CAP原则
- 特点
- 一致性(C)->强一致性,原子性
- 强一致性
- 弱一致性
- 顺序一致性(按顺序)
- 最终一致性(不按顺序【BASE理论】)raft协议保证
- 可用性(A) ->高可用+高性能
- 分区容错性(P)时限内达成数据一致性(必须保证)
- 一致性(C)->强一致性,原子性
- 诞生概念
- CA: - **CP**:强一致性系统=》金融系统 - **AP**:高可用系统=》互联网系统
- 特点
BASE理论:对CAP中一致性和可用性权衡的结果
- 特点:保证服务一直可用
- 基本可以:允许出现故障时,允许部分损失部分可用
- 软状态:允许系统存在中间状态,不影响系统整体可用
- 最终一致性:数据经过一个副本后达到最终一致性
- 两阶段提交协议 (强一致):资源锁定相互等待
- 缺点:资源锁定性能差(开启了本地事务,会加锁,要互相等待)和可能存在单点故障(服务或者协调者挂了)。
- 优势:能保证强一致,成熟。
- 特点:
- 全局事务拆分成两个阶段来执行(协调者和参与者)
- 阶段一(投票阶段):准备阶段,协调者通知各个本地事务(参与者)完成本地的准备工作,询问是否可以执行事务,只要有一个反馈错误,则说明执行失败。
- 阶段二(提交阶段):执行阶段,各个本地事务根据上一阶段执行结果,进行提交或回滚。
- TCC (强一致):各阶段相互独立,不会相互等待,效率高。逻辑复杂,代码侵入性高。最终一致
- 特点:补偿机制
- try:资源检测和预留(冻结扣款,预留30元)
- comfirm:执行业务操作,要求try成功,confirm肯定也成功。(扣除30元)
- cancel:预留资源释放(释放预留的30元)
- 特点:补偿机制
- 可靠消息服务(最终一致):将远程分布事务拆分成一系列本地事务,依赖于MQ,解耦
- 消息可靠,不断重试,只到成功(最终一致)。限制了使用范围,从业务不能影响主业务。
- 注意事项:
- 事务发起者A必须保证本地事务成功后,消息一定发送成功。
- MQ必须保证消息正确投递和持久化保存(存数据库,扣款和写队列作为一个事务)。
- 事务参与者B必须确保消息一定能消费,如果失败多次重试。
- 事务B执行失败,会重试,但不会导致A回滚。
- RabbirMQ的消息确认:
- ack确认
- AT模式:类似于分阶段提交,但是底层拦截sql框架自动操作(Seata),执行失败,反向操作。同时实现了分段提交和tcc,资源锁定时间短。
- 特点:保证服务一直可用
Docker部署模式
- 一次构建多次运行
- 独立的虚拟服务器(一台容器中问题不影响其他容器【隔离机制】)
K8S:容器编排系统(管理docker)