架构师训练营第十一周命题作业

发布于: 2020 年 12 月 08 日

作业一:

导致系统不可用的原因有哪些?保障系统稳定高可用的方案有哪些?请分别列举并简述。

导致系统不可用的原因有很多,从用户侧到系统侧,再深入系统内部,链路上的各个环节都可能出现问题从而导致系统不可用,而出问题的原因又多种多样,包括有意的和无意的。除此之外,还有地震、火灾等可能的客观因素导致系统不可用。



可能的原因:

  • 硬件故障:机器的磁盘、内存坏了,系统就没法运行了

  • 软件 bug:软件有 bug,系统可用性自然也就受影响;可能有自身的软件故障,也可能是因为依赖的其他系统的有问题

  • 系统发布:比如将错误的版本发布到线上

  • 并发压力:系统的接收的压力超过了系统的最大处理能力,从而把系统压垮

  • 网络攻击:有人恶意攻击,修改了系统内的数据,或删除了数据库表,或者把光线挖断

  • 外部灾害:地震、火灾等自然灾害,导致机房受损



保证高可用的方案:

  • 冗余:服务不要出现单点,以集群的形式搭建;必要的话,要做数据中心的异地多活

  • 备份:数据要定时备份,避免数据丢失

  • 隔离:系统与系统之间要尽量隔离,不通过的组件、不同的层里的故障,不要蔓延到其他组件和层。这和最后的「解耦」有一定的相似之处

  • 限流:对流量要有主动控制的能力,接收的流量要在系统的处理能力之内

  • 熔断:当服务出现故障,继续调用这个服务会造成调用者阻塞,是系统状态进一步恶化,这种情况下需要使用熔断器阻断对故障服务的调用

  • 降级:有一些非核心的业务也会对系统造成很大压力,所以在系统压力大的时候,可以选择性地关闭非核心业务

  • 异步:对于大并发、耗时的操作,可以以异步的形式处理,处理完成后再通知用户

  • 失效转移:当服务出现故障时,要将流量从故障实例切换到其他实例上,比如数据库的主主备份

  • 重试:在服务请求失败时,增加重试的机制,尽量保证请求能被成功处理

  • 幂等:这一点应该是「要求」,而不是「方案」。有些业务特性要求某些操作多次执行,结果保持一致。比如请求从一个故障节点切换到了其他节点,请求会被重新处理,要保证在重复执行的情况下,结果是一致的,就像只执行了一遍一样。

  • 解耦:从服务间的依赖关系,到代码层面的高内聚低耦合,都要尽量做到解耦

  • 事务补偿:在事务失败的条件下,通过执行业务的逆操作,使事务回到执行前的状态



作业二:

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



package main
import (
"crypto/sha1"
"fmt"
"io"
"log"
)
func main() {
userId := "user-123"
password := "welcome"
encryptedPwd, err := encrypt(password)
if err != nil {
log.Fatalln(err)
}
if match := validateUser(userId, password, encryptedPwd); match {
log.Println("user info matched")
} else {
log.Println("user info does not match")
}
}
func validateUser(userId string, password string, encryptedPassword string) bool {
if encryptedPwd, err := encrypt(password); err != nil {
log.Println(err)
return false
} else {
return encryptedPwd == encryptedPassword
}
}
func encrypt(str string) (string, error) {
t := sha1.New()
if _, err := io.WriteString(t, str); err != nil {
return "", err
}
return fmt.Sprintf("%x", t.Sum(nil)), nil
}



发布于: 2020 年 12 月 08 日阅读数: 17
用户头像

还未添加个人签名 2018.07.26 加入

还未添加个人简介

评论

发布
暂无评论
架构师训练营第十一周命题作业