你管这破玩意儿叫高可用?
前言
互联网架构剖析
接入层:主要由 F5 硬件或 LVS 软件来承载所有的流量入口
反向代理层:Nginx,主要负责根据 url 来分发流量,限流等
网关:主要负责流控,风控,协议转换等
站点层:主要负责调用会员,促销等基本服务来装配 json 等数据并返回给客户端
基础 service:其实与站点层都属于微服务,是平级关系,只不过基础 service 属于基础设施,能被上层的各个业务层 server 调用而已
存储层:也就是 DB,如 MySQL,Oracle 等,一般由基础 service 调用返回给站点层
中间件:ZK,ES,Redis,MQ 等,主要起到加速访问数据等功能,在下文中我们会简单介绍下各个组件的作用
接入层&反向代理层
微服务
中间件
ZK
Leader: 即领导者,在集群中只有一个 Leader,主要承担了以下的功能
事务请求的唯一调度和处理者,保证集群事务处理的顺序性,所有 Follower 的写请求都会转给 Leader 执行,用来保证事务的一致性
集群内部各服务器的调度者:处理好事务请求后,会将数据广播同步到各个 Follower,统计 Follower 写入成功的数量,超过半数 Follower 写入成功,Leader 就会认为写请求提交成功,通知所有的 Follower commit 这个写操作,保证事后哪怕是集群崩溃恢复或者重启,这个写操作也不会丢失。
Follower:
处理客户端非事务请求、转发事务请求给 leader 服务器
参与事物请求 Proposal 的投票(需要半数以上服务器通过才能通知 leader commit 数据; Leader 发起的提案,要求 Follower 投票)
参与 Leader 选举的投票
Redis
主从模式
Cluster 分片集群
主节点写的压力难以降低:因为只有一个主节点能接收写请求,如果在高并发的情况下,写请求如果很高的话可能会把主节点的网卡打满,造成主节点对外无法服务
主节点的存储能力受到单机存储容量的限制:因为不管是主节点还是从节点,存储的都是全量缓存数据,那么随着业务量的增长,缓存数据很可能直线上升,直到达到存储瓶颈
同步风暴:因为数据都是从 master 同步到 slave 的,如果有多个从节点的话,master 节点的压力会很大
ES
ES 的写机制与 Redis 和 MySQL 的主从架构有些差别(后两者的写都是直接向 master 节点发起写请求,而 ES 则不是),所以这里稍微解释一下 ES 的工作原理 首先说下节点的工作机制,节点(Node)分为主节点(Master Node)和从结点(Slave Node),主节点的主要职责是负责集群层面的相关操作,管理集群变更,如创建或删除索引,跟踪哪些节点是集群的一部分,并决定哪些分片分配给相关的节点,主节点也只有一个,一般通过类 Bully 算法来选举出来,如果主节点不可用了,则其他从节点也可以通过此算法来选举以实现集群的高可用,任何节点都可以接收读写请求以达到负载均衡的目的 再说一下分片的工作原理,分片分为主分片(Primary Shard,即图中 P0,P1,P2)和副本分片(Replica Shard,即图中 R0,R1,R2),主分片负责数据的写操作,所以虽然任何节点可以接收读写请求,但如果此节点接收的是写请求并且没有写数据所在的主分片话,此节点会将写请求调度到主分片所在的节点上,写入主分片后,主分片再把数据复制到其他节点的副本分片上,以有两个副本的集群为例,写操作如下
MQ
存储层
总结
瞬时流量问题:比如我们可能会面临秒杀带来的瞬时流量激增导致系统的承载能力被压垮,这种情况可能影响日常交易等核心链路,所以需要做到系统之间的隔离,如单独为秒杀部署一套独立的集群
安全问题:比如 DDOS 攻击,爬虫频繁请求甚至删库跑路等导致系统拒绝服务
代码问题:比如代码 bug 引起内存泄露导致 FullGC 导致系统无法响应等
部署问题:在发布过程中如果贸然中止当前正在运行的服务也是不行的,需要做到优雅停机,平滑发布
第三方问题:比如我们之前的服务依赖第三方系统,第三方可能出问题导致影响我们的核心业务
不可抗力:如机房断电,所以需要做好容灾,异地多活,之前我司业务就由于机房故障导致服务四小时不可用,损失惨重
我们之前对接过一个第三方资金方由于自身原因借款功能出了问题导致无法借款,这种情况为了避免引起用户恐慌,于是我们在用户申请第三方借款的时候返回了一个类似「为了提升你的额度,资金方正在系统升级」这样的文案,避免了客诉
在流媒体领域,当用户观看直播出现严重卡顿时,很多企业的第一选择不是查 log 排查问题,而是为用户自动降码率。因为比起画质降低,卡得看不了显然会让用户更痛苦
双十一零点高峰期,我们把用户的注册登录等非核心功能给停掉了,以保证下单等核心流程的顺利