- 单体应用架构
- 微服务架构
- SOA和微服务
- 分布式架构
- 需要解决的问题
- 消息队列
- 应用场景
- 异步
- 削峰
- 解耦
- 消息队列的缺点
- 常见消息中间件及特点
- 高并发
- 系统设计目标
- 高性能
- 高可用
- 高扩展
就是把所有的功能都写在一起,打包成一个应用,直接部署。
优点
- 开发、调试、部署方便
- 没有网络开销
缺点
- 系统耦合性高,开发效率低下
- 代码冗余,多人开发下问题多
- 语言单一,不能根据场景选择合适的语言
- 可靠度低,一个模块出错影响整个系统
- 不易于扩展,代码结构复杂,扩展困难
单体架构就相当于一个小诊所,挂号、诊断、买药都在一个屋子内,你不需要来回跑动去完成你想完成的事务。但是当业务复杂,科目多,药种类多时,很显然一个小诊所想要完成这些功能就会出现很大的冗余,于是我们就要将这业务横向分层、纵向分类。于是有了微服务架构。
微服务架构根据不同业务拆分出不同的服务,每个服务独立部署,独立运行,代码进行分离。
优点
- 耦合度降低,模块之间边界清晰
- 技术选型丰富,不同服务用不同语言
- 扩展方便,比如商品访问量大,就只用给商品服务扩容
缺点
- 改变顶层接口,改动量就大
- 有依赖关系,调用、测试麻烦
- 增加网络开销,性能变差;还有网络可靠性问题
微服务就像一个大医院,把挂号、诊断、取药分成了很多窗口,为了支持大业务量,不同类型病例实现业务隔离。单个业务与业务之间有走动开销,也就是调用的网络开销。
SOA和微服务SOA和微服务都是面向服务的架构
- SOA是中心化的,有一个总线进行交互,也就是ESB(用于整合服务的),需要按照总线的标准进行开发改造;微服务是去中心化的
- SOA注重的是企业资源的重复利用,把企业的各个应用通过 ESB 进行整合;而微服务注重的是应用级别的服务划分,使得应用内服务边界清晰,易扩展
由多个节点组成的系统,多个节点协同操作
整个系统中有的负责请求处理,有的负责存储,有的负责计算,最终他们相互协调把最后的结果返回并呈现给用户
- 微服务是架构设计方式,分布式是系统部署方式
- 把一个应用集群部署是分布式但不是微服务
简单来说就是不同的多台服务器上面部署不同的服务模块,他们通过Rpc/Rmi之间通信和调用,对外提供服务和组内协调
集群:不同的多台服务器上部署相同的服务模块,使用负载均衡访问
优点
- 增大系统容量
- 高可用,故障对系统的影响小
- 系统模块重用度高
- 模块拆分,开发速度快
- 扩展性高
- 多节点之间通信
- 并发安全性问题
- 调优:jvm ;IO
- 高可用:负载,故障处理策略
- 伸缩性:垂直,水平伸缩:访问量、数据量、计算能力;
消息队列 是指利用 高效可靠 的 消息传递机制 进行与平台无关的 数据交流,并基于 数据通信 来进行分布式系统的集成
应用场景 异步比如一个下单操作的业务流程很多(支付、优惠券、积分、短信等),客户买一个东西要很长时间,所以要异步。
我这个流程只管支付,剩下的操作发出消息交给别人,异步进行,需要一致性(分布式事务)
并发量大的时候,所有的请求直接怼到数据库,造成数据库连接异常
系统A慢慢的按照数据库能处理的并发量,从消息队列中慢慢拉取消息。在生产中,这个短暂的高峰期积压是允许的
解耦- 发送者和接受者不必了解对方、只需要 确认消息;
- 发送者和接受者 不必同时在线。
- 系统可用性降低:消息队列万一挂了就g了
- 系统复杂性增加:一致性问题、如何保证消息不被重复消费,如何保证消息可靠传输
高并发意味着大流量,我们需要运用技术手段抵抗流量的冲击,能让流量更平稳地被系统所处理,带给用户更好的体验
淘宝双十一;微博热点;秒杀系统;订单系统;
系统设计目标高性能、高可用、高扩展
高性能系统的并行处理能力;反映了用户的体验(响应时间)
性能指标
- 平均响应时间
- 吞吐量:单位时间内处理完成的请求量
实现方案
- 集群部署,通过负载均衡减轻单机压力。
- 多级缓存,包括静态数据使用CDN、本地缓存、分布式缓存等,以及对缓存场景中的热点key、缓存穿透、缓存并发、数据一致性等问题的处理。
- 分库分表和索引优化,以及借助搜索引擎解决复杂查询问题。
- 考虑NoSQL数据库的使用,比如HBase、TiDB等,但是团队必须熟悉这些组件,且有较强的运维能力。
- 异步化,将次要流程通过多线程、MQ、甚至延时任务进行异步处理。
- 限流,需要先考虑业务是否允许限流(比如秒杀场景是允许的),包括前端限流、Nginx接入层的限流、服务端的限流。
- 对流量进行削峰填谷,通过MQ承接流量。
- 缓存预热,通过异步任务提前预热数据到本地缓存或者分布式缓存中。
- 减少IO次数,比如数据库和缓存的批量读写、RPC的批量接口支持、或者通过冗余数据的方式干掉RPC调用。
- 减少IO时的数据包大小,包括采用轻量级的通信协议、合适的数据结构、去掉接口中的多余字段、减少缓存key的大小、压缩缓存value等。
- 程序逻辑优化,算法优化
- 各种池化技术的使用和池大小的设置,包括HTTP请求池、线程池(考虑CPU密集型还是IO密集型设置核心参数)、数据库和Redis连接池等。
- JVM优化,包括新生代和老年代的大小、GC算法的选择等,尽可能减少GC频率和耗时。
- 锁选择,读多写少的场景用乐观锁,分段锁
表示系统可以正常服务的时间,减少故障次数
可用性 = 平均故障时间 / 系统总运行时间
实现方案
- 节点故障转移,主从切换(redis的哨兵模式或者集群模式、MySQL的主从切换等)
- 接口层面的超时设置、重试策略
- 降级处理:保证核心服务,牺牲非核心服务,必要时进行熔断;或者核心链路出问题时,有备选链路
- 限流处理:对超过系统处理能力的请求直接拒绝或者返回错误码
- MQ场景的消息可靠性:(队列、消息持久化,发布确认)
- 监控报警:全方位的监控体系(CPU、内存、磁盘、网络,Web服务器、JVM、数据库、中间件)
表示系统的扩展能力,流量高峰时能否在短时间内完成扩容,更平稳地承接峰值流量
架构不改变,通过增加机器来提高性能
扩展性 = 性能提升比例 / 机器增加比例
像MySQL这种有状态的存储服务通常是扩展的技术难点,如果架构上没提前做好规划(垂直和水平拆分),就会涉及到大量数据的迁移
高扩展性需要考虑:服务集群、数据库、缓存和消息队列等中间件、负载均衡、带宽、依赖的第三方等,当并发达到某一个量级后,上述每个因素都可能成为扩展的瓶颈点
实现方案
- 合理的分层架构:业务层分层(MVC)
- 存储层拆分:按照业务维度做垂直拆分、按照数据特征维度进一步做水平拆分(分库分表)。
- 业务层拆分:微服务拆分业务



