架构师训练营」第 11 周作业
导致系统不可用的原因有哪些?保障系统稳定高可用的方案有哪些?请分别列举并简述。
导致系统不可用的原因:
硬件层面
硬件故障
内存、硬盘、网卡等
软件层面
操作系统安全、性能漏洞
基础组件安全、性能漏洞
如 Tomcat, Nginx, Jenkins(几乎每周都会有新的漏洞)
软件 bug
系统崩溃。个别崩溃可可从服务集群中摘除。大范围崩溃可能是程序bug或负载过高,需通过模拟复现,问题并定位解决
应用cpu或内存使用率过高。可通过profile工具定位繁忙进程/线程
网络可用性降低,包括延迟、丢包等。网络质量检测,及时修复或启用备用线路。
软件高并发导致的不可用
系统负载超过其极限。系统限流+及时扩容
网络黑客攻击
XSS/SQL Injection/CRSF/Error code echo
外界环境层面
地震、火灾
电子、电磁干扰
社会宗教层面
游行、示威
某国外大型网站就在黑人游行疫情期间,大量服务器被抢,导致网站服务不稳定。
恐怖组织袭击,大量服务器被炸坏,导致网站服务不稳定。
保障系统稳定高可用的方案:
通用设计方法
Scale-out(横向扩展):组合多台性能机器组成一个分布式集群来共同抵御并发流量的冲击(1台4核4G->2台4核4G)
Scale-up(纵向扩展):追逐摩尔定律不断提升CPU性能(4核4G->8核8G)
缓存:磁盘寻道花费时间在毫秒级、CPU指令和内存的寻址在纳秒级、千兆网络读取数据时间在微秒级,不同的存储介质的性能不通
异步
架构分层
什么是分层架构
将整体系统拆分成N个层次
例如:MVC、OSI网络模型、TCP/IP协议、Linux文件系统
分层有什么好处
简化系统,让不同的人专注做某一层次的事情
分层可以提升代码的复用
分层更容易做横向的扩展
如何做系统分层
定义清楚每一层次的边界是什么
层次之间一定是相邻层相互依赖,数据的流转也只能在相邻的两层之间流转。
举例:表现层和业务层都可以直接操作数据库,当数据库地址发生变更,就需要在多个层次做更改,失去分层的意义、后面维护和重构是灾难性的
分层架构的不足
增加了代码的复杂度
如果每个层次独立部署,层次通过网络来交互,多层的架构在性能上会有损耗
系统怎样做到高可用?
高可用性
它指的是系统具备较高的无故障运行的能力
可用性的度量
MTBF(Mean Time Between Failure)是平均故障间隔的意思,代表两次故障的间隔时间,也就是系统正常运转的平均时间。这个时间越长,系统稳定性越高。
MTTR(Mean Time To Repair)表示故障的平均恢复时间,也可以理解为平均故障时间。这个值越小,故障对于用户的影响越小。
可用性与 MTBF 和 MTTR 的值息息相关Availability = MTBF / (MTBF + MTTR)
一般来说,我们的核心业务系统的可用性,需要达到四个九,非核心系统的可用性最多容忍到三个九。
高可用系统设计思路
系统设计failover(故障转移)
超时控制
降级
限流
系统运维
灰度发布
灰度发布指的是系统的变更不是一次性地推到线上的,而是按照一定比例逐步推进的。
一般情况下,灰度发布是以机器维度进行的。比方说,我们先在 10% 的机器上进行变更,同时观察 Dashboard 上的系统性能指标以及错误日志。如果运行了一段时间之后系统指标比较平稳并且没有出现大量的错误日志,那么再推动全量变更。
故障演练
故障演练指的是对系统进行一些破坏性的手段,观察在出现局部故障时,整体的系统表现是怎样的,从而发现系统中存在的,潜在的可用性问题
举例:Chaos Monkey
不要过渡追求高可用
提高系统的可用性有时候是以牺牲用户体验或者是牺牲系统性能为前提的,也需要大量人力来建设相应的系统,完善机制。
特殊业务不追求性能,只追求极致的可用性
比如配置下发的系统
如何让系统易于扩展
为什么提升扩展性很复杂
在单机系统中通过增加处理核心的方式,来增加系统的并行处理能力当并行的任务数较多时,系统会因为争抢资源而达到性能上的拐点,系统处理能力不升反降。
集群系统中,不同的系统分层上可能存在一些“瓶颈点”,这些瓶颈点制约着系统的横线扩展能力。如数据库瓶颈、千兆带宽的限制
无状态的服务和组件更易于扩展,而像 MySQL 这种存储服务是有状态的,就比较难以扩展。因为向存储集群中增加或者减少机器时,会涉及大量数据的迁移,而一般传统的关系型数据库都不支持。这就是为什么提升系统扩展性会很复杂的主要原因
我们需要站在整体架构的角度,而不仅仅是业务服务器的角度来考虑系统的扩展性 。所以说,数据库、缓存、依赖的第三方、负载均衡、交换机带宽等等都是系统扩展时需要考虑的因素。
高可用扩展性的设计思路
拆分:将复杂的问题简单化。庞杂的系统拆分成一个个独立、单一职责的模块
存储层的扩展性
存储拆分首先考虑的维度是业务维度
然后根据数据维度拆分:按照某些算法来分库分表,此时尽量不要使用事务
业务层的扩展性
业务维度
重要性维度
请求来源维度
请用你熟悉的编程语言写一个用户密码验证函数,Boolean checkPW(String 用户 ID,String 密码明文,String 密码密文)返回密码是否正确 boolean 值,密码加密算法使用你认为合适的加密算法。
因为MD5算法是不可逆的,所以被很多网站广泛使用,
普遍使用的三种加密方式
方式一:使用位运算符,将加密后的数据转换成16进制
方式二:使用格式化方式,将加密后的数据转换成16进制(推荐)
方式三:使用算法,将加密后的数据转换成16进制
用户对象
工具类
评论 (1 条评论)