极客大学架构师训练营 加密技术 高可用系统的度量 高可用系统的架构 高可用系统的运维 第 22 课 听课总结
说明
首席架构师:李智慧
信息加密技术及秘钥安全管理
2011 年 12月被曝 CSDN 密码泄露事故中,网站安全措施不力,导致用户数据库被黑客“拖库” 并不稀奇,令人惊愕的是数据库中的用户密码居然是明文保存,导致密码泄露,成为地下黑市交易的商品。
通常,为了保护网站的敏感数据,应用需要对这些信息进行加密处理,信息加密技术可以分为三类:单向散列加密,对称加密,非对称加密。
如果跟金融、交易有关的产品,出事后第一嫌疑人就是开发加解密算法的工程师,第二嫌疑人就是数据库DBA。如果真遇上了,就像:拿着卖白菜的工资,操着卖白粉的心。
单向散列加密
比如: MD5。 应用场景:文件校验信息,用户密码加密。
有些黑客创建一个网站,用户注册的时候把密码的明文和密文都收集起来。把别的网站的密文密码拖库了以后,直接拿之前的对照表,就可以反向查询到明文。
解决方案:加盐,密码加某些特定的字符,或者用户id等。
用户密码单向散列解密,密文存储到数据库,用户永远不能取回原始密码,只能重置密码。如果能还原成原始密码,说明这个系统是脆弱的。
对称加密
应用场景比较多,特别是内部应用。
非对称加密
顺方向应用场景:https
逆方向应用场景:数字签名、电子签名、区块链
秘钥安全管理与加解密服务系统架构
秘钥管理者是多人一起管理的。
连自己人都防住了,才是真正的安全。
反垃圾邮件
贝叶斯分类算法
贝叶斯算法解决概率论中的一个典型问题:一号箱子放在红色球和白色球各20个,二号箱子放有白色球10个,红色球30个,现在随机挑选一个箱子,取出来一个球的颜色是红色的,请问这个球来自一号箱子的概率是多少。
利用贝叶斯算法进行垃圾邮件的识别基于同样原理,根据已分类的样本信息获得一组特征值的概率(如“茶叶” 这个词出现在垃圾邮件中的概率和非垃圾邮件中的概率),就得到分类模型,然后对待处理信息提取特征值,结合分类模型,判断其分类。
布隆过滤器黑名单
开辟16G的内存空间(大小可以看情况设置),初始化16G * 8 bit的位置值都为0。入库黑名单,分别用8个算法算出一个数字范围,就把值设置为1。校验黑名单,分别用8个算法如果得到的数字都是1,就认为是黑名单。
注意:布隆过滤器黑名单有可能会误杀,比如有的非黑名单邮箱地址碰巧被命中都是1,就被误杀了。
电子商务风险控制
电子商务网站在给人们代理购物交易的极大便利的同时,也将风险带给了网络安全一无所知的人们。由于买卖双方的信息不对等,交易本来就存在风险,而当交易在网上发生的时候,买卖双方彼此一无所知,交易风险也就更加难以控制。如果一个电商网站骗子横行,诚信的交易者屡屡被骗,那么网站就到了最危险的时候,可以说,交易安全是电子商务网站的底线。
电子商务具有多种形式,B2B,B2C,C2C 每种交易的场景都不相同,风险也各有特点,大致可分为以下几种:
账户风险:包括账户被黑客盗用,恶意注册账号等几种情况。
买家风险:买家恶意下单占库存进行不正当竞争;黄牛利用促销抢购低价商品;此外还有良品拒收,欺诈退款以及常见于 B2B 交易的虚假询盘等。
卖家风险:不良卖家进行恶意欺诈的行为,例如货不对板,虚假发货,炒作信用等,此外还有发布违禁商品、侵权商品等。
交易风险:信用卡盗刷,支付欺诈,洗钱套现等。
大型电商网站都配备有专门的风控团队进行风险控制,风控的手段也包括自动和人工两种方式。机器自动识别为高风险的交易和信息会发送给风控审核人员进行人工审核,机器自动风控的技术和方法也不断通过人工发现的新风险类型进行逐步完善。
机器自动风控的技术手段主要有规则引擎和机器学习。
规则引擎
当交易的某些指标满足一定条件的时候,就会被认为具有高风险的欺诈可能性。
比如:
用户来自欺诈高发地区;
交易金额超过某个数值;
和上次登录的地址距离差距很大;
用户登录地与收货地不符;
用户第一次交易;
...
大型网站在运营过程中,结合业界的最新发现,会总结出数以千计的此类高风险交易规则。一种方案是在业务逻辑中通过编程方式使用 if... else ... 代码实现这些规则,可以预见,这些代码会非常庞大,而且由于运营过程中不断发现新的交易风险类型,需要不断调整规则,代码也需要不断修改...
机器学习
规则引擎虽然技术简单,但是随着规则的逐渐增加,出现规则冲突,难以维护等情况,而且规则越多,性能越差。大型互联网应用更倾向于使用机器学习模型进行风控。
高可用系统的度量
可用性指标
业界通常用多少个9来衡量网站的可用性,如 QQ 的可用性是4个9,即 QQ 服务99.99% 可用,这意味着 QQ 服务要保证其在所有运行时间中,只有0.01% 的时间不可用,也就是一年中大约53分钟不可用。
网站年度可用性指标 = (1 - 网站不可用时间 / 年度总时间)x 100%
网站不可用时间(故障时间)= 故障修复时间点 - 故障发现(报告)时间点
对可用性的定性描述,两个9是基本可用,年度停机时间小于88小时;3个9较高可用,年度停机时间 小于 9小时;4个9是具有自动恢复能力的高可用,年度停机时间小于 53 分钟; 5个9是极高可用性,年度停机时间小于 5 分钟。由于可用性影响因素很多,对于网站整体而言,达到4个9,乃至5个9的可用性,除了过硬的技术、大量的设备资金投入和工程师的责任心,还要有个好运气。
淘宝、支付宝、微信一般都宣称是99.99%。 如果更高一个成本太高,一个是技术上也比较难达到。一年53分钟不可用。更多是应用某个功能不可用,一般不会是全网站不可用。
Twitter 之前可用性是在 98% 是比较低的。
故障分类管理
故障处理流程及考核
引起故障的原因
硬件故障
软件 bug
系统发布
并发压力
网络攻击
外部灾害
高可用系统架构
解耦
高内聚、低耦合的组件设计原则
面向对象基本设计原则
面向对象设计模式
领域驱动设计建模
隔离
业务与子系统隔离
微服务与中台架构
生产者消费者隔离
虚拟机与容器隔离
异步
多线程编程
反应式编程
异步通信网络编程
事件驱动异步架构
备份
集群设计
数据库复制:CAP原理
任何情况下都不能只用一台服务器提供服务,任何服务都要提供2个以上的服务器。
都要考虑当一台服务器不可用的时候,其它服务器可以替代使用。架构师在系统架构设计的时候,都要考虑这种异常情况。
Failover (失效转移)
数据库主主失效转移。
负责均衡失效转移。
如何确认失效,需要转移?
设计无状态的服务。
幂等
应用调用服务失败后,会将调用请求重新发送到其它服务器,但是这个失败可能是虚假的失败。比如服务以及处理成功,但是因为网络故障应用没有收到响应,这时应用重新提交请求就导致服务重复调用,如果这个服务是一个转账操作,就会产生严重的后果。
服务重复调用有时候是无法避免的,必须保证服务重复调用和调用一次产生的结果相同,即服务具有幂等性。有些服务天然具有幂等性,比如将用户性别设置为女性,不管设置多少次,结果都一样。但是对于交易等操作,问题就会比较复杂,需要通过交易编号等信息进行服务调用有效性校验,只有有效的操作才继续执行。
事务补偿
传统事务的 ACID:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。
分布式事务的 BASE:基本可用(Basic Availability)、软状态(Soft-State)、最终一致性(Eventual Consistency)。
事务补偿:通过执行业务逻辑逆操作,使事务回滚到事务前状态。
重试
远程服务可能会由于线程阻塞、垃圾回收或者网络抖动,而无法及时返还响应,调用者可以通过重试的方式修复单词调用的故障。
上游调用者超时时间要大于下游调用者超时时间之和。
熔断
当某个服务出现故障,响应延迟或者失败率增加,继续调用这个服务会导致调用者请求阻塞,资源消耗增加,进而出现服务级联失效,这种情况下使用断路器阻断对故障服务的调用。
断路器三种状态:关闭,打开,半开。
Spring Cloud 断路器实现:Hystrix
限流
在高并发场景下,如果系统的访问量超过了系统的承受能力,可以通过限流对系统进行保护。限流是指对系统的用户请求进行流量限制,如果访问量超过了系统的最大处理能力,就会丢弃一部分的用户请求,保证整个系统可用,保证大部分用户是可以访问系统的。这样虽然有一部分用户的请求被丢弃,产生了部分不可用,但还是好过整个系统崩溃,所有的用户都不可用要好。
限流的几种方法:
计数器算法(固定窗口,滑动窗口)
令牌桶算法
漏桶算法
计数器(固定窗口)算法
使用计数器在周期内累加访问次数,当达到设定的限流值时,触发限流策略。下一个周期开始时,进行清零,重新计数。
固定窗口算法的临界点问题:假设1min 内服务器的负载能力为100,一次一个周期的访问量限制在100,然而在第一个周期的最后5秒和下一个周期的开始5秒时间段内,分别涌入100的访问量,虽然没有超过每个周期的限制量,但是整体上10秒 内达到200的访问量,以远远超过服务器的负载能力。
计数器(滑动窗口)算法
将时间周期分为N个小周期,分别记录着每个小周期内访问次数,并且根据时间滑动删除过期的小周期。
假设时间周期为1min, 将1min 再分为2个小周期,统计每个小周期的访问数量,则可以看到,第一个时间周期内,访问量为75,第二个时间周期内,访问数量为100,超过100的访问则被限流掉了。
令牌桶算法
以固定的速度向令牌桶中增加令牌,直到令牌桶满,请求到达时向令牌桶请求令牌,如获取到令牌则通过请求,否则触发限流策略。
漏桶算法
访问请求到达时直接放入漏桶,如当前容量已达到限流值,则进行丢弃。漏桶以固定的速率进行释放访问请求,直到漏桶为空。
自适应限流
没有提前的人工评估,便没有提前的评估过时与人的评估疏漏/错误!
实时自动评估QPS
业务流量的不确定性与技术方案的自适应天上一对!
淘宝2019年双十一上线了自适应限流。
降级
有一些系统功能是非核心的,但是它也给系统产生了非常大的压力,比如说在电商系统中又确认收货这个功能,即便我们不去确认收货,系统也会超时自动确认收货。
但是实际上确认收货这个操作是一个非常重的操作,因为它会对数据库产生很大的压力:它要进行更改订单状态,完成支付确认,并进行评价等一系列操作。如果在系统高并发的时候去完成这些操作,那么会对系统雪上加霜,使系统的处理能力更加恶化。
解决办法就是在系统高并发的时候,比如说像淘宝双11 的时候,当前可能整天系统都处于一种极限的高并发访问压力之下,这时候就可以将确认收货、评价这些非核心的功能关闭,将宝贵的系统资源留下来,给正在购物的人,让他们去完成交易。
异地多活
如果整个数据中心都不可用,比如说数据中心所在城市遭遇了地震,机房遭遇了火灾或者停电,这样的话,不管我们的设计和系统多么的高可用,系统依然是不可用的。
为了解决这个问题,同时也为了提高系统的处理能力和改善用户体验,很多大型互联网应用都采用了异地多活的多机房机构策略,也就是说数据中心分布在多个不同地点的机房里,这些机房都可以对外提供服务,用户可以连接任何一个机房进行访问,这样每个机房都可以提供完整的系统服务,即使某一个机房不可使用,机房也不会宕机,依然保持可用。
异地多活的难点是数据一致。
高可用系统的运维
发布
网站需要保证 7x24 小时高可用运行,同时网站又需要不断的发布新功能吸引用户以保证在激烈的市场竞争中获得成功。许多大型网站每周都需要发布一到两次,而中小型网站则更加频繁,一些处于快速发展期的网站甚至每天发布十几次。
不管发布的新功能是修改了一个按钮的布局还是增加一个核心交易功能,都需要在服务器上关闭原有的应用,然后重新部署启动新的应用,整个过程还要求不影响用户的使用。这相当于是要求飞行中的飞机换个引擎,既不能让飞机有剧烈的晃动,也不能让飞机降落,更不能让飞机坠毁。
既然网站的发布过程事实上和服务器宕机效果相当,那么就可以用服务器宕机的高可用方案来应对网站的发布。所以设计一个网站的高可用架构的时候,需要考虑的服务器宕机概率不是物理上的每年一两次,而是事实上的每周一两次。也许你认为这个应用不重要,重启也非常快,用户可以忍受每年一到两次的宕机故障,因而不需要复杂的高可用设计。事实上,由于应用的不断发布,用户需要面对的是每周一到两次的宕机故障。用户哭了。
自动化测试
代码在发布到线上服务器之前需要进行严格的测试。即使每次发布的新功能都是在原有系统功能上的小幅增加,但是为了保证系统没有引入未预料的 BUG,网站测试还是需要对整个网站功能进行全面的回归测试。此外还需要测试各种浏览器的兼容性,在发布频繁的网站应用中,如果使用人工来进行,成本和时间都难以承受。
目前大部分网站都采用 Web 自动化测试技术,使用自动测试工具或脚本完成测试。比较流行的 Web 自动化测试工具是 ThoughtWorks 开发的 Selenium。 Selenium 运行在浏览器中,模拟用户操作进行测试,因此 Selenium 可以同时完成 Web 功能测试和浏览器兼容测试。
手工测试和自动化测试的总体成本
雇个测试工程师,测试工程师在每次发布前进行应用测试。开始的时候,这种成本是非常小的,但是增长却很快。每次开发新功能都需要对新功能进行测试,而前面已经发布的各种功能也需要进行测试,确保开发新功能不会破坏现有的产品功能。也就是说,每次发布的测试成本都比前一次发布的测试成本高(测试效率随时间推移逐步降低)。这也会使软件的版本的发布周期逐渐变长,因为随着软件规模的增长,测试需要越来越长的时间。
自动化测试需要一些前置投资,你需要安装自动化测试工具,部署持续集成服务器,但是后续投入却是相对便宜的。一旦完成初始安装,只需要为新功能创建测试就可以了,测试已经存在的功能几乎不需要花费任何成本。随着时间的推移,测试会变得越来越高效,每一次发布测试,已经测试的代码和待测试的代码之比都在增加。最终,会到达一个平衡点,然后自动化测试的总体成本会低于手工测试的成本。
自动化部署
持续部署三步走
持续集成:允许工程师随时向公共分支提交代码,并立即进行自动化测试。
持续交付:除了跑单元测试及软件打包,持续交付机制会将软件部署到各种测试环境中。
持续部署:代码在没有人工干预的情况下被测试、构建、部署并推送到生产环境。
Amazon亚马逊 应用比较成熟,提供了很多工具。
持续部署流程
预发布验证
即使是经过严格的测试,软件部署到线上服务器之后还是经常会出现各种问题,甚至根本无法启动服务器。主要原因是测试环境和线上环境并不相同,特别是应用需要依赖的qita服务,如数据库,缓存,公用业务服务等,以及一些第三方服务,如电信短信网关、银行网银接口等。也许是接口变化导致的通信失败;也许是配置错误导致连接失败;也许依赖的服务在线上环境还没有准备好;这些问题都有可能导致应用故障。
因此在网站发布的时候,并不是把测试通过的代码包直接发布到线上服务器,而是先发布到预发布机器上,开发工程师和测试工程师在预发布服务器上进行预发布验证,执行一两个典型的业务流程,确认系统没有问题后才正式发布。
预发布服务器是一种特殊用途的服务器,它和线上的正式服务器唯一的不同就是没有配置在负载均衡服务器上,外部用户无法访问。
代码版本控制
对于大型互联网系统,核心应用系统和公用业务模块涉及许多团队和工程师,需要对相同的代码库进行共同开发和维护,而这些团队对同一个应用的开发维护,其开发周期和发布时间点各不相同。如何进行代码管理,既能保证代码发布版本的稳定正确,同时又能保证不同团队的开发互不影响。
主干开发、分支发布
主干开发、分支发布:
代码修改都在主干上进行,需要发布的时候,从主干上拉一个分支发布,该分支即成为一个发布版本,如果该版本发现 Bug,继续在该分支上修复发布,并将修改合并(merge)会主干,直到下次主干发布。
分支开发,主干发布
分支开发,主干发布:
*任何修改都不得在主干上直接进行,需要开发一个新功能或者修复一个 bug 的时候,从主干拉一个分支进行开发,开发完成测试通过后,合并回主干,然后从主干进行发布,主干上的代码永远是最新发布的版本。
两种分支方式优缺点
两种方式各有优缺点。主干开发、分支发布方式,主干代码反应目前整个应用的状态,一目了然,便于管理和控制,也利于持续集成。分支开发,主干发布方式,各个分支独立进行,互不干扰,可以使不同发布周期的开发在同一应用中进行。
目前互联网应用开发中主要使用的是分支开发、主干发布的方式。
自动化发布(小团队合适)
网站的版本发布频繁,整个发布过程需要许多团队合作,发布前,多个代码分支合并回主干可能发生冲突(conflict),预发布验证也会带来风险,每次发布又相当于一次宕机事故。因此网站发布过程荆棘丛生,一不小心就会踩到雷。
阿里巴巴曾经执行的自动化发布流程,单体架构的时候用过。
灰度发布
应用发布完成功后,仍然可能会发现因为软件问题而引入的故障,这时候就需要做发布回滚,即卸载刚刚发布的软件,将上一个版本的软件包重新发布,使系统复原,消除故障。
大型网站的主要业务服务器集群规模非常庞大,比如 QQ 的服务器数量超过一万台。一旦发现故障,即使想要发布回滚也需要很长时间才能完成,只能眼睁睁看着故障时间在不断增加干着急。为了应付这种局面,大型网站会使用灰度发布模式,将集群服务器分成若干部分,每天只发布一部分服务器,观察运行稳定没有故障,第二天继续发布一部分服务器,持续几天的时间才把整个集群全部发布完毕,期间如果发现问题,就只需要回滚发布的一部分服务器即可。
网站运行监控
”不允许没有监控的系统上线“,这是许多网站架构师在做项目上线评审的时候常说的一句话。网站运行监控对于网站运维和架构设计优化至关重要,没有监控的网站,犹如盲人骑瞎马,夜半临深渊而不知。生死未卜,提高可用性、减少故障率就更无从做起了。
监控数据采集
广义上的网站监控涵盖所有非直接业务行为的数据采集与管理,包括供数据分析师和产品设计师使用的网站用户行为日志,业务运行数据和系统性能数据等。
用户行为日志收集
用户行为日志指用户在浏览器上所做所有操作及其所在的操作环境,包括用户操作系统与浏览器版本信息, IP 地址,页面访问路径,页面停留时间等,这些数据对统计网站 PV/UV 指标,分析用户行为,优化网站设计,个性化营销与推荐等非常重要。
具体用户行为日志收集手段有两种:
服务端日志收集,这个方案比较简单,Apache 等几乎所有 Web 服务器都具备日志记录功能,可以记录大部分用户行为日志,开启 Web 服务器的日志记录功能即可。其缺点是可能会出现信息失真,如 IP 地址是代理服务器地址而不是用户真实 IP;多个链接指向同一个页面的情况下无法分辨访问路径等。
客户端App、浏览器日志收集,浏览器可以收集用户真实的操作行为,因此比服务器日志收集更加精准。其缺点是比较麻烦,需要在页面嵌入特定的 JS 脚本完成。
服务器性能监控
收集服务器性能指标,如系统 Load,内存占用,磁盘IO,网络IO 等对尽早做出故障预警,及时判断应用状况,防患于未然,将故障扼杀在萌芽时期非常重要。此外根据性能监控数据,运维工程师可以合理安排服务器集群规模,架构师及时改善系统性能及调整系统伸缩性策略。
目前网站使用比较广泛的开源性能监控工具是 Ganglia, 支持大规模服务器集群,并支持以圆形的方式在浏览器展示实时性能曲线。
业务运行数据报告
除了服务器系统性能监控,网站还需要监控一些具体业务场景相关的技术和业务指标,比如缓冲命中率、平均响应延迟时间、每分钟发送邮件数目、待处理的任务总数等。不同于服务器性能监控,网站运维人员可以在初始化系统的时候统一部署,业务运行数据需要在具体程序中采集并报告,汇总后统一显示。
监控管理
监控数据采集后,除了用作系统性能评估、集群规模伸缩性预测等,还可以根据实时监控数据进行风险预警,并对服务器进行失效转移,自动负载调整,最大化利用集群所有机器的资源。
报警
服务器运行正常的情况下,其各项监控指标基本稳定在一个特定水平,如果这些指标超过某个阀值,就与围着系统将要出现故障,这时候需要对相关人员报警,及时采取措施,在故障还未真正发生就将其扼杀在萌芽状态。
监控管理系统可以配置报警阀值和值守人员的联系方式,报警方式除了邮件,即时通讯工具,还可以配置手机短信,语音报警,保证发生报警时,工程师即使在千里之外、夜里睡觉也能及时通知,迅速响应。
自动控制
自动失效转移:除了应用程序访问失败时进行失效转移,监控系统也可以在发现故障的情况下主动通知应用,进行失效转移。
自动扩容:如果因访问压力大而导致服务器性能指标下降,监控系统自动触发服务器集群扩容。
自动限流:根据监控指标,自动控制访问流量。
监控系统架构
比较好的开源监控系统:大众点评
高可用的价值观
保持简单,使问题易于发现,快速解决。
目标明确,解决特定环境下的具体问题。
价值回归,成本收益要合理。
总结
目前很多架构师都倾向于复杂的架构,主要是别人会质疑架构师的能力。如果这么简单就能够实现,还要架构师干嘛。
版权声明: 本文为 InfoQ 作者【John(易筋)】的原创文章。
原文链接:【http://xie.infoq.cn/article/3d872d41707fa39361627f716】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论