Eswlnk Blog Eswlnk Blog
  • 资源
    • 精彩视频
    • 破解专区
      • WHMCS
      • WordPress主题
      • WordPress插件
    • 其他分享
    • 极惠VPS
    • PDF资源
  • 关于我
    • 论文阅读
    • 关于本站
    • 通知
    • 左邻右舍
    • 玩物志趣
    • 日志
    • 专题
  • 热议话题
    • 游戏资讯
  • 红黑
    • 渗透分析
    • 攻防对抗
    • 代码发布
  • 自主研发
    • 知识库
    • 插件
      • ToolBox
      • HotSpot AI 热点创作
    • 区块
    • 快乐屋
    • 卡密
  • 乱步
    • 文章榜单
    • 热门标签
  • 问答中心反馈
  • 注册
  • 登录
首页 › 攻防对抗 › BEAM 虚拟机是如何进行容错处理?

BEAM 虚拟机是如何进行容错处理?

Eswlnk的头像
Eswlnk
2022-07-17 12:08:39
BEAM 虚拟机是如何进行容错处理?-Eswlnk Blog
智能摘要 AI
文章探讨了BEAM虚拟机(用于Elixir和Erlang代码)的容错特性及其在编写可靠应用程序中的作用。容错不仅有助于系统恢复,还能简化错误处理,使开发者专注于业务逻辑。文章区分了预期错误(如无效输入)和意外错误(如硬件故障),建议通过容错机制处理意外错误,减少不必要的错误处理代码。通过“让其失败”的策略,开发者可以编写更简洁、自信的代码,利用模式匹配和断言检查假设,确保核心逻辑的纯净性。BEAM的独特之处在于其进程隔离机制,允许单个进程的失败不影响整体系统。文章强调了明确规范的重要性,并鼓励开发者充分利用容错特性,享受对意外错误的无知。

BEAM 虚拟机(运行我们的 Elixir 和 Erlang 代码的虚拟机)以容错而闻名。关于用 Erlang 编写的许多可靠应用程序的好故事。人们倾向于将其高可靠性归因于语言的容错性。但我认为这种归因只对了一半。容错确实有帮助,但这只是一个很好的起点。容错性的真正亮点在于,一旦代码处于意外状态,我们就可以让它失败,我们可以编写更少的错误处理代码,我们可以更多地关注我们的业务逻辑。使用更简单的代码,我们可以更轻松地维护我们的应用程序,增加我们使这些应用程序更可靠并长期维护它们的机会。这篇文章解释了为什么会这样,以及如何利用容错语言和编写更简单的代码。

BEAM 虚拟机是如何进行容错处理?-Eswlnk Blog
虚拟机容错

区分预期和意外错误

这里最大的教训是,不要以各种可能的方式使用 Supervisors 并隐藏地毯下的错误处理代码。但是要真正考虑要编写哪些错误处理代码以及根本不编写哪些代码。为此,我们需要真正理解和区分系统中不同类型的“错误”。

简而言之,我会将“错误”分为两类:预期错误预期错误是可预测的情况,与快乐路径略有不同。当这些错误发生时,用户(或客户端代码)可以自行修复。无效的参数或输入就是最好的例子。意外错误意外错误是用户无法修复的不可预测的情况。大多数编程语言都会在出现意外错误时引发异常。当这些错误发生时,我们的代码根本无法继续运行。修复它的责任落在了开发人员或运营商身上。磁盘空间不足,网络故障就是最好的例子。

错误是一个简单的词,但有太多的含义。对于用户来说,“用户名被占用”错误与“500 内部服务器错误”页面大致相同。
当用户看到错误页面或 Flash 消息时,她不知道错误是预期的还是意外的。对于开发人员来说,一个函数调用可能会返回一个错误元组,而另一个函数可能会引发异常。但是错误元组可能是意外的,而异常可能是预期的。因此,除非我们作为开发人员在编写代码时真正考虑到这一点,否则很容易混合预期和意外错误。

Erlang 论文(在存在软件错误的情况下制作可靠的分布式系统)对“什么是错误?”这个问题给出了很好的回答。

由程序员决定异常是否对应于错误……

Schneider 在他 1990 年的 ACM 教程论文中给出了许多容错定义。
在这篇论文中,他说:
一旦组件的行为不再符合其规范,它就被认为是有缺陷的

最后,这一切都归结为规范(即预期或意外)。如果规范已经定义了在某种异常情况下的响应,那么这是一个预期的错误。如果代码发现自己处于未定义状态,那么最好尽早失败。

以下是一些示例,可帮助您在考虑错误时区分预期和意外:

  1. 除以零误差
    • 预期的时候
      当您构建计算器时,预计用户可能会输入1 / 0.
      因此在这种情况下应考虑除零误差。
      开发人员应该考虑为这些可能的输入返回什么。
    • 出乎意料的时候
      当您真正将 0 作为除数传递时,运行时不知道如何进行。行为在数学
      上是未定义的,周期。 所以提出一个例外是合理的。
  2. 文件不存在错误
    • 预期的时候
      在构建文本编辑器时,预计用户可能会打开一个不存在的文件来创建它。
      文本编辑器甚至可能不会将其视为错误,而是日常操作。
    • 出乎意料的时候
      当您的应用在启动过程中需要读取配置文件时,通常最好将丢失的配置文件视为意外错误。
      在这种情况下,一个常见的解决方案是回退到一些默认值,
      我发现它在操作级别和代码级别都太混乱了。
      缺少配置文件时很难调试,但应用程序仍然可以工作(但不同)。
      很难理解代码,因为回退可能发生在任何级别。
      所以我总是假设应用程序启动时配置文件就在那里,如果不是这样,就提出来。
      (我从Chris Keathley 那里学到了这个想法 – 使用 Stacking 构建弹性系统 – ElixirConf EU 2019 – YouTube)
BEAM 虚拟机是如何进行容错处理?-Eswlnk Blog

通过“忽略”意外错误来减少代码编写

现在我们已经区分了预期和意外错误,这将如何帮助我们编写更少的代码?

诀窍是我们现在可以一劳永逸地“忽略”意外错误。让容错运行时处理它。

首先,让我们承认,我们无法预测或处理所有意外错误。我们希望我们的节点始终在线,但最终,只需短暂断电或网络中断即可关闭我们的一个节点。我们无法在软件级别处理这种硬件错误。所以我们不会尝试处理它们,而是通过链接和主管来检测它们。

相同的逻辑适用于所有意外错误。根据规范,它们是意外的,我们不知道如何处理它们。因此,让我们停止继续并退回到更简单的任务。

更简单的任务可能是:

  • 记录意外错误
  • 从头开始重试(即在 BEAM 中重新启动进程)
  • 停止应用程序

通过断言我们的假设来编写更自信的代码

凭借“忽略”意外错误的特权,我们可以编写更少但更自信的代码。
因为我们可以围绕我们的代码建立一个围栏,一个断言外壳来检查我们的假设。

  • 如果函数只接受非空列表,则在函数头中进行模式匹配:
    def average ([ _ | _ ] = list ) do … end
  • 如果总是期望从列表中获得结果,则对其进行模式匹配并确保它不是nil:
    % SomeStruct {} =结果=枚举。查找(列表,…)
  • 如果case语句只期望一些可能的输入,则无需在最后添加始终匹配子句:
    案例文件。read ( path ) do {: ok , binary } -> … {: error , : enoent } -> {: error , : file_does_not_exist } # 其他错误是意外的,我们应该在它们出现时中止end

通过以这种风格编写代码,我们基本上是在提取函数的输入1,使其在深入到我们的核心逻辑中时变得越来越纯净。
我将这种编码风格称为Assertive Shell、Confident Core。(受Gary Bernhardt-YouTube 的 RubyConf 12-Boundaries启发)或者 Erlang 的老手可能会称之为让它失败。

而且这种编码风格也非常 MVP-ish 和可扩展的。当我们刚开始使用应用程序时,在许多情况下,规范总是含糊不清且未定义。因此,与其花太多精力去覆盖我们能想到的所有情况,我们只需确保我们始终在我们设计的快乐道路上,如果不再是这种情况,就提出一个例外。随着规范变得越来越复杂,我们的代码可以相应地增长并根据规范处理更多案例。

BEAM 虚拟机是如何进行容错处理?-Eswlnk Blog

BEAM VM 让“让它失败”的生产就绪

我们可以在任何编程语言中应用这种编码风格。那么 BEAM 的特别之处和它的容错性呢?答案是隔离。

BEAM VM 中的每个进程都是相互隔离的。因此,如果一个进程因异常而死亡,那也没关系。它的主管会将其带回干净的状态。这种机制已融入语言。

在 Ruby 等其他语言中,我不太有信心在随机函数中引发异常。恐怕这个异常会使整个应用程序崩溃。我只能依靠框架(Rails、Sidekiq 等)来捕捉这个异常并神奇地处理它。

我想这就是为什么这种编码风格毕竟不那么受欢迎的原因。BEAM VM 为我们提供了此特权。

概括

“让它失败”和容错是 BEAM 社区的陈词滥调。我对写这篇文章犹豫不决,因为我总是告诉自己这个想法已经被很好地解释了,就像 Erlang 论文(在存在软件错误的情况下制作可靠的分布式系统)所做的那样。

不过我对最后的部分感到高兴,因为我认为我们没有足够强调“让它失败”编码风格给我们带来的简单性和信心。请记住更彻底地定义您的规范,并享受对意外错误的无知!

本站默认网盘访问密码:1166
本站默认网盘访问密码:1166
beam虚拟机beam虚拟机容错Erlang容错处理容错机制
0
0
Eswlnk的头像
Eswlnk
一个有点倒霉的研究牲站长
赞赏
PostgreSQL 视图和物化视图如何工作以及它们如何影响 TimescaleDB 连续聚合
上一篇
起亚汽车创建自定义固件指南
下一篇

评论 (0)

请登录以参与评论
现在登录
    发表评论

猜你喜欢

  • 今日热点:伪Clash软件下载陷阱曝光,附防范建议
  • 「攻防对抗」利用 fastjson 原生反序列化与动态代理突破安全限制
  • 「攻防对抗」从上传漏洞到Getshell | 一次完整的渗透过程
  • 「日志记录」从零起步揭开路由器漏洞挖掘的面纱
  • 「攻防对抗」NSmartProxy流量特征的真实表现与应用
Eswlnk的头像

Eswlnk

一个有点倒霉的研究牲站长
1108
文章
319
评论
679
获赞

随便看看

「攻防对抗」绕过杀软添加用户和计划任务(360核晶模式)
2023-11-10 12:34:40
关于如何运行二进制文件而不留下痕迹的研究
2022-03-27 15:09:20
Reverse: Level2 & 动态调试修改内存 Cracked by Eswink
2021-10-29 1:39:18

文章目录

专题展示

WordPress53

工程实践37

热门标签

360 AI API CDN java linux Nginx PDF PHP python SEO Windows WordPress 云服务器 云服务器知识 代码 免费 安全 安卓 工具 开发日志 微信 微软 手机 插件 攻防 攻防对抗 教程 日志 渗透分析 源码 漏洞 电脑 破解 系统 编程 网站优化 网络 网络安全 脚本 苹果 谷歌 软件 运维 逆向
  • 首页
  • 知识库
  • 地图
Copyright © 2023-2025 Eswlnk Blog. Designed by XiaoWu.
本站CDN由 壹盾安全 提供高防CDN安全防护服务
蜀ICP备20002650号-10
页面生成用时 0.541 秒   |  SQL查询 38 次
本站勉强运行:
友情链接: Eswlnk Blog 网站渗透 倦意博客 特资啦!个人资源分享站 祭夜博客 iBAAO壹宝头条
  • WordPress142
  • 网络安全64
  • 漏洞52
  • 软件52
  • 安全48
现在登录
  • 资源
    • 精彩视频
    • 破解专区
      • WHMCS
      • WordPress主题
      • WordPress插件
    • 其他分享
    • 极惠VPS
    • PDF资源
  • 关于我
    • 论文阅读
    • 关于本站
    • 通知
    • 左邻右舍
    • 玩物志趣
    • 日志
    • 专题
  • 热议话题
    • 游戏资讯
  • 红黑
    • 渗透分析
    • 攻防对抗
    • 代码发布
  • 自主研发
    • 知识库
    • 插件
      • ToolBox
      • HotSpot AI 热点创作
    • 区块
    • 快乐屋
    • 卡密
  • 乱步
    • 文章榜单
    • 热门标签
  • 问答中心反馈