草庐IT

不存在百分百的安全,该给你的系统上个保险了

程序猿DD 2023-03-28 原文

故障,是每个技术人都不愿遇到,但却总会遇到的事件。程序Bug、安全漏洞、黑客攻击、服务器宕机、网络中断等诸多因素都有可能引发系统故障,使我们的业务面临瘫痪的窘境。这样的例子,国内外都在不断的发生,比如:
2020年,由于严重的全澳性IT故障,Coles的收银机全部不能联网,down机瘫痪。收银员扫不了货品顾客也不能结账,澳洲每家Coles超市都被迫暂时关闭。
2018年,上海的医疗保险信息系统就突发故障,波及上海各大医院的结算系统,致使大量市民在就医时无法正常使用医保卡,众多医院的排队窗口前纷纷大排长龙,场面混乱。事发之后就有不少网友质疑,涉及面如此之广的医保信息系统,“难道没有应急措施?”
这些活生生的真实案例都在提醒我们,技术赋能业务产生更高效率、获取更多价值的同时,保障系统稳定运行也至关重要。一旦系统出现大范围、长时间故障,致使业务中断的后果可能直接磨灭技术赋能带来的收益,甚至还可能带来经济损失、品牌受损等严重后果。

所以,有必要给我们的系统上一份“保险”——构建高可用的系统架构,这是每个技术团队都在努力的核心目标。

什么是高可用

那么怎么样的系统是否具备高可用能力的呢?我认为主要考量两个方面:容错与容灾。

容错能力指的是当故障来临时,业务系统是否可以不中断,继续服务的能力。常规措施就是集群化部署,同样业务的应用部署多台服务器,即时有个别服务坏了,其他服务依然可以提供业务支持。这就像飞机配置多台引擎一样,即时有一台坏了,剩下的依然可以支撑它飞行到指定地点安全着陆。

容灾能力指的是当重大灾难来临时,容错能力已经全部失效了,但我们依然有能力通过一些手段让业务重新恢复。常规措施就是备份,当某个机房发生了严重的故障,所有服务器都无法正常工作了,但数据备份还在,那我们就可以重新加载它们并让系统重新运行起来。这就好比飞机上的引擎全部坏了,但为了保证飞行任务以后还能执行,必须提供保护飞行员逃生的装置,比如通过弹射跳伞的方式令其可以幸存下来,之后又继续再其他飞机上继续执行任务。

高可用系统的构建准备

首先,在构建高可用系统之前,我们要对故障有几个基本的认识:没有任何一个设施是100%安全可靠的。所以,一个系统在设计高可用架构的时候,复杂度随涉及的设施的数量增多而变高。

其次,我们需要尽可能的精简运维体系。简单的说,上云是大部分企业的最佳选择。除非自身团队在同预算的情况下,能够在基建维护上达到相同乃至更高的可用性。不然你机房建设、服务器、网络等基础设施的维护可能都将要你半条命。

再者,必须平常心对待可用性保障,这个道理就不多说了。意外总是在发生,翻翻过去的那些故障,是不是都还历历在目:

2022年6月,Cloudflare的意外中断导致大量热门网站访问出现问题
2021年12月,AWS大面积故障导致大量网站无法服务,亚马逊电商也遭受重创2021年5月,IBM Cloud在短短5天里连续发生两次严重的中断事故
2020年3月,Google Cloud多个地区的云服务瘫痪,时间长达14小时
2019年2月,Google Cloud因光纤受损出现网络问题,时间长达10小时
2018年4月,Azure因受雷雨天气影响导致电压激增而中断服务,时间长达28小时
但是。正因为没有100%的无故障,我们才要用高可用,因为这是唯一挽救你造成巨大财产损失的机会。

最后,我们不得不正视一个云服务用户的常见误区。当我们选择云服务商的时候,需要明确云厂商到底给我们提供了哪些高可用能力,而剩下的高可用能力覆盖是需要我们自己设计和实现的。我们要知道,一个高可用系统的构建是贯穿基础设施、中间件、服务端、客户端等多方面的。对稳定性高度敏感的企业一定要平常心看待故障 ,用好高可用。

(下图展示了云服务厂商和用户的高可用上的责任模型:云服务商提供的主要是基础硬件服务的高可用能力。而我们之前所提到的业务容错(负载架构)、容灾(保障数据备份)能力都是在用户侧的。供参考)

所以,如果在上云的时候,对自身业务系统不做额外的高可用保障,那就很可能出现文章开始我们提到的那些业务窘境。

总结

今天跟大家聊了聊系统上云时,容易被忽略的高可用问题,以及如何做好云上高可用架构的方法。对此你有什么想法呢?留言区一起聊一聊。

欢迎关注我的公众号:程序猿DD。第一时间了解前沿行业消息、分享深度技术干货、获取优质学习资源

有关不存在百分百的安全,该给你的系统上个保险了的更多相关文章

  1. ruby - 如何使用 Ruby aws/s3 Gem 生成安全 URL 以从 s3 下载文件 - 2

    我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A

  2. ruby - 如何安全地删除文件? - 2

    在Ruby中是否有Gem或安全删除文件的方法?我想避免系统上可能不存在的外部程序。“安全删除”指的是覆盖文件内容。 最佳答案 如果您使用的是*nix,一个很好的方法是使用exec/open3/open4调用shred:`shred-fxuz#{filename}`http://www.gnu.org/s/coreutils/manual/html_node/shred-invocation.html检查这个类似的帖子:Writingafileshredderinpythonorruby?

  3. ruby-on-rails - rspec - 如何检查方法是否存在? - 2

    我的模型有defself.empty_building//stuffend我怎样才能对这个现有的进行rspec?,已经尝试过:describe"empty_building"dosubject{Building.new}it{shouldrespond_to:empty_building}endbutgetting:Failure/Error:it{shouldrespond_to:empty_building}expected#torespondto:empty_building 最佳答案 你有一个类方法self.empty_bu

  4. ruby - 用 YAML.load 解析 json 安全吗? - 2

    我正在使用ruby2.1.0我有一个json文件。例如:test.json{"item":[{"apple":1},{"banana":2}]}用YAML.load加载这个文件安全吗?YAML.load(File.read('test.json'))我正在尝试加载一个json或yaml格式的文件。 最佳答案 YAML可以加载JSONYAML.load('{"something":"test","other":4}')=>{"something"=>"test","other"=>4}JSON将无法加载YAML。JSON.load("

  5. ruby-on-rails - ActiveRecord 的 find_or_create* 方法是否存在根本性缺陷? - 2

    有几种方法:first_or_create_by、find_or_create_by等,它们的工作原理是:与数据库对话以尝试找到我们想要的东西如果我们找不到,就自己做保存到数据库显然,并发调用这些方法可能会使两个线程都找不到它们想要的东西,并且在第3步中一个线程会意外失败。似乎更好的解决方案是,创建或查找即:提前在您的数据库中创建合理的唯一性约束。如果你想保存一些东西,就保存它如果有效,那就太好了。如果它因为RecordNotUnique异常而无法工作,它已经存在,太好了,加载它那么在什么情况下我想使用Rails内置的东西而不是我自己的(看起来更可靠)create_or_find?

  6. ruby-on-rails - 安全地显示使用回形针 gem 上传的图像 - 2

    默认情况下:回形针gem将所有附件存储在公共(public)目录中。出于安全原因,我不想将附件存储在公共(public)目录中,所以我将它们保存在应用程序根目录的uploads目录中:classPost我没有指定url选项,因为我不希望每个图像附件都有一个url。如果指定了url:那么拥有该url的任何人都可以访问该图像。这是不安全的。在user#show页面中:我想实际显示图像。如果我使用所有回形针默认设置,那么我可以这样做,因为图像将在公共(public)目录中并且图像将具有一个url:Someimage:看来,如果我将图像附件保存在公共(public)目录之外并且不指定url(同

  7. ruby - 检查网络文件是否存在,而不下载它? - 2

    是否可以在不实际下载文件的情况下检查文件是否存在?我有这么大的(~40mb)文件,例如:http://mirrors.sohu.com/mysql/MySQL-6.0/MySQL-6.0.11-0.glibc23.src.rpm这与ruby​​不严格相关,但如果发件人可以设置内容长度就好了。RestClient.get"http://mirrors.sohu.com/mysql/MySQL-6.0/MySQL-6.0.11-0.glibc23.src.rpm",headers:{"Content-Length"=>100} 最佳答案

  8. ruby-on-rails - 如果存在则更新,否则什么也不做? - 2

    当且仅当模型存在时,我才尝试更新模型的值。如果没有,我什么都不做。搜索似乎只返回更新或创建问题/答案,但我不想创建。我知道我可以用一个简单的方法来做到这一点:found=Model.find_by_id(id)iffoundupdatestuffend但是,我觉得有一种方法可以在一次调用中完成此操作,而无需分配任何临时本地值或执行if。如果记录不存在,我该如何编写一个Rails调用来更新记录而不出现嘈杂错误?最新的Rails3.x 最佳答案 您可以使用try在对find_by_id或where的结果调用update_attribut

  9. ruby - 如何使用 Ruby 检查域是否存在? - 2

    类似的东西:defdomain_exists?(domain)#performcheck#returntrue|falseendputs"valid!"ifdomain_exists?("example.com") 最佳答案 require'socket'defdomain_exists?(domain)beginSocket.gethostbyname(domain)rescueSocketErrorreturnfalseendtrueend 关于ruby-如何使用Ruby检查域是否存

  10. ruby-on-rails - 检查 Rails/Ruby 中对象是否存在的正确方法是什么? - 2

    我有很多模型和关系。由于这个事实,在View/Controller中有很多调用,看起来像这样:@object.something.with_something.value链的某些部分最终可能为零,这完全没问题。检查终端对象是否存在的正确/干净/快速的方法是什么?正在调用类似的东西:@object.something.with_something.valueifdefined?@object.something.with_something.value还可以吗? 最佳答案 在本地,您需要使用&&运算符(不是defined?),但这很快

随机推荐