写点什么

架构师 01 期,第十一周课后作业

用户头像
子文
关注
发布于: 2020 年 12 月 06 日
  • 导致系统不可用的原因有哪些?保障系统稳定高可用的方案有哪些?请分别列举并简述。

  • 请用你熟悉的编程语言写一个用户密码验证函数,Boolean checkPW(String 用户 ID,String 密码明文,String 密码密文),返回密码是否正确 boolean 值,密码加密算法使用你认为合适的加密算法。


引起系统故障的原因大致可以分为硬件原因、软件原因、外部原因三类。

  • 硬件原因:主要是指基础设施故障,例如硬件故障,包括硬盘、内存、CPU、电源故障等,以及网络故障。

  • 软件原因:主要包括软件 bug、并发阻塞、黑客攻击等。

  • 外部原因:主要指不可控因素和不可抗力因素,例如断电、自然灾害、光缆断路、审查限制等。

保障系统高可用的方案大致分为架构方案、运维方案、监控方案三类。

架构方案

解耦

设计高内聚、低耦合的系统组件,遵循面向对象设计原则、设计模式,以领域驱动设计指导领域建模,降低系统复杂度,提升可靠性和故障修复速度

隔离

从部署上将不同的子系统分离开,使用微服务架构、中间件、容器等技术,从系统层面控制住故障的影响范围。

异步

通过并发编程、反应式编程、异步通信、消息队列、事件驱动等手段减少系统阻塞的情况,避免由于网络性能的原因带来的系统不可用。

备份

对特定的子系统和服务进行集群化部署,通过负载均衡分发并发请求,减轻系统的压力。失效转移

在备份的前提下,当集群中某台服务器出现故障,需要将流量指向到其他服务器,在数据库集群中还涉及到主服务器的选举。

幂等

幂等性是设计无状态服务的必要条件,幂等服务在失效后进行重试不会导致数据不一致。事务补偿

对于传统的数据库事务应当满足 ACID 原则,而对于分布式事务应当满足 BASE 原则,在事务处理失败的时候,需要通过事务补偿,即业务逻辑上的逆操作对事务进行回滚。

重试

由于阻塞、网络故障等原因造成的短时间请求失败可以通过重试来解决,需要注意上游调用者的超时时间要大于下游调用者的超时时间之和。

熔断

当某个服务出现故障时,继续调用这个服务会增加系统资源消耗,因此应当使用断路器阻断对该服务的调用。

限流

在并发量激增的情况下,为了避免系统被压垮,需要对部分请求进行限制,只允许一部分流量进入,这样虽然会对部分用户造成影响,但比整个服务失去响应要好。

降级

在系统高并发的情况下,可以关闭一些非核心的业务和功能,集中力量保障核心服务的正常运转。

异地多活

异地多活针对的是整个数据中心不可用,是对数据中心的异地部署,并且每个数据中心都可以独立提供完整服务。

运维方案

发布

在发布代码更新的时候,需要关停服务、更新代码、重新启动这几个步骤,因此会造成服务的短时不可用,为了避免对用户造成感知上的影响,就需要在前期以集群+负载均衡的形式进行服务部署,通过调整负载均衡路由,分批下线服务并进行更新、重启,然后再重新上线。

为了避免某次发布带来问题后需要全盘回滚,通常会采用灰度发布的方式,即分批次地对服务和服务器进行更新,每一批次之间间隔一段时间,上一批次没有出现问题的情况下再进行下一批次。

自动化测试

为了减少人工测试的繁琐和疏忽,自动化测试技术可以在更新发布后对整个应用进行回归测试,尽可能减少 bug 流传到生产环境的概率。

持续部署

按照持续集成、持续交付、持续部署三个步骤逐步搭建起自动化运维流程和系统,只需要极少的人工干预就可以完成代码更新的发布、测试和部署工作,确保系统的质量。

监控方案

日志收集与分析

对用户行为、业务操作、系统性能等指标进行实时的数据记录和分析。

自动控制

根据日志监控和分析结果自动发现故障并执行相应的失效转移、扩容、限流、熔断、降级等操作。


package test.zzw;
import org.apache.commons.codec.binary.Hex;
import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;
public class CheckPWDemo { public static Boolean checkPW(String userId, String password, String encodedPassword) throws NoSuchAlgorithmException { if (!isExistUser(userId)) { return false; } String encryptedStr = encodeBySHA256(password); System.out.println(encodedPassword); return encodedPassword.equals(encryptedStr); } private static String encodeBySHA256(String str) throws NoSuchAlgorithmException { MessageDigest messageDigest = MessageDigest.getInstance("SHA-256"); byte[] digestBytes = messageDigest.digest(str.getBytes()); String digestStr = Hex.encodeHexString(digestBytes); return digestStr; } private static boolean isExistUser(String userId) { return true; } public static void main(String[] args) throws NoSuchAlgorithmException { String userId = "sabring"; String pwd = "1qaz@WSX"; String encryptionpwd = encodeBySHA256(pwd); System.out.println("encryptionpwd:" + encryptionpwd); Boolean result = checkPW(userId, pwd, encryptionpwd); System.out.println("result:" + result); }

}



复制代码


用户头像

子文

关注

233 2018.04.03 加入

233

评论

发布
暂无评论
架构师 01 期,第十一周课后作业