写点什么

架构师训练营 4 期 第 11 周

用户头像
引花眠
关注
发布于: 2021 年 03 月 14 日

作业一(至少完成一项)

系统不可用

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


引起系统不可用的原因大致有以下原因:


  1. 硬件故障 硬盘损毁等等

  2. 软件 Bug 本身代码质量不高

  3. 系统发布 版本太多

  4. 并发压力 比如活动人数超出预期

  5. 网络攻击/故障 比如黑客攻击、机房不可用

  6. 外部灾害 比如地震、火灾


如果要保障系统的高可用性,大致分为两部分,架构和运维


在架构层面,可以采取的方案有:


  1. 降低系统的耦合性 通过将不同的系统解耦.隔离,使用异步的方式请求系统,避免多系统之间的影响

  2. 避免单点故障 使用集群和数据库复制,来避免单点问题

  3. 失效转移 当一个系统节点出问题时,将对其的调用转移到其他相同功能的节点上,要达成这样的能力,最好设计幂等的服务

  4. 限流与降级 用来避免高出系统承受能力的请求

  5. 异地多活 即可以用来降低延迟,也能用来避免同时遭受外部灾害


运维层面,采取的方案有:


  1. 测试 上线前对代码进行自动化测试,可以使用自动化测试工具比如 Selenium 对 Web 应用测试

  2. 部署 最好能构建自动化部署流程,避免部署阶段的发生的低级问题

  3. 发布 对于发布到生产的代码要慎重,最好可以在预发布环境进行验证,对于大规模的集群也不应该同时发布,而应该使用灰度发布模式

  4. 监控 不能将系统放到生产之后就不管了,需要对系统进行监控,收集用户的、服务器的、系统的日志,如果出现问题,就要通知运维人员来处理。


加密算法

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


如果用户 id 时不变的,那么可以使用 Md5 对密码进行加密 代码地址为:


工具类:


import java.security.GeneralSecurityException;import java.security.MessageDigest;
import org.apache.commons.codec.DecoderException;import org.apache.commons.codec.binary.Hex;
public class Md5Utils { private Md5Utils() {
}
private static final String MD5 = "MD5";
/** * 对传入的字符串进行md5运算,不加盐 * * @param input * 输入字符串 * @return */ public static String md5(String input) { return encodeHex(digest(input.getBytes(), null, 1)); }
/** * 对传入的字符串进行md5运算 * * @param input * 输入字符串 * @param salt * 加盐 * @return */ public static String md5(String input, String salt) { return encodeHex(digest(input.getBytes(), salt.getBytes(), 1)); }
/** * 对字符串进行散列 * * @param input * 输入byte数组 * @param salt * 加盐 * @param iterations * 迭代次数 * @return */ private static byte[] digest(byte[] input, byte[] salt, int iterations) { try { MessageDigest digest = MessageDigest.getInstance(MD5);
if (salt != null) { digest.update(salt); }
byte[] result = digest.digest(input);
for (int i = 1; i < iterations; i++) { digest.reset(); result = digest.digest(result); } return result; } catch (GeneralSecurityException e) { throw new RuntimeException(e); } }
/** * Hex编码. */ private static String encodeHex(byte[] input) { return new String(Hex.encodeHex(input)); }
/** * Hex解码. */ private static byte[] decodeHex(String input) { try { return Hex.decodeHex(input.toCharArray()); } catch (DecoderException e) { throw new RuntimeException(e); } }}
复制代码


密码验证:


import org.apache.commons.codec.binary.StringUtils;
public class UserPasswordCheckUtils { private UserPasswordCheckUtils() {
}
public static boolean checkPassword(String userId, String rawPassword, String encryptedPassword) { return StringUtils.equals(encryptedPassword, Md5Utils.md5(rawPassword, userId)); }
public static String encrypt(String userId, String rawPassword) { return Md5Utils.md5(rawPassword, userId); }}
复制代码


测试代码:


mport static org.junit.jupiter.api.Assertions.assertFalse;import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.BeforeEach;import org.junit.jupiter.api.Test;
class UserPasswordCheckUtilsTest {
String userName = "shaozuo"; String password = "password"; String encryptedPassword = "";
@BeforeEach public void before() { encryptedPassword = UserPasswordCheckUtils.encrypt(userName, password); }
/** * 正常 */ @Test void success() { assertTrue(UserPasswordCheckUtils.checkPassword(userName, password, encryptedPassword)); }
/** * 校验失败 */ @Test void failed() { assertFalse(UserPasswordCheckUtils.checkPassword(userName, password, "p@ssw0rd")); assertFalse(UserPasswordCheckUtils.checkPassword("laozhai", password, encryptedPassword)); assertFalse(UserPasswordCheckUtils.checkPassword(userName, "p@ssw0rd", encryptedPassword)); }
}
复制代码


作业二:根据当周学习情况,完成一篇学习总结

本中主要讲解的是安全架构与高可用相关知识


架构师训练营 -Web 攻击与防护


关于高可用的内容在 第一题有描述


发布于: 2021 年 03 月 14 日阅读数: 14
用户头像

引花眠

关注

还未添加个人签名 2018.06.11 加入

还未添加个人简介

评论

发布
暂无评论
架构师训练营 4 期 第11周