欢迎你们前往腾讯云技术社区,获取更多腾讯海量技术实践干货哦~
前端
做者: 林喜东
人与人之间最重要的是信任,但程序的世界里,可能信任越少越好;我愈加以为越是高性能高可用的系统里,不信任原则会体现得更加淋漓尽致。 为了少走弯路,写下这篇文章留给本身参考,其中一些是本身踩过的一些坑;一些是接手他人系统时触过的雷;还有一些是从别人分享的经验学习得来;能力有限,先记下本身的一些体会,错误的地方再慢慢改正。程序员
编程,是一件容易的事,也是一件不容易的事。说它容易,是由于掌握一些基本的数据类型和条件语句,就能够实现复杂的逻辑;说它不容易,是由于高性能高可用的代码,须要了解的知识有不少不少;编程的世界,也跟扫雷游戏的世界同样,充满雷区,十面埋伏,一不当心,随时均可能踩雷,随时均可能Game Over。算法
而玩过扫雷的人都知道,避免踩雷的最好方法,就是提早识别雷区并作标记(设防)避免踩踏。sql
鉴于此,编程的世界里,从输入到输出一样须要到处设防,步步为营。编程
(1)对空指针的检查后端
不仅是输入,只有是使用到指针的地方,都应该先判断指针是否为NULL,而内存释放后,应当将指针设置为NULL。安全
【真实案例】:注册系统某段逻辑,正常使用状况下,都有对指针作检查,在某个错误分支,打印日志时,没检查就使用了该字符串;结果可正常运行,但当访问某个依赖模块超时走到改分支,触发bug,致使coredump。网络
(2)对数据长度的检查xss
使用字符串或某段buf,特别是memcpy/strcpy时,须要尽可能对数据长度作下检查和截断。性能
【真实案例】:接手oauth系统后运行数月表现良好,忽然有一天,发生了coredump,经查,是某个业务不按规定请求包中填写了超长长度,致使memcpy时发生段错误,根本缘由,仍是没有作好长度检查。
(3)对数据内容的检查
某些场景下,没有对数据内容作检查就直接使用,可能致使意想不到的结果。
【案例】:sql 注入和 xss 攻击都是利用了服务端没有对数据内容作检查的漏洞。
变动的影响通常体如今输出,有时候输出的结果并不能简单的判断是否正常,如输出是加密信息,或者输出的内容过于复杂。
因此,对于每次变动
(1)修改代码时,采用不信任编码,正确的不必定是“对”的,再小的修改也应确认其对后续逻辑的影响,有些修正可能改变原来错误时的输出,而输出的改变,就会影响到依赖该改变字段的业务。
(2)发布前,应该对涉及到的场景进行测试和验证,测试能够有效的发现潜在的问题,这是众所周知的。
(3)发布过程,应该采用灰度发布策略,由于测试并不是老是能发现问题,灰度发布,能够减小事故影响的范围。常见灰度发布的策略有机器灰度、IP灰度、用户灰度、按比例灰度等,各有优缺点,须要根据具体场景选择,甚至能够同时采用多种的组合。
(4)发布后,全面监控是有效发现问题的一种方法。由于测试环境和正式环境可能存在不一致的地方,也可能测试不够完整,致使上线后有问题,因此需采起措施补救
A:如使用Monitor监控请求量、成功量、失败量、关键节点等
B:使用DLP告警监控成功率
C:发布完,在正式环境测试一遍
【案例】oauth系统某次修改后编译时,发现有个修改不相关的局部变量未初始化的告警,出于习惯对变量进行了初始化(初始化值和编译器默认赋值不同),而包头某个字段采用了该未初始化的变量,但在测试用例中未能体现,监控也没细化到每一个字段的值,致使测试正常,监控正常;但前端业务齐齐互动使用了该包头字段,致使发布后影响该业务。
通常的系统,都会有上下游的存在,正以下图所示
而上下游的整个链路中,每一个点都是不能保证绝对可靠的,任何一个点均可能随时发生故障,让你措手不及。
所以,不能信任整个链路中的任何一个点,需进行设防。
主要措施以下:
(1)服务监控
前面所述的请求量、成功量、失败量、关键节点、成功率的监控,都是对服务环节的单点监控。
在此基础上,能够加上自动化测试,自动化测试能够模拟应用场景,实现对于流程的监控。
(2)进程秒起
人可能在程序世界里是不可靠的因素(大牛除外),前面的措施,可能是依赖人来保证的;因此,coredump仍是有可能发生的,这时,进程秒起的实现,就能够有效减小coredump的影响,继续对外提供服务。
可采用柔性可用策略,对于根据模块的不可或缺性,区分关键路径和非关键路径,并采起不一样的策略
(1)对于非关键路径,采用柔性放过策略
当访问非关键路径超时时,简单的可采起有限制(必定数量、必定比重)的重试,结果超时则跳过该逻辑,进行下一步;复杂一点的统计一下超时的比例,当比例太高时,则跳过该逻辑,进行下一步
(2)对于关键路径,提供弱化服务的柔性策略
关键路径是不可或缺的服务,不能跳过;某些场景,能够根据目的,在关键路径严重不可用时,提供弱化版的服务。举例如派票系统访问票据存储信息严重不可用时,可提供不依赖于存储的纯算法票据,为弥补安全性的确实,可采起缩短票据有效期等措施。
(1)对请求来源的不信任
有利可图的地方,就会有黑产时刻盯着,伪造各类请求,对此,可采起以下措施
A:权限控制
如ip鉴权、模块鉴权、白名单、用户登陆态校验等
B:安全审计
权限控制仅能打击一下非正常流程的请求,但坏人常常可以成功模拟用户正常使用的场景;因此,对于一些重要场景,须要加入安全策略,打击如IP、号码等信息汇集,频率过快等机器行为,请求重放、劫持等请求)
(2)对请求量的不信任
前端的请求,不老是平稳的;有活动时,会暴涨;前端业务故障恢复后,也可能暴涨;前端遭到恶意攻击时,也可能暴涨;一旦请求量超过系统负载,将会发生雪崩,最终致使整个服务不可用,对此种种突发状况,后端服务须要有应对措施
A:频率限制,控制各个业务的最大请求量(业务根据正常请求峰值的2-3倍申请,该值可修改),避免因一个业务暴涨影响全部业务的状况发生。
B:过载保护,虽然有频率限制,但业务过多时,依然有可能某个时间点,全部的请求超过了系统负载,或者到某个IDC,某台机器的请求超过负载,为避免这种状况下发生雪崩,将超过必定时间的请求丢弃,仅处理部分有效的请求,使得系统对外表现为部分可用,而非彻底不可用。
机器故障时有发生,若是服务存在单点问题,故障时,则服务将彻底不可用,而依赖人工的恢复是不可预期的,对此,可经过如下措施解决
(1)容灾部署
即至少有两台以上的机器能够随时对外提供服务。
(2)心跳探测
用于监控机器是否可用,当机器不可用时,若涉及到主备机器的,应作好主备机器的自动切换;若不涉及到主备的,禁用故障机器对外提供服务便可。
现实生活中,整个机房不可用也是有发生过的,如2015年的天津滨海新区爆炸事故,致使腾讯在天津的多个机房不能对外提供正常服务,对此采起的措施有:
(1)异地部署
不一样IDC、不一样城市、不一样国家等部署,可用避免整个机房不可用时,有其余机房的机器能够对外提供服务
(2)容量冗余
对于相似QQ登录这种入口型的系统,必须保持两倍以上的冗余;如此,能够保证当有一个机房故障时,全部请求迁移到其余机房不会引起系统过载。
虽然咱们愈来愈离不开电力,但电力却不能保证一直在为咱们提供服务。断电时,其影响和机器故障、机房故障相似,机器会关机,数据会丢失,因此,须要对数据进行备份。
(1)磁盘备份
来电后,机器重启,能够从磁盘中恢复数据,但可能会有部分数据丢失。
(2)远程备份
机器磁盘坏了,磁盘的数据会丢失,使用对于重要系统,相关数据应当考虑采用远程备份。
(1)不一样地方,网络时延不同
通常来讲,本地就近的机器,时延要好于异地的机器, 因此,比较简单的作法就是近寻址,如CMLB。
也有部分状况,是异地服务的时延要好于本地服务的时延,因此,若是要作到较好的最优路径寻址,就须要先作网络探测,如Q调
(2)常有网络有波动或不可用状况
和机器故障同样处理,应当作到自动禁用;但网络故障和机器故障又不同,常常存在某台机器不可用,但别的机器能够访问的状况,这时就不能在服务端禁用机器了,而应当采用本地回包统计策略,自动禁用服务差机器;同时需配合定时探测禁用机器策略,自动恢复可正常提供服务机器。
人的因素在运营的世界里实际上是不稳定的因素(大牛除外),因此,不能对人的操做有过多的信任。
(1)操做备份
每一步操做都有记录,便于发生问题时的回溯,重要的操做须要review,避免我的考虑不周致使事故。
(2)效果确认
实际环境每每和测试环境是存在一些差别,全部在正式环境作变动后,应经过视图review和验证来确认是否符合预期。
(3)变动可回滚
操做前需对旧程序、旧配置等作好备份,以便发生故障时,及时恢复服务。
(4)自动化部署
机器的部署,可能有一堆复杂的流程,如各类权限申请,各类客户端安装等,仅靠文档流程操做加上测试验证时不够的,可能某次部署漏了某个步骤而测试又没测到,上线后就可能发生事故若能全部流程实现自动化,则可有效避免这类问题。
(5)一致性检查
现网的发布可能因某个节点没同步致使漏发,也就是不一样的机器服务不同;对此,有版本号的,可经过版本号监控发现;没版本号的,则需借助进程、配置等的一致性检查来发现问题。
备注:以上提到的不信任策略,有的不能简单的单条使用,须要结合其余的措施一块儿使用的。
好了,先写这么多。最重要的仍是那句话,程序的世界里,应该坚持不信任原则,到处设防。
程序员的江湖:从黑木崖到回龙观
手工完成自建迁移_from RDS to CDB
理解 JDK 中的 MethodHandle
此文已由做者受权腾讯云技术社区发布,转载请注明文章出处
原文连接:cloud.tencent.com/community/a…