高可用注意点

用户头像
dony.zhang
关注
发布于: 2020 年 08 月 26 日
高可用注意点

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

(一) 导致系统不可用原因:

导致系统不可用,涉及服务提供者的调用链上各组件的硬件、软件、网络等各方面的因素,以为外部环境对这些因素的影响。具体如下:

  • 硬件故障

网络:光纤、交换机等网络相关设备和基础设施

计算:物理机中CPU、内存、主板等损坏

存储:磁盘、SSD等损坏



  • 软件bug

操作系统、容器/系统软件、中间件、第三方服务、框架、类库、应用程序、脚本等



  • 并发压力

突发流量、营销活动、高频应用等



  • 系统发布

修改点对现有功能影响,测试与线上的硬件和软件环境不一致,发布步骤、代码、脚本不完整等



  • 网络/黑客攻击

利用系统软件的漏洞、应用程序bug、脚本注入、登录信息、灰色产业链等进行攻击



  • 外部灾难

市政建设、地质灾害、战争、政治等原因导致数据中心不可用

(二) 保障系统稳定高可用方案:

保障系统高可用,需从架构、运维、业务、代码等进行设计和优化。

高可用治理的指导思想:

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

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

iii) 价值回归,成本收益比要合理;

以下主要从架构、运维两方面讨论

1. 从架构方面保障系统高可用
  • 解耦

微服务、组件、面向对象、领域驱动设计



  • 隔离

裸机/虚拟机隔离、容器隔离、业务隔离、子系统隔离、生产者消费者隔离、服务隔离、数据隔离



  • 异步

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



  • 备份

集群设计、数据库复制



  • Failover(失效转移)

负载均衡失效转移、数据库主主失效转移、无状态服务设计



  • 幂等

必须保证服务重复调用和调用一次产生的结果相同,有些服务天然具有幂等性,但交易性操作,需通过交易编号等信息进行服务调用有效性校验。



  • 事务补偿

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



  • 重试

因线程阻塞、垃圾回收、网络抖动等,无法及时返回响应,调用者通过重试修复单次调用的故障。



  • 熔断

当某个服务出现故障,响应延迟或失败率增加,继续调用,请求阻塞、资源消耗增加、进而服务级联失效。这样情况可使用断路器阻断服务的调用。断路器有三种状态:关闭、打开、半开



  • 限流

在高并发场景下,系统的访问量超过系统的承受能力,就会丢弃一部分的用户请求,保证整个系统可用。限流的算法:

i) 固定窗口 计数器算法:存在临界点问题

ii) 滑动窗口 计数器算法:分N个小周期,且根据时间滑动删除过期的小周期

iii) 令牌桶算法:以固定的速度向令牌桶中增加令牌,直到令牌桶满,请求到达向令牌桶请求令牌。获取到令牌可完成请求,否则触发限流策略。

iv) 漏桶算法:请求到达是直接放入漏桶,超过容量则丢弃。漏桶以固定的速率进行释放访问请求,直到漏桶为空。

v) 自适应限流:实时自动评估QPS, 通过实时采集基础设施性能数据,反馈到PID控制算法决策,执行限流器的策略。



  • 降级

在系统极限的高并发访问压力之下,将一些非核心的功能关闭,将宝贵的系统资源留下来,完成交易等核心的功能。



  • 异地多活

如果整个数据中心都不可用,为了提高系统的处理能力和改善用户体验,大型互联网应用都采用了异地多活的多机房架构策略,将数据中心分布在多个不同地点的机房里。异地多活的难点是数据一致。

2. 从运维方面保障系统高可用
i) 发布

发布时,需要在服务器上关闭原有的应用,然后重新部署启动新的应用,整个过程要求不影响用户的使用。服务的发布过程事实上和服务器宕机效果相当,那么可以用服务器宕机的高可用方案来应对网站的发布。



  • 代码版本控制

制定适合自己的版本控制规范和流程,可采用单分支,特性分支等多种方式



  • 自动化测试

每次发布新功能,都是在原有的系统功能上小幅增加。但为了防止系统引入未预料的Bug,需对整个系统的功能进行全面的回归测试,兼容性测试。人力、时间成本都比较高,难以承受。需引入自动化测试工具或脚本完成测试。比如:selenium工具

需考虑:人工手动测试与自动化测试的成本、以及平衡点



  • 自动化/持续部署

持续集成:允许开发者随时向公共分支提交代码,并立即进行自动化测试

持续构建:通过后,完成软件打包

持续交付:持续交付机制将软件包部署到各种测试环境中

持续部署:代码在没有人工干预情况下被测试、构建、部署并推送到生产环境中



  • 预发布验证

即使经过严格的测试,软件部署到线上服务器之后还是经常出现各种问题。主要原因是测试环境与线上环境并不相同,在发布时,并不是吧测试通过的代码包中介发布到线上服务器,而是先发布到预发布机器上,开发和测试在预发布服务器上进行预发布验证,执行1-2个典型的业务流程,确认没问题才正式发布。和线上服务器唯一不同就是没有配置在负载均衡服务器上,外部用户无法访问。



  • 灰度发布

发布完成后,仍然会发现一些entity而引入故障,这是需做发布回滚,但集群规模非常庞大时,回滚也需要很长一段时间。为了避免这个场景下,引起的系统不可用。 将集群分成若干部分,每天发布一部分服务器,如果发现问题,只需回滚一部分已发布的服务器。



ii) 日志&监控

应用程序运行在服务器的硬件机器、系统软件、中间件之上,需能实时跟踪和监测服务器的基础设施、系统软件、中间件、应用程序的状态和性能,当出现异常能实现自动告警,自动治愈等。

  • 服务运行监控

“不允许没有监控的系统上线”,运行监控对于网站的运维和架构设计优化至关重要。



  • 监控数据采集

用户行为日志:用户再浏览器端或客户端所做的所有操作及所在系统上下文信息,这些数据对系统的PV/UV指标、分析用户行为、优化系统设计、个性化营销、推荐等非常重要。包含:服务器日志收集、客户端日志收集

业务运行日志&数据报告:监控一些具体业务场景相关的技术和业务指标, 如缓存命中率、平均响应延迟时间、待处理的任务总数等。



  • 服务器性能监控

收集服务器的物理机、虚拟机上的系统Load、CPU、内存、磁盘、网卡等,尽早做出故障预警,合理安排服务器集群规模,改善系统性能、调整系统伸缩性策略。



  • 监控管理&告警&自愈

根据实时监控数据进行风险预警,并对服务器进行失效转移,自动负载调整,最大化利用集群所有集群资源。



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

public class UserPwdValidate {
public static void main(String[] args) {
//正确密码
System.out.println(checkPwd("112233", "66666666", "2054b6760a08820e7ad17b8d80938d6e") ? "验证通过" : "验证失败");
//错误密码
System.out.println(checkPwd("112233", "66666666", "72097c84777050783affd7f528371ed5") ? "验证通过" : "验证失败");
}
public static boolean checkPwd(String userId, String pwdPlain, String pwdCipher) {
if(StringUtils.isBlank(userId) || StringUtils.isBlank(pwdPlain) || StringUtils.isBlank(pwdCipher)) {
return false;
}
try {
//可替换为其他userId的转换值
final String salt = userId;
return pwdCipher.equals(MD5(pwdPlain + salt));
} catch (NoSuchAlgorithmException e) {
return false;
}
}
public static String MD5(String source) throws NoSuchAlgorithmException {
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
messageDigest.update(source.getBytes());
return Hex.encodeHexString(messageDigest.digest());
}
}



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

dony.zhang

关注

专注成就专业 2018.07.06 加入

程序员

评论

发布
暂无评论
高可用注意点