1.架构的演进
架构为什么要演进,随着互联网的高速发展,业务场景越来越复杂,以往的架构已经无法满足现在的需求,这时架构就需要进行演进,直到符合需求为止
发展的特点
- 业务功能越来越多,越来越复杂
- 万物互联,数据量越来越大
- 请求量越来越大,更高的用户体验要求
- 业务快速迭代,持续交付的能力
架构演进图
2.单体架构
单体架构是早期互联网常用的架构,所有的功能都在同一个项目中开发,打出来的就是一个war包
适用场景
- 业务简单、功能简单、研发人员较少
- 创业公司的初期
- 性能要求苛刻
单体架构优点
- 服务器成本低
- 部署简单
- 开发简单
单体架构缺点
- 系统耦合高
- 技术选型单一
- 开发效率越来越低下
单体架构图
单体架构扩展图
如果解决单点的痛点?
- 数据库数据量大的处理方式
- 拆分
- 垂直拆分(分库)
- 水平拆分(分表)
- 拆分
- 架构同理
- 垂直拆分(业务维度)
- 水平拆分(功能维度)
3.水平分层架构
水平是按功能拆分的一种粗粒度拆分,把一个整体项目按功能水平方向拆分成多个独立的进程,部署到多台不同机器运行
水平分层架构图
拆分规则
从水平分层架构图中可以看出,层与层之间分离,单向依赖
- 业务逻辑服务层分离数据访问服务层
- 网关服务层分离业务逻辑服务层
- 展示层分离网管服务层
他们的依赖关系是
- 业务逻辑服务层依赖数据访问服务层
- 网关服务层依赖业务逻辑服务层
- 展示层依赖网关服务层
每层的功能
-
网关层
- 请求鉴权
- 比如是否登录
- 数据完整性检查
- 检查请求格式是否完整
- 协议转换
- http或https转为tcp,rpc也是一种tcp
- 服务与服务之间一般是用tcp进行通信,因为http的连接效率与传输效率不高
- 数据协议转换
- json太大了,一般需要使用数据协议进行压缩
- 路由转发
- 转发不同的业务逻辑服务层
- 服务治理
- 限流、降级、熔断等
- 请求鉴权
-
业务逻辑层
- 业务逻辑处理
-
数据访问层
- 数据的增删改查
- ORM框架
- 分库分表(使用NewSql方案代替)
- 屏蔽底层存储差异性
同步架构与异步架构
同步架构是指请求经过所有路径并原路返回,比如说app请求到nginx,nginx转发到网关,网关转发到业务逻辑服务层,业务逻辑服务层请求到数据访问服务层,数据访问服务层再访问DataBase,最后再由DataBase原路返回,当业务并发量大的时候每个请求都要经过所有路径并原路返回,导致连接占用时间较长,无法腾出空闲连接给其他请求使用,最终无法应对并发量大的场景,所以需要异步架构来应对
所以异步架构就是在两层之间在加入一个中间队列层,上层只有队列层交互进行同步,下层也只与队列层交互,达到上下层解耦,架构图如下
异步架构
- 异步的目的
- 提升吞吐量
- 异步的手段
- 消息队列
- 异步的请求类型
- 写请求
- 异步的业务类型
- 数据一致性弱或非核心主流程业务
案例
- 识别并发量高低
在微信中发消息与发红包那个频率更高,肯定是发消息,于发消息来说是高并发量,发红包是低并发量
- 识别弱一致性与强一致性
充值业务就是强一致性,充值的时候不能直接返回充值成功,万一银行卡余额不足或异步充值失败,这都出现严重问题的。
发微信朋友圈就是弱一致性,你们好友不关心你什么时候发送的朋友圈,只要最后他们都能看到就行了
- 异步写和同步读取场景
一般发送完微信朋友圈,最想看到这条消息的必然是我们自己,当我们发完立即去看的时候,有可能异步还在执行,并没把这条数据写入db,此时我们看到的数据不是最新发送,这种情况该怎么办,一般在发送之后会在微信客户端缓存起来,当你第二次再去看的时候,如果发现db有的话,就会把缓存刷新成最新db的,如果异步处理失败,朋友圈会提示你重新发送
架构层次
- 同步架构(4层)
- 网关层
- 业务逻辑层
- 数据库层
- 数据存储层
- 异步架构(5层)
- 网关层
- 异步消息队列层
- 业务逻辑层
- 数据库层
- 数据存储层
异步架构图
4.垂直拆分架构
垂直是按业务拆分的一种粗粒度拆分,把一个整体项目按业务垂直方向拆分成多个独立的进程,部署到多台不同机器运行
垂直分层架构图
垂直拆分这块没太多可讲的,规则就是按业务拆分,但是每个业务服务内部的分层需要与水平拆拆分一样,保持单向依赖,不要同级调用,每个业务服务之间的调用也要明确好在内部分层里面的某一层调用,一般加入facade层
5.微服务架构
微服务架构其实就是水平+垂直两个维度的拆分
微服务架构图
从上图我们可以看出来,它也是单向依赖,服务之间调用是通过数据访问层,千万别打破单向依赖的规则,进行同级调用,这样很容易引起循环调用,比如系统a的业务层a-1方法调用了系统b的业务层b-1方法,而b-1方法里面又调用了a-1方法,这样就会引起循环调用,把系统跑死,可是有时候当前系统需要某些系统的业务层方法,难道我们又在当前系统重新冗余一份嘛,答案是否定的,这种业务层的方法需要被其他系统的业务层引用,说明它是公用的,那么我们需要下层一个公用业务层,如下图
每个系统的业务逻辑层都可以调用公用业务逻辑层与数据访问层,而公用业务逻辑层只能调用数据访问
6.服务网格
服务网格这块待后面会专门单独写一篇文章
7.总结
分布式优点
- 系统解耦,提高开发效率
- 真正的物理层面分离,分布式计算,流量分散
- 更有针对性优化、调整、重构
- 系统故障缩小影响范围
- 不受语言限制
- 不受语言限制带来的成本是非常高的,意味着你不同语言都要开发对应的sdk服务通信包,所以服务网格就是处理这种问题的,它统一了通信包
分布式缺点
- 请求路径变长
- 平均响应延迟变高
- 定位问题变得复杂
- 运维成本高
- 机器成本高
- 开发人员成本高
- 技术成本高,服务太多,要考虑限流、降级熔断等
依赖规则
- 单向依赖
- 由上到下,上层只能调用下层
- 禁止同级调用,同级调用会使关系变成网状,导致调用关系复杂,增加写出了循环调用的概率,特别是分布式环境下这种概率更大,因为双方都不知道对方写的代码细节
架构的好坏
架构是演进而来,演进是随着业务的变化,架构没有好坏之分,只有适不适合当前业务场景,能不能解决碰到的瓶颈,适合当前公司发展阶段的架构就是好的架构。