架构师训练营第十一章作业

用户头像
吴吴
关注
发布于: 2020 年 08 月 26 日

作业一:

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

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



系统不可用原因

  • 硬件故障

  • 软件BUG

  • 系统发布

  • 并发压力

  • 网络攻击

  • 外部灾害



保障系统稳定高可用的方案

  • 解耦

高内聚低耦合的组件设计原则,面向对象设计原则,面向对象设计模式,领域驱动设计建模

使代码边界更清晰,且可扩展性可维护性更好,能快速分析问题产生原因并解决

  • 隔离

业务与子系统隔离,微服务与中台架构,生产者消费者隔离,虚拟机与容器隔离

解耦是逻辑层面,隔离是物理层,使问题不要扩散开来

  • 异步

多线程编程,反应式编程,异步通信网络编程,事件驱动异步架构

如果部分失败再通过补偿系统或机制的进行处理,整个系统还是可用的

  • 备份(冗余)

集群,数据库复制

互联网中任何一个服务器不能是单点(Doris的管理控制台没有做备份,当管理控制台失效的时候,并不影响系统的正常运行)

  • Failover(失效转移)

数据库主主失效转移,负载均衡失效转移

数据库主主由外部服务器去确认谁是master,比如Zookeeper。而Zookeeper通过自身集群策略提供高可用。

  • 幂等

事件失败的时候可重复提交

  • 事务补偿

执行业务逻辑逆操作,使事务回滚到事务前状态

  • 重试

远程服务可能会由于线程阻塞、垃圾回收或者网络抖动,而无法及时返回响应,调用者可以通过重试的方式修复单次调用的故障。

上游调用者超时时间要大于下游调用者超时时间之和。

  • 熔断

当某个服务出现故障,响应延迟或者失败了增加,继续调用整个服务会导致调用者请求阻塞,资源消耗增加,进而出现服务级联失效,这种情况下使用断路器阻断对故障服务的调用。

断路器三种状态:关闭,打开,半开

  • 限流

高并发场景,访问量超过了系统的承受力,可以通过限流进行保护。限流会丢弃部分用户的请求,以保证整个系统的可用,保证大部分用户可以访问。丢车保帅的做法。

限流算法:计数器(固定窗口)算法,计数器(滑动窗口)算法,令牌桶算法(固定速率生产),漏桶算法(固定速率消费),自适应限流(实时自动评估QPS,业务流量的不确定性)

  • 降级

某些非核心功能也会给系统产生非常大的压力,比如电商的确认收货功能,即便不主动确认收货,系统也会到时自动确认收货。

比如像淘宝双11的时候,可以采用将确认收货、评价这些非核心功能关闭的降级策略,降低低价值的资源消耗。

  • 异地多活

前面的方法主要针对系统层面的,异地多活主要针对系统外部的不可控因素。比如地震、火灾、停电、战争地区



import java.security.MessageDigest;

import java.security.NoSuchAlgorithmException;



import org.apache.commons.codec.binary.Hex;



public class CheckPW {

public static Boolean checkPW(String userId, String pwd, String encodedPwd) throws NoSuchAlgorithmException {

String digestStr = encodeWithSHA256(userId+pwd);

return encodedPwd.equals(digestStr);

}

private static String encodeWithSHA256(String str) throws NoSuchAlgorithmException {

MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");

byte[] digestBytes = messageDigest.digest(str.getBytes());

String digestStr = Hex.encodeHexString(digestBytes);

return digestStr;

}

public static void main(String[] args) throws NoSuchAlgorithmException {

String userId = "111";

String pwd = "123456";

System.out.println(encodeWithSHA256(userId+pwd));

Boolean result = checkPW(userId, pwd, encodeWithSHA256(userId+pwd));

System.out.printf("result :%b \n", result);

}

}



相对于MD5跟安全



用户头像

吴吴

关注

还未添加个人签名 2018.03.02 加入

还未添加个人简介

评论

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