我之前帮同行朋友排查过一次线上服务不稳定的问题,整套环境搭在aws亚马逊上。朋友之前一直做本地机房的项目开发,第一次接触公有云的大规模部署,折腾了两天都没定位到原因,最后发现问题出在一个很基础的配置细节上。很多第一次接触aws亚马逊的普通开发者,都会碰到类似的情况------不是技术能力不够,而是对平台的基础设计逻辑不熟悉,容易用惯性思维去配置,最后踩了没必要的坑。这篇就整理几个我实际接触过的常见问题,把基础概念理清楚。
基础概念容易搞混的点
很多人第一次打开aws亚马逊的控制台,都会看到区域和可用区两个选项,不少人下意识会认为,区域就是一个大型机房,可用区只是机房里划分的不同机架,本质上差别不大,这种理解其实是错的。aws亚马逊的区域是指一个地理范围内的服务集群,通常围绕一个大城市部署,而每个区域之下,会至少设置两个完全独立的可用区。每个可用区对应一座物理隔离的独立机房,拥有单独的供电、冷却系统和主干网络接入,不同可用区之间保持几公里到几十公里的物理距离,靠低延迟的私有光纤连接,相互之间的延迟通常可以控制在1毫秒以内。这种设计的核心目标就是做故障隔离,一个可用区因为自然灾害或者设备故障出问题的时候,同一区域的其他可用区不会受影响,服务可以快速切换过去。
很多新人部署项目的时候,图操作方便,把所有的实例、数据库都放在同一个可用区,平时运行看不出问题,真碰到可用区级别的故障,整个服务都会直接中断,连回滚恢复的立足点都没有。我接触过的几个类似故障,都是开发者一开始不理解这个设计,觉得多可用区部署麻烦,没必要,出问题之后才追悔莫及。
除了可用区的概念,区域选择也是很多人容易错的地方。很多人选区域的时候,随便选一个默认的,或者选一个看起来配额比较充足的区域,完全不考虑服务用户的物理位置,这就很容易出问题。如果用户群体集中在某一个地理区域,却选了远在另一处的区域部署,直接的结果就是访问延迟偏高,还更容易出现链路波动。我开头提到的那个朋友,当初就是犯了这个错,他选了一个离目标用户一万多公里的区域,平时访问延迟就接近三百毫秒,高峰期直接出现大量请求超时,他一开始还以为是自己的代码性能不够,折腾了快两天才想到去查网络延迟,最后才定位到问题。跨区域复制备份数据的时候,也要考虑链路的带宽情况,如果备份数据量比较大,尽量避开业务高峰期操作,不然会占用生产链路的带宽,影响正常业务的响应速度。
权限配置的常见误区
aws亚马逊的权限体系是细粒度的身份与访问管理,核心设计思路是最小权限原则,也就是每个服务、每个身份只获取完成任务必需的权限,不需要的权限一概不开放。但很多开发者做小型项目或者测试项目的时候,嫌一步步配置权限太麻烦,图省事直接给新建的角色开放了管理员权限,觉得这样不会碰到权限不够的报错,省时间。这其实是非常大的安全隐患。
我之前听过同行分享过一个案例,一个创业团队的测试项目部署在aws亚马逊上,因为给实例开了过度的权限,又开放了一个公共的测试端口,被自动扫描工具发现之后,出现了大量非预期的资源创建操作,整个项目的资源拓扑被完全打乱,团队花了整整三天才清理完异常资源,找回了重要数据,耽误了项目的上线进度。其实不管用哪个云平台,过度开放权限都是危险的,只是aws亚马逊的权限体系天生做得非常细,很多习惯了宽松权限配置的开发者,会不习惯这种繁琐的步骤,反而更容易踩这个坑。这里的经验很简单:哪怕是测试项目,也要坚持按最小权限原则配置,需要访问哪个存储桶就只给这个存储桶的权限,需要调用哪个服务就只开放这个服务的权限,刚开始配置的时候多花十几分钟,后面能避免很多不可控的问题。
还有一个常见的误区是访问密钥的管理,很多开发者做本地测试的时候习惯用长期有效的访问密钥,部署到云服务器之后,也直接把密钥写在配置文件里,甚至不小心跟着代码提交到了代码仓库。哪怕是内部的私有代码仓库,也存在密钥泄露的风险。aws亚马逊本身提供了IAM角色的方式给实例授权,实例启动的时候会自动获取需要的临时权限,不需要在配置文件里存储明文密钥,很多第一次接触aws亚马逊的开发者不知道这个功能,还是沿用原来的操作习惯,给项目留下了安全隐患。
备份容灾容易忽略的细节
做服务部署,备份容灾永远是不能忽略的环节,很多人用aws亚马逊的对象存储服务存备份,默认会把备份文件放在和生产实例同一个区域,觉得这样恢复的时候下载速度快,操作方便。但实际上,备份的核心作用是应对极端故障,如果整个区域都出现了网络或者电力故障,备份放在同一个区域,也就一起没法访问了,从结果来看,起不到容灾的作用。aws亚马逊的服务可用性已经做到了很高的水平,但哪怕是最高等级的服务可用性协议,也不承诺单个区域100%不会出问题,跨区域备份是应对区域级故障的必要手段。
还有一个非常容易被忽略的细节,就是很多人只做备份,从来不做恢复测试。把备份文件传上去就不管了,也不验证备份是不是完整可用,真出了问题要恢复的时候,才发现备份文件损坏,或者权限配置不对,下载不下来,这种情况我碰到过不止一次。我自己养成的习惯是,不管用哪个平台的服务,每个季度都会抽一两个小时,抽一份最近的备份做完整的恢复测试,aws亚马逊上面也一样,这个步骤花不了多少时间,但是能在真出问题的时候帮你省大量的时间,避免更大的损失。
另外,aws亚马逊很多存储服务默认会开启版本控制功能,会自动保留对象的历史版本,如果不需要保留所有历史版本,可以根据自己的需求设置版本保留规则,避免不必要的资源占用。
默认配置的隐形坑
aws亚马逊很多服务的默认配置,是为了适配大多数通用场景设计的,不会针对高负载的业务场景做优化,很多新人直接用默认配置跑业务,高峰期就容易出莫名其妙的问题,排查半天找不到原因。
最常见的就是块存储的IO性能配置,默认的通用型块存储,IOPS是有上限的,如果你的业务是跑关系型数据库,或者有大量随机读写请求的应用,默认配置的IO性能根本满足不了需求,高峰期磁盘IO会被打满,磁盘等待队列变长,直接导致整个服务的响应速度变慢。很多人碰到这种问题,第一反应是优化代码、调整数据库索引,折腾了好几天最后才发现是存储的性能不够,白白浪费了大量的排查时间。我开头提到的那个朋友的问题,其实也有这个因素,他的数据库用了默认的块存储配置,高峰期IO打满,再加上选址不对,两个问题叠加,就更难定位了。
还有一个常见的问题是监控配置,aws亚马逊的默认监控策略,很多服务只开放了基础的五分钟粒度指标,更详细的指标比如每个磁盘的IO等待时间、每个网络接口的进出流量,需要手动开启详细监控。如果不开详细监控,出问题的时候你只能看到CPU使用率整体偏高,看不到具体是哪里的IO卡住了,排查起来非常费劲。我那个朋友就是没开详细监控,对着监控面板看了大半天,都没发现是磁盘IO的问题,最后还是开了详细监控才看到异常。
某种意义上说,aws亚马逊的设计逻辑更偏向于大规模分布式系统的部署管理,对于习惯了小规模开发的普通开发者来说,刚开始接触会觉得步骤繁琐,很多规则和用惯的平台不一样,但是只要把这些基础概念理清楚,理解设计背后的思路,就会发现这些繁琐的步骤其实都是为了减少后续的风险。其实不管用哪个云平台,核心的原则都是相通的:做好故障隔离、坚持最小权限、提前准备容灾、验证配置有效性,这些最基础的点,往往最容易被忽略,也最容易出大问题。