写点什么

十一周作业

用户头像
olderwei
关注
发布于: 2020 年 08 月 24 日

导致系统不可用的原因及应用策略

在大型分布式系统中,系统可用性是一个很重要的指标,业界通常用多少个9来衡量,比如4个9,说明网站一年的不可用时间不能超过53分钟,这对系统开发人员及运维人员要求都非常高,要24小时oncall,且需要有完备的流程来保证系统可用性,下面看一下导致系统不可用的原因都有哪些以及我们如何应对。

系统不可用的原因有:

  • 硬件故障

  • 软件bug

  • 系统发布

  • 并发压力

  • 网络攻击

  • 外部灾害

我们应对系统故障也需要从几方面来考虑:

从系统架构层面,我们要尽量保证系统不被过大的访问压力压垮,我们可以从以下几个方面来考虑

  • 解耦:遵循高内聚、低耦合的设计原则,保证模块之间不相互影响,不至于一个模块出问题导致所有模块都出问题

  • 隔离:资源隔离,模块之间互不影响,比如将Redis资源隔离,不要几个系统都依赖一个集群,防止一个系统导致redis出问题后影响到其他系统

  • 异步:尽量不要强依赖一个组件,能进行异步通知的就做成异步,比如功能A依赖发邮件服务,可以将发邮件做成异步,当邮件服务出问题,功能A还能正常运行。

  • 备份:每一个系统都不要单点,都有部署多份,当一个出现问题,还能切换到其他服务器

  • 失效转移:比如应用服务器的无状态设计保证服务能快速切换。

  • 幂等:保证服务的重复调用和第一次调用的结果一致,比如A调用B,B已经成功处理,但是网络出现失败,A没有收到结果然后重试,这个时候就需要幂等性来保证操作可重复操作。

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

  • 重试:由于网络故障,可能调用会出现抖动,所以需要重试来保证服务正常调用

  • 超时设置:服务调用一定要设置超时时间,不然由于依赖服务一直无返回导致调用方的线程阻塞,会导致调用方和服务方的线程耗尽

  • 熔断:当调用某个服务出现问题,会导致依赖方也会出现问题,导致服务雪崩,所以当服务出现问题时,达到某一个阈值时,不调用该服务,然后过一段时间再尝试调用,如果恢复了,则继续调用,未恢复,则继续熔断

  • 限流:当流量突然增大时,超过限流的部分不让进入系统,直接拒绝;限流方法有:计数法(固定窗口、滑动窗口),令牌法、漏铜法

  • 降级:在系统压力大的时候,降级掉某些非核心服务,节省系统资源。

从系统安全层面,要对抗各种恶意攻击

  • 防XSS攻击,进行消毒处理,如将"<"转义成"&gt","<"转义成"&lt"

  • 防SQL注入,使用预编译来绑定参数

  • 防CSRF攻击,请求带token,请求提交后需要验证token,或者检查refer

  • 关闭错误回显,有专门的错误页

  • 用户信息脱敏处理,用户密码密文持久化,http请求升级到https

  • 引用三方包的要关注漏洞安全,及时更新修复版本,或使用更稳定安全的工具类

  • 网站漏洞安全扫描,静态代码扫描等

从系统运维层面,要保证系统发布及运行的正常,我们也可以从如下几方面来考虑:

  • 发布过程需要将机器从负载均衡下线,发布完成后再上线

  • 预发布验证,它和线上服务器的唯一区别就是外部用户无法访问,上线之前一定先在预发布进行验证。

  • 灰度发布,每一次发布少量机器,保证出现问题时能及时回滚

  • 代码版本控制,一般主干发布,分支开发

  • 监控报警:没有监控的系统,犹如盲人骑瞎马,夜半临深渊而不知,需要收集机器的监控信息,以及业务的监控打点信息,并配置相应的报警阈值,在出现问题时能够及时通知我们。

密码验证

加密算法使用HmacSha256

public class Sha256Utils {
private static Mac sha256_HMAC;
static {
try {
sha256_HMAC = Mac.getInstance("HmacSHA256");
} catch (NoSuchAlgorithmException e) {
System.err.println("Init Error");
}
}
public static String hmacSha256(String key, String message) {
try {
SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(), "HmacSHA256");
sha256_HMAC.init(secret_key);
String hash = Base64.getEncoder().encodeToString(sha256_HMAC.doFinal(message.getBytes()));
return hash;
} catch (Exception e){
System.err.println("Encrypt Password Error");
}
return "";
}
}
public class User {
private Map<String, String> userMap = new ConcurrentHashMap<>();
public boolean checkPW(String userName, String password) {
String encryptPassword = Sha256Utils.hmacSha256(userName, password);
String userPassword = userMap.get(userName);
if (encryptPassword.equals(userPassword)) {
return true;
} else {
return false;
}
}
public void register(String userName, String password) {
String encryptPassword = Sha256Utils.hmacSha256(userName, password);
if ("".equals(encryptPassword)) {
throw new RuntimeException("User Register Fail");
}
userMap.put(userName, encryptPassword);
}
public static void main(String[] args) {
User user = new User();
user.register("chenwei", "chenwei123");
System.out.println(user.checkPW("chenwei", "chenwei"));
System.out.println(user.checkPW("chenwei", "chenwei123"));
}
}



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

olderwei

关注

还未添加个人签名 2018.04.26 加入

还未添加个人简介

评论

发布
暂无评论
十一周作业