写点什么

第十一周课后练习

用户头像
晴空万里
关注
发布于: 2021 年 01 月 02 日

作业一

(至少完成一个)

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

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


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


导致系统不可用用的原因主要有:

  1. 硬件故障

  2. 软件 bug

  3. 系统发布

  4. 并发压力

  5. 网络攻击

  6. 外部灾害


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

首先就是高可用的系统架构,它有下面这些设计方法

  • 解耦

  • 高内聚、低耦合的组件设计原则

  • 面向对象基本设计原则

  • 面向对象设计模式

  • 领域驱动设计模式

  • 隔离

  • 业务与子系统隔离

  • 微服务与中台架构

  • 生产者消费者隔离

  • 虚拟机与容器隔离

  • 异步

  • 多线程编程

  • 反应式编程

  • 异步通信网络编程

  • 事件驱动异步架构

  • 备份

  • 集群设计

  • 数据库复制

  • CAP 原理

  • 失效转移(Failover)

  • 数据库主主失效转移

  • 负载均衡失效转移

如何确认失效,需要转移?Zookeeper 选举等手段

设计无状态的服务

  • 幂等

  • 事务补偿

  • 传统事务的 ACID

  • 分布式事务的 BASE

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

  • 重试

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

  • 熔断

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

  • 限流

  • 计数器算法(固定窗口、滑动窗口)

  • 令牌桶算法

  • 漏桶算法

  • 自适应限流

  • 实时自动评估 QPS

  • 业务流量的不确定性与技术方案的自适应天生一对

  • 降级

  • 异地多活

然后就是高可用的系统运维

  • 发布

  • 7*24 小时不间断

  • 自动化测试

  • 自动化部署

  • 持续部署三步走

  • 持续集成

  • 持续交付

  • 持续部署

  • 预发布验证

  • 代码版本控制

  • 主干开发、分支发布

  • 分支开发、主干发布

  • 自动化发布

  • 灰度发布

接着就是网站运行监控

  • 网站运行监控

不允许没有监控的系统上线

  • 监控数据采集

  • 用户行为日志收集

  • 服务器性能监控

  • 业务运行数据报告

  • 监控管理

  • 报警

  • 自动控制


最后:需要明确一点

高可用的价值观

  • 保持简单,使问题易于发现,快速解决

  • 目标明确,解决特定环境下的具体问题

  • 价值回归,成本收益要合理


第二题:

aes 对称加密+盐(用户名)


import org.apache.commons.lang3.StringUtils;
/** * @author ccc * @date 2021/01/02 */public class CheckPwd { /** * @param userId 用户编码 * @param password 明文密码 * @param cipherText 加密密码 * @return 是否正确 默认不正确 */ static boolean checkPwd(String userId, String password, String cipherText) { // 加密后的字符串 String encrypt = SecurityUtils.encrypt(password, userId); assert encrypt != null; // 解密后的原文 64E2DD2D68BDFBF42E3E818FC966B993 return StringUtils.equals(encrypt, cipherText); }
public static void main(String[] args) { // 使用用户名作为盐用户名:ccc 密码:123456 加密后密文:64E2DD2D68BDFBF42E3E818FC966B993 System.out.println("1、输入用户名:ccc,密码:111111(正确密码是123456)"); boolean b = checkPwd("ccc", "111111", "64E2DD2D68BDFBF42E3E818FC966B993"); System.out.println(String.format("密码是否正确:%s", !b ? "否" : "是"));
System.out.println("1、输入用户名:ccc,密码:123456(正确密码是123456)"); boolean b1 = checkPwd("ccc", "123456", "64E2DD2D68BDFBF42E3E818FC966B993"); System.out.println(String.format("密码是否正确:%s", !b1 ? "否" : "是")); }}
复制代码


import lombok.extern.slf4j.Slf4j;
import javax.crypto.Cipher;import javax.crypto.KeyGenerator;import javax.crypto.SecretKey;import javax.crypto.spec.SecretKeySpec;import java.security.SecureRandom;
@Slf4jpublic class SecurityUtils { /** * 编码格式 */ private static final String ENCODING = "UTF-8"; /** * 加密算法 */ public static final String KEY_ALGORITHM = "AES"; /** * 签名算法 */ public static final String SIGN_ALGORITHMS = "SHA1PRNG";
/** * 加密 * * @param content 待加密内容 * @param key 加密的密钥 * @return */ public static String encrypt(String content, String key) { try { KeyGenerator kgen = KeyGenerator.getInstance(KEY_ALGORITHM); SecureRandom random = SecureRandom.getInstance(SIGN_ALGORITHMS); random.setSeed(key.getBytes(ENCODING)); kgen.init(128, random); SecretKey secretKey = kgen.generateKey(); byte[] enCodeFormat = secretKey.getEncoded(); SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, KEY_ALGORITHM); Cipher cipher = Cipher.getInstance(KEY_ALGORITHM); byte[] byteContent = content.getBytes(ENCODING); cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec); byte[] byteRresult = cipher.doFinal(byteContent); StringBuffer sb = new StringBuffer(); for (int i = 0; i < byteRresult.length; i++) { String hex = Integer.toHexString(byteRresult[i] & 0xFF); if (hex.length() == 1) { hex = '0' + hex; } sb.append(hex.toUpperCase()); } return sb.toString(); } catch (Exception e) { log.error("加密操作", e); } return null; }
/** * 解密 * * @param content 待解密内容 * @param key 解密的密钥 * @return */ public static String decrypt(String content, String key) { if (content.length() < 1) { return null; }
byte[] byteRresult = new byte[content.length() / 2]; for (int i = 0; i < content.length() / 2; i++) { int high = Integer.parseInt(content.substring(i * 2, i * 2 + 1), 16); int low = Integer.parseInt(content.substring(i * 2 + 1, i * 2 + 2), 16); byteRresult[i] = (byte) (high * 16 + low); } try { KeyGenerator kgen = KeyGenerator.getInstance(KEY_ALGORITHM); SecureRandom random = SecureRandom.getInstance(SIGN_ALGORITHMS); random.setSeed(key.getBytes(ENCODING)); kgen.init(128, random); SecretKey secretKey = kgen.generateKey(); byte[] enCodeFormat = secretKey.getEncoded(); SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, KEY_ALGORITHM); Cipher cipher = Cipher.getInstance(KEY_ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, secretKeySpec); byte[] result = cipher.doFinal(byteRresult); return new String(result, ENCODING); } catch (Exception e) { log.error("解密操作", e); } return null; }
}
复制代码


用户头像

晴空万里

关注

还未添加个人签名 2018.07.18 加入

还未添加个人简介

评论

发布
暂无评论
第十一周课后练习