是否存在防灾语言?

Toa*_*oad 41 programming-languages language-design

在创建必须具有高可靠性的系统服务时,我经常最终编写许多"故障保护"机制,以防万一:通信已经消失(例如与数据库通信),如果电源是什么会发生什么?丢失,服务重新启动....如何拿起碎片并以正确的方式继续(并记住,当拾取碎片时,电源可能会再次出现......)等等

我可以想象,对于不太复杂的系统,一种能满足这一要求的语言非常实用.所以这种语言在任何特定时刻都会记住它的状态,无论电源是否被切断,还是在它停止的地方继续.

这还存在吗?如果是这样,我在哪里可以找到它?如果没有,为什么不能实现呢?在我看来,关键系统非常方便.

ps如果数据库连接丢失,则表示出现问题,需要手动干预.在他恢复连接的那一刻,它会在它停止的地方继续.

编辑:由于讨论似乎已经消失,让我添加几点(等待我可以添加奖金之前的问题)

Erlang的反应现在似乎是最高评价.我知道Erlang并且读过Armstrong(主要创作者)的实用书.这一切都非常好(虽然函数式语言使我的头部旋转所有的递归),但"容错"位不会自动出现.离得很远.Erlang提供了许多监督程序和其他方法来监督进程,并在必要时重新启动它.但是,要正确地制作适合这些结构的东西,你需要成为erlang大师,并且需要让你的软件适合所有这些框架.此外,如果电源掉电,程序员也必须拿起碎片并尝试在下次程序重启时恢复

我正在寻找的东西更简单:

想象一种语言(例如像PHP一样简单),您可以在这里执行诸如数据库查询,操作,执行文件操作,执行文件夹操作等操作.

然而,它的主要特征应该是:如果电源消失,并且事情重新启动它就会从它停止的地方开始(因此它不仅会记住它的位置,它还会记住变量状态).此外,如果它在文件复制过程中停止,它也将正确恢复.等等

最后但并非最不重要的是,如果数据库连接丢失且无法恢复,语言就会暂停,并发出信号(可能是系统日志)供人为干预,然后继续进行.

像这样的语言会使很多服务编程变得容易多了.

编辑:似乎(根据所有评论和答案判断)这样的系统不存在.并且可能不会在近乎可预见的将来由于它(接近?)无法做到正确.

太糟糕了....我不是在寻找这种语言(或框架)让我登上月球,或用它来监视某人的心跳.但对于小型定期服务/任务总是有大量的代码处理边框(在中间的某个地方断电,连接丢失而不是恢复),......在这里暂停,...修复问题,... ..并继续你离开的地方方法会很好.

(或作为评论者指出的检查点方法(如在视频游戏中).设置检查点....如果程序死亡,请在下次重新启动.)

Bounty奖励:在每个人都得出结论的最后一刻可能无法完成,Stephen C带有napier88,它似乎具有我正在寻找的属性.虽然它是一种实验性语言,但它确实可以证明它是可以完成的,并且它是值得研究的东西.

我将着眼于创建自己的框架(可能包含持久状态和快照),以便在.Net或其他VM中添加我正在寻找的功能.

每个人都感谢您的投入和伟大的见解.

Ira*_*ter 59

Erlang设计用于电信系统,其中高可靠性是基础.我认为他们有标准的方法来构建可以优雅处理故障的通信流程集.

ERLANG是一种并发功能语言,非常适合分布式,高度并发和容错的软件.Erlang的一个重要部分是它对故障恢复的支持.通过将ERLANG应用程序的流程组织到树结构中来提供容错.在这些结构中,父进程监视其子进程的故障并负责重新启动.

  • 在Erlang中重要的是线程可以失败的想法,并且监督线程可以听到它并采取措施重新启动监督线程应该做的工作.这是构建容错系统的关键构建块.在电源故障的情况下,监控线程当然更好地在另一台非电力故障机器中.如果你坚持对所有事情进行停电的可能性,那么某个地方就必须得救.请参阅此主题中的STM答案. (6认同)
  • Jeff和Joel与Damien Katz进行了一次有趣的谈话,关于他在构建CouchDB时使用Erlang是Stack Overflow播客#59 http://blog.stackoverflow.com/2009/06/podcast-59/ (3认同)
  • 我过去看过二郎.不管它有什么样的容错功能......它无法在断电中存活下来.当代码重新启动时,你将不得不拿起碎片 (2认同)
  • 是的,但实质上它不是防灾的.如果出现问题,你仍然需要手动编写启动它的代码,并且必须"恢复"(清理旧文件等) (2认同)

Ira*_*ter 33

软件事务存储器(STM)与非易失性RAM相结合可能会满足OP的修订问题.

STM是用于实现"事务"的技术,例如,作为原子操作有效地完成的动作集,或者根本不执行.通常,STM的目的是使高度并行的程序能够以比传统的锁定资源编程更容易理解的方式在共享资源上进行交互,并且由于具有高度乐观的无锁定风格而可以降低开销.节目.

基本思想很简单:记录"事务"块内的所有读写(以某种方式!); 如果任何两个线程在其任一事务结束时在这些集合上发生冲突(读写或写 - 写冲突),则一个被选为胜利者并继续,另一个被迫将其状态回滚到开头交易和重新执行.

如果坚持所有计算都是事务,并且每个事务的开始(/结束)的状态存储在非易失性RAM(NVRAM)中,则可以将电源故障视为事务故障,从而导致"回滚".计算只能以可靠的方式从交易状态进行.这些天的NVRAM可以用闪存或电池备份来实现.人们可能需要很多NVRAM,因为程序有很多状态(最后看小型机的故事).或者,可以将已提交的状态更改写入写入磁盘的日志文件; 这是大多数数据库和可靠文件系统使用的标准方法.

STM目前的问题是,跟踪潜在的交易冲突有多昂贵?如果实施STM会使机器速度下降很多,那么人们将会接受现有的略微不可靠的方案而不是放弃这种性能.到目前为止,故事并不好,但研究还很早.

人们通常没有为STM设计语言; 出于研究目的,他们主要通过STM增强Java(参见今年6月的ACM通讯文章).我听说MS有一个C#的实验版本.英特尔有一个C和C++的实验版本.维基百科页面有很长的列表.像往常一样,功能编程人员声称功能程序的无副作用属性使STM在函数式语言中实现起来相对微不足道.

如果我没记错的话,早在70年代,在分布式操作系统中就有相当多的早期工作,其中进程(代码+状态)可以在机器之间轻松地进行.我相信几个这样的系统明确地允许节点故障,并且可以从另一个节点中的保存状态重启故障节点中的进程.早期的关键工作是Dave Farber 的 分布式计算系统.因为在70年代设计语言很受欢迎,我记得DCS有它自己的编程语言,但我不记得名字.如果DCS不允许节点故障并重新启动,我相当确定研究系统的后续工作.

编辑:这乍一看似乎有你的愿望是记录在属性的系统,1996年在这里.它的原子事务概念与STM背后的思想是一致的.(去证明太阳下没有太多新东西).

旁注:回到70年代,核心记忆仍然是王道.核心是磁性的,在电源故障时是非易失性的,许多小型计算机(我相信大型机)都有电源故障中断,在电源断电前几毫秒通知软件.使用它,可以轻松存储机器的寄存器状态并完全关闭.当电源恢复时,控制将返回状态恢复点,软件可以继续.因此,许多程序可以在电源闪烁和可靠重启后继续存在.我亲自在Data General Nova小型机上建立了分时系统; 你实际上可以让它运行16个远程类型的全面爆炸,接通电源,并重新启动并重新启动所有的电传类型,好像什么都没发生一样.从嘈杂到沉默和背部的变化令人惊叹,我知道,我不得不多次重复调试电源故障管理代码,它当然做了很棒的演示(插上插头,扼杀沉默,插回...... ).这样做的语言的名称当然是汇编程序: - }

  • 对于C#,这可能有助于http://stackoverflow.com/questions/329067/checkpointing-library-for-c/330243虽然你经常检查点并使应用程序研磨 (2认同)

Chr*_*s S 13

据我所知¹,Ada经常用于安全关键(故障安全)系统.

Ada最初的目标是嵌入式和实时系统.

Ada的显着特性包括:强类型,模块化机制(包),运行时检查,并行处理(任务),异常处理和泛型.Ada 95增加了对面向对象编程的支持,包括动态调度.

Ada支持运行时检查,以防止访问未分配的内存,缓冲区溢出错误,逐个错误,阵列访问错误和其他可检测的错误.为了提高运行效率,可以禁用这些检查,但通常可以有效地进行编译.它还包括帮助程序验证的设施.

由于这些原因,Ada广泛用于关键系统,任何异常都可能导致非常严重的后果,即意外死亡或受伤.使用Ada的系统的示例包括航空电子设备,武器系统(包括热核武器)和航天器.

N版编程也可以为您提供一些有用的背景阅读.

¹ 基本上是一位熟悉编写嵌入式安全关键软件的人

  • 阿丽亚娜5灾难是由于愚蠢的项目管理.他们认为某些代码在Ariane 4(初始加速度低得多)上工作得很好,因此在使用Ariane 5之前他们甚至都不会看它.没有语言可以免受规格的影响,因此输入更改在它下面. (3认同)
  • Ada*用于关键系统*,但主要是因为额外的检查有助于确保程序员不会编写愚蠢的东西.Ada作为一种语言不提供*我知道的任何*设施,允许Ada线程以安全的方式死亡和恢复. (2认同)

Gre*_*zky 13

我怀疑你所描述的语言特征是否有可能实现.

其原因在于,定义常见和一般故障模式以及如何从中恢复将非常困难.考虑一下您的示例应用程序 - 一些具有一些逻辑和数据库访问权限的网站.并且假设我们有一种语言可以检测电源关闭和后续重启,并以某种方式从中恢复.问题是,不可能知道语言如何恢复.

假设您的应用是在线博客应用.在那种情况下,从我们失败的那一点开始就足够了,一切都好.但是,请考虑网上银行的类似情况.突然间,从同一点继续下去已经不再聪明了.例如,如果我试图从我的帐户中提取一些钱,并且计算机在检查之后但在执行提款之前就已经死了,然后它会在一周之后返回,即使我的帐户在现在消极.

换句话说,没有一个正确的恢复策略,因此这不是可以在语言中实现的东西.什么语言可以告诉你什么时候发生了不好的事情 - 但大多数语言已经支持异常处理机制.其余的由应用程序设计人员来考虑.

有许多技术可以设计容错应用程序.数据库事务,持久消息队列,群集,硬件热交换等等.但这一切都取决于具体要求以及最终用户愿意支付多少费用.


Ste*_*n C 11

有一种称为Napier88的实验性语言(理论上)具有防灾的一些属性.该语言支持正交持久性,并且在一些实现中,这扩展(扩展)以包括整个计算的状态.具体来说,当Napier88运行时系统将正在运行的应用程序检查指向持久性存储时,当前线程状态将包含在检查点中.如果应用程序随后崩溃并以正确的方式重新启动它,则可以从检查点恢复计算.

不幸的是,在这种技术准备好主流使用之前,需要解决许多难题.这些包括确定如何在正交持久性的上下文中支持多线程,确定如何允许多个进程共享持久存储,以及持久存储的可伸缩垃圾收集.

并且存在在主流语言中进行正交持久性的问题.已经尝试过用Java做OP,包括由Sun(Pjama项目)相关人员完成的,但目前没有任何活跃的.如今,JDO/Hibernate方法更受青睐.


我应该指出,正交持久性在很大程度上并不是真正的防灾.例如,它无法处理:

  • 重新启动后,使用"外部"系统重新建立连接等
  • 应用程序错误导致持久数据损坏,或
  • 由于检查点之间的系统崩溃导致的数据丢失.

对于那些人,我不相信有一些实用的通用解决方案.

  • @Ira:该语言指定任何可从持久根可访问的对象都是持久的.检查点(持久性存储提交)自动发生,或者应用程序可以请求它们.我们不是在谈论检查指向虚拟内存.相反,它是一个进程(如GC),其中遍历对象树并且(仅)将脏的可到达对象写入存储.实现可重新启动性,确保线程/堆栈状态是可以到达的. (2认同)

Wil*_*ill 10

大多数此类努力 - 称为" 容错 " - 都围绕着硬件,而不是软件.

最典型的例子是Tandem,其"不间断"机器具有完全冗余.

在硬件级别实现容错是有吸引力的,因为软件堆栈通常由来自不同提供商的组件制成 - 您的高可用性软件应用程序可能会安装在操作系统之上的一些非常不稳定的其他应用程序和服务上.使用明显易碎的硬件设备驱动程序..

但在语言层面,几乎所有语言都提供了正确错误检查的功能.但是,即使使用RAII,异常,约束和事务,这些代码路径也很少被正确测试,很少在多故障场景中一起测试,并且通常在错误处理代码中隐藏错误.所以更多的是程序员的理解,纪律和权衡,而不是语言本身.

这使我们回到硬件级别的容错.如果可以避免数据库链接失败,则可以避免在应用程序中执行狡猾的错误处理代码.


Cyn*_*hia 10

,不存在防灾语言.

编辑:

防灾意味着完美.它提醒了一个过程的图像,该过程应用一些智能以逻辑方式解决未知,未指定和意外的情况.编程语言无法通过这种方式实现此目的.如果你作为程序员,无法弄清楚你的程序将如何失败以及如何从中恢复,那么你的程序也无法做到.

从IT角度来看,灾难可能以如此多的方式出现,以至于任何一个流程都无法解决所有这些不同的问题.您可以设计一种语言来解决出现问题的所有方法的想法是错误的.由于硬件的抽象,使用编程语言解决许多问题甚至没有多大意义; 但它们仍然是"灾难".

当然,一旦你开始限制问题的范围; 那么我们就可以开始讨论为它开发解决方案了.因此,当我们停止谈论防灾并开始谈论从意外的电涌中恢复时,开发一种编程语言以解决这个问题变得更加容易,即使在处理该问题时也许没有多大意义.如此高水平的堆栈.但是,我会冒险预测,一旦你将其范围缩小到实际的实现,它就会变得无趣,因为它变得非常具体.即使用我的脚本语言在一夜之间运行批处理过程,这些过程将从意外的电涌和网络连接丢失中恢复(有一些人工协助); 这对我来说并不是一个引人注目的商业案例.

请不要误解我.在这个帖子中有一些很好的建议,但在我看来,他们甚至没有任何东西,甚至远程接近防灾.

  • 当您缩小范围足以使其工作时,您将不再具有可推广的解决方案.(它不会是一种语言.)您只需为您的应用程序设计一个精心设计的程序.充其量,您将拥有一个很好的工具,许多程序员可以使用它来执行常见但必要的任务.那不错; 但它也不是一种防灾语言. (6认同)
  • 我不是在开玩笑; 这不合理.寻找促进可恢复性和可靠性的语言是一回事.(参见Erlang的答案)但是找到一种能为你做的语言完全是另一回事.生活对于像这样的事情来说太复杂了.什么适合医疗成像设备和空中交通塔和亚马逊的数据库都完全不同.失败模式和恢复方式各不相同; 所以没有一种语言可以做到这一切.即使在简单的程序中,错误处理例程也很复杂. (4认同)