有防灾语言吗?
当创build必须具有高可靠性的系统服务时,我经常会写下很多“故障安全”机制,例如:通讯已经消失(例如与数据库通讯),如果电源是失去了,服务重新启动….如何拿起件,并继续以正确的方式(并记住,在拿起件时,权力可以再出…)等等
我可以想象,对于不太复杂的系统来说,能够满足这个要求的语言将是非常实用的。 因此,无论权力何时被切断,在任何特定时刻都会记住它的状态,并继续停止。
这是否存在? 如果是的话,我在哪里可以find它? 如果没有,为什么不能实现呢? 在我看来,对于关键系统来说非常方便。
ps数据库连接丢失时,表示出现问题,需要手动干预。 在连接恢复的那一刻,它将继续停止。
编辑:由于讨论似乎已经死了,让我补充几点(在等待之前,我可以添加一个赏金的问题)
Erlang的回应似乎是目前最高的评价。 我知道Erlang,并阅读过Armstrong(主要创作者)的实用书。 这一切都非常好(尽pipe函数式语言让我的头脑旋转了所有的recursion),但是“容错”位并不会自动产生。 离得很远。 Erlang提供了许多监督人员监督stream程的其他方法,并在必要时重新启动。 然而,为了正确地做出与这些结构一起工作的东西,你需要成为erlang大师,并且需要使你的软件适合所有这些框架。 另外,如果功耗下降,程序员也必须拿起这些部件,并在下一次程序重新启动时尝试恢复
我正在寻找的是更简单的事情:
想象一下,一种语言(就像PHP一样简单),你可以做类似于数据库查询,操作,执行文件操作,执行文件夹操作等的语言。
它的主要特点应该是:如果电源死了,重新启动,它会停止它的位置(所以它不仅会记住它在哪里,还会记住variables状态)。 另外,如果它在文件拷贝中间停止,它也将正确恢复。 等等
最后但并非最不重要的是,如果数据库连接断开并且无法恢复,语言只是暂停,并且发送信号(可能是syslog)供人工干预,然后继续进行。
像这样的语言会使很多服务编程变得更容易。
编辑:它似乎(所有评论和答案来看),这样一个系统不存在。 可能在近乎可预见的将来,由于(近?)不可能得到正确的。
太糟糕了….我再也不是在寻找这种语言(或框架)让我登上月球,或者用它来监视某人的心脏。 但是,对于小型的周期性服务/任务,这些服务/任务总是会导致大量的代码处理边界案例(电力中断,连接丢失,不能恢复),…在这里暂停,…解决问题。 ..并继续你离开的方法将工作良好。
(或作为评论者之一指出的检查点方法(如在video游戏中)。设置检查点….如果程序死亡,下次重新启动。
赏金奖励:在最后一刻,每个人都得出结论,这是不可能完成的,Stephen C带着napier88,这似乎有我正在寻找的属性。 虽然它是一种实验性的语言,但它确实certificate它是可以做到的,这是值得深入研究的东西。
我将研究创build我自己的框架(可能具有持久状态和快照)来添加我在.Net或其他虚拟机中寻找的function。
每个人都感谢您的意见和伟大的见解。
有一种名叫Napier88的实验性语言(理论上)有一些属于防灾的属性。 该语言支持正交持久性(Orthogonal Persistence),并且在一些实现中,这延伸(扩展)为包括整个计算的状态。 具体来说,当Napier88运行时系统检查指向正在运行的应用程序到持久性存储区时,当前线程状态将包含在检查点中。 如果应用程序然后崩溃,并以正确的方式重新启动它,则可以从检查点恢复计算。
不幸的是,在这种技术准备好用于主stream应用之前,还有一些难题需要解决。 这些包括了解如何在正交持久化的情况下支持multithreading,弄清楚如何允许多个进程共享一个持久存储,以及持久存储的可伸缩垃圾回收。
在主stream语言中存在正交持久性的问题。 在Java中已经尝试过使用OP,其中一个是由与Sun(Pjama项目)相关联的人员完成的,但目前没有任何活动。 JDO / Hibernate方法现在更受青睐。
我应该指出,正交持久在大的意义上并不是真正的防灾。 例如,它不能处理:
- 重新启动后,与“外部”系统重新build立连接等,
- 应用程序错误,导致腐败的持续数据,或
- 由于某些事情造成检查点之间的系统丢失,导致数据丢失。
对于那些,我不相信有一般的解决scheme是可行的。
Erlang被devise用于电信系统,其中高可靠性是基础。 我认为他们有一套标准的方法来build立一系列沟通过程,在这些过程中可以优雅地处理失败。
ERLANG是一种并发function语言,非常适合分布式,高度并发和容错软件。 Erlang的一个重要组成部分是支持故障恢复。 通过将ERLANG应用程序的进程组织到树结构中来提供容错function。 在这些结构中,父进程监视其subprocess的失败并负责重启。
软件事务内存(STM)与非易失性RAM结合可能会满足OP的修订问题。
STM是一种实现“交易”的技术,例如,作为primefaces操作有效完成的一组操作,或者根本不实行。 通常,STM的目的是使高度并行的程序能够以比传统的locking资源编程更容易理解的方式在共享资源上进行交互,并且由于具有非常乐观的无locking风格节目。
基本思想很简单:在“交易”块内的所有读写都被logging下来(某种程度上! 如果任何两个线程在这些集合上发生冲突(读写或写 – 写冲突),则在其中一个事务结束时select一个作为获胜者并继续进行,另一个线程被迫将其状态回滚到开始的交易并重新执行。
如果坚持所有计算都是交易,并且每笔交易开始(/结尾)的状态都存储在非易失性RAM(NVRAM)中,则电源故障可能被视为导致“回滚”的交易失败。 计算将仅以可靠的方式从成交的国家进行。 NVRAM这些天可以用闪存或电池备份来实现。 人们可能需要大量的NVRAM,因为程序有很多状态(见最后的小型机故事)。 或者,可以将已提交的状态更改写入写入磁盘的日志文件; 这是大多数数据库和可靠文件系统使用的标准方法。
STM现在的问题是,跟踪潜在的交易冲突有多昂贵? 如果执行STM会使机器的运行速度降低很多,那么人们就会接受现有的稍微不可靠的scheme,而不是放弃这种性能。 到目前为止,这个故事并不好,但是研究还是比较早的。
人们通常没有为STMdevise语言; 出于研究的目的,他们大多用STM来增强Java(参见今年6月份的ACM文章通讯)。 我听说MS有一个C#的实验版本。 英特尔拥有C和C ++的实验版本。 维基百科页面有一个很长的列表。 和往常一样,函数式编程人员声称function程序的副作用自由属性使得STM在函数式语言中实现起来相对简单。
如果我没有记错的话,早在七十年代,在分布式操作系统中有相当多的早期工作,其中进程(代码+状态)可以在机器之间轻微移动。 我相信有几个这样的系统明确允许节点故障,并且可以从另一节点中的保存状态重新启动发生故障的节点中的进程。 Dave Farber在早期的关键工作是分布式计算系统 。 由于70年代的devise语言很stream行,我记得DCS有它自己的编程语言,但我不记得名字。 如果DCS不允许节点故障并重新启动,我相当肯定研究系统的跟踪。
编辑:一个1996年出现乍一看有你想要的属性的系统logging在这里 。 其primefaces交易的概念与STM背后的思想是一致的。 (去certificate太阳下没有太多新东西)。
一个侧面说明:在70年代,核心内存仍然是国王。 核心是磁性的,在整个电源故障期间是非易失性的,许多小型计算机(并且我确信大型机)具有断电中断,在断电之前几毫秒通知软件。 使用它,可以轻松存储机器的注册状态并完全closures。 当电源恢复时,控制将返回到状态恢复点,并且软件可以继续。 许多程序因此可以在闪烁和可靠重启之后幸存下来。 我亲自在Data General Nova小型机上build立了分时系统; 你实际上可以让它运行16次,完全爆炸,然后重新开始,重新开始所有的teletypes,就好像什么都没发生一样。 从杂音到沉默和背部的变化是惊人的,我知道,我不得不多次重复它来debugging电源故障pipe理代码,它当然做了很好的演示(猛拔插头,死寂沉寂,插回.. )。 这样做的语言的名称,当然是汇编: – }
从我所知道的¹, Ada经常被用在安全关键(故障安全)系统中。
Ada最初是针对embedded式和实时系统的。
Ada的显着特点包括:强打字,模块化机制(包),运行时检查,并行处理(任务),exception处理和generics。 Ada 95增加了对面向对象编程的支持,包括dynamic调度。
Ada支持运行时检查,以防止访问未分配的内存,缓冲区溢出错误,逐个错误,数组访问错误和其他可检测到的错误。 为了提高运行效率,可以禁用这些检查,但通常可以高效地进行编译。 它还包括帮助程序validation的工具。
由于这些原因,Ada广泛应用于关键系统,任何exception都可能导致非常严重的后果,即意外死亡或受伤。 使用Ada的系统的例子包括航空电子设备,武器系统(包括热核武器)和航天器。
N版编程也可能会给你一些有用的背景阅读。
¹ 这基本上是一个熟悉embedded式安全关键软件的人
我怀疑你描述的语言特征是否可以实现。
其原因是定义常见的一般故障模式以及如何从中恢复是非常困难的。 想一想你的示例应用程序 – 一些网站有一些逻辑和数据库访问。 让我们说,我们有一种语言,可以检测电源closures和后续重新启动,并以某种方式恢复。 问题是,不可能知道语言如何恢复。
假设您的应用程序是一个在线博客应用程序。 在这种情况下,从我们失败的地步继续下去,一切都可以。 不过考虑一个网上银行的类似情况。 突然之间,从同一点继续下去已经不再聪明了。 例如,如果我试图从我的帐户中提取一些钱,并且电脑在检查之后但是在执行提款之前就死了,然后在一个星期之后退还,即使我的账户在现在消极。
换句话说,没有单一的正确的恢复策略,所以这不是可以实现的语言。 什么语言可以做的就是告诉你什么时候发生了什么坏事,但是大多数语言已经支持exception处理机制。 其余的由应用程序devise师来考虑。
有许多技术允许devise容错应用程序。 数据库事务,持久消息队列,集群,硬件热插拔等等。 但这一切都取决于具体的要求和最终用户愿意为此付出多less。
大多数这样的努力 – 被称为“ 容错 ” – 都是围绕硬件而不是软件。
这个最好的例子是Tandem ,他的“不间断的”机器有完全的冗余。
在硬件层面上实现容错function是有吸引力的,因为软件堆栈通常是由来自不同提供者的组件提供的 – 您的高可用性软件应用程序可能安装在一些明显不稳定的其他应用程序和服务上,使用硬件设备驱动程序,这是决定脆弱..
但是在语言层面上,几乎所有的语言都提供了正确的错误检查function。 但是,即使使用RAII,exception,约束和事务,这些代码path也很less被正确testing,很less在多故障scenerios中一起testing,而且通常在错误隐藏的error handling代码中。 所以它更多的是程序员的理解,纪律和权衡,而不是语言本身。
这使我们回到硬件级别的容错。 如果您可以避免数据库链接失败,则可以避免在应用程序中执行不好的error handling代码。
不 ,防灾语言不存在。
编辑:
防灾意味着完美。 它让人想起一个过程的图像,它运用了一些智能来以合乎逻辑的方式解决未知的,未指定的和意料之外的情况。 编程语言没有办法做到这一点。 如果作为程序员,你无法弄清楚你的程序将如何失败以及如何从中恢复,那么你的程序也无法做到这一点。
从IT的angular度来看,灾难会以这么多的方式出现,任何一个进程都无法解决所有这些不同的问题。 你可以devise一种语言来解决所有可能发生错误的方法的想法是错误的。 由于硬件的抽象,许多问题甚至没有用编程语言来解决。 但他们仍然是“灾难”。
当然,一旦你开始限制问题的范围, 那么我们可以开始谈论开发一个解决scheme。 所以,当我们停止谈论防灾,并开始谈论从意外的电源浪涌中恢复的时候,开发一种编程语言来解决这个问题变得更容易,即使可能在处理这个问题时没有多大意义如此高水平的堆栈。 然而,我会冒险一个预测,一旦你把这个缩小到现实的实现,它变得没有兴趣作为一种语言,因为它已经变得如此具体。 即使用我的脚本语言在一夜之间运行批处理过程,从意外的电源浪涌和丢失的networking连接中恢复过来(在某些人工协助下); 在我看来,这不是一个令人信服的商业案例。
请不要误解我。 在这个主题中有一些很好的build议,但是在我看来,他们甚至没有任何东西可以远程接近防灾。
考虑一个由非易失性存储器构build的系统。 程序状态始终保持不变,如果处理器停止了一段时间,它将在重新启动时的剩余点恢复。 因此,您的程序在电源故障后仍能保持“防灾”状态。
这是完全可能的,正如其他职位在谈到软件事务内存时所概述的那样,以及“容错性”等等。好奇的没有人提到“忆阻器”,因为它们将提供具有这些属性的未来架构,而且可能不完全是冯诺依曼架构也。
现在设想一个由两个这样的分立系统构build的系统 – 为了直观的说明,一个是数据库服务器,另一个是在线银行网站的应用服务器。
如果一个人停下来,另一个人做什么? 它如何处理它的同事突然无法使用?
它可以在语言层面进行处理,但是这意味着很多error handling等等,而这正是棘手的代码。 这几乎没有我们今天所在的地方好,机器不是检查尖端,但语言试图检测问题,并要求程序员处理它们。
它也可以暂停 – 在硬件层面上,它们可以被捆绑在一起,从功率的angular度来看,它们是一个系统。 但是这不是一个好主意。 更好的可用性来自具有备份系统等的容错架构。
或者我们可以在两台机器之间使用持久的消息队列。 但是,在某些时候,这些信息会被处理,而且他们可能在那个时候太老了! 在这种情况下,只有应用程序逻辑才能真正做到做什么,在那里我们又回到了编程人员的语言。
所以目前的防灾措施看起来比较好 – 不间断电源,准备就绪的热备份服务器,主机之间的多路networking路由等。然后我们只希望我们的软件没有缺陷!
精确的答案:
Ada和SPARK被devise用于最大限度的容错能力,并将所有的错误转移到编译时而不是运行时。 Ada由美国国防部devise,用于军事和航空系统,运行在诸如飞机之类的embedded式设备上。 火花是它的后裔。 在美国早期的太空计划中还有另一种语言,HAL / S面向处理由于宇宙射线造成的硬件故障和内存损坏。
实际答案:
我从来没有见过任何可以编码Ada / Spark的人。 对于大多数用户来说,最好的答案就是具有自动故障转移和服务器集群的DBMS上的SQL变体。 诚信检查保证安全。 像T-SQL或PL / SQL这样的事物具有完整的事务安全性,是图灵完备的,并且相当宽容。
原因没有一个更好的答案:
出于性能原因,您无法为每个程序操作提供耐久性。 如果你这样做了,处理速度将会降到最快的非易失性存储器的速度。 充其量,你的性能会下降一千或一百万倍,因为任何东西都比CPUcaching或RAM慢了很多。
这相当于从Core 2 Duo CPU到古老的8086 CPU – 最多可以每秒执行几百次操作。 除此之外,这将是甚至更低。
在出现频繁的电源循环或硬件故障的情况下,您可以使用类似DBMS的内容,这可以保证每个重要操作的ACID。 或者,您使用具有快速,非易失性存储(例如,闪存)的硬件 – 这仍然非常慢,但是如果处理非常简单,那么就可以。
充其量,你的语言给你编译时安全检查错误,并会抛出exception而不是崩溃。 exception处理是现在使用的一半语言的一个特征。
这个问题迫使我发表这个文本
(它从Douglas Adams的HGTTG引用:)
点击,哼。
巨大的灰色Grebulon侦察船静静地穿过黑色的空洞。 它以惊人的惊人的速度旅行,然而在十亿个遥远的恒星的微光背景下,却一点也没有出现。 这只是一个黑暗的星球冻结在一个无限精彩的夜晚的粒度。
在船上,一切都像过去几千年一样,深沉而沉寂。
点击,哼。
至less,几乎所有的东西。
点击,点击,哼。
点击,哼哼,点击,哼哼,点击,哼哼。
点击,点击,点击,点击,点击,哼哼。
嗯。
一个低级别的监督程序在船的半昏迷的networking中深深地唤醒了一个稍高一级的监督程序,并报告说,每当它发出咔嚓声时,所有的声音都是嗡嗡声。
上级监督scheme问它应该得到什么,低级监督程序说不能准确记住,但认为它可能更像是一种遥远的满意的叹息,不是吗? 它不知道这是什么嗡嗡声。 点击,哼哼,点击,哼。 这就是它所得到的。
上级监督scheme考虑到这一点,不喜欢它。 它询问低级别的监督程序究竟是在监督什么,而低级别的监督程序也说不记得那也只是为了咔嚓一声,每十年左右叹息一次,失败。 它曾试图查阅错误的查询表,但找不到它,这就是为什么它已经提醒上级监督scheme解决这个问题。
上级监督程序去查阅自己的查询表,找出低级监督程序要监督的内容。
它找不到查找表。
奇。
它再次看。 它得到的只是一个错误消息。 它试图在错误信息查找表中查找错误信息,但是找不到。 它经历了所有这一切,并允许几十纳秒。 然后,它起床了它的部门职能主pipe。
部门职能主pipe立即遇到问题。 它叫它的监督代理也碰到问题。 在第二个虚拟电路的百万分之几之内,这个虚拟电路几个世纪以来一直沉睡在整个船上。 在某个地方,某个地方出现了很大的错误,但是没有一个监督scheme能够说明这是什么。 在每一个层面上,重要的指示都失踪了,发现重要指示失踪的指示也没有了。
软件的小模块 – 代理 – 通过逻辑path,分组,咨询,重新分组而激增。 他们很快就确定了船的记忆,一直回到它的中心任务模块,却一帆风顺。 没有多less讯问可以确定发生了什么事情。 即使是中央任务模块本身似乎也被损坏了。
这使得整个问题很容易处理。 更换中央任务模块。 还有一个,一个备份,一个原件的确切副本。 它必须在物理上被replace,因为出于安全的原因,原始和备份之间没有任何联系。 一旦中央任务模块被更换,它本身就可以监督系统其他部分的重build,一切都会好起来的。
指示机器人将备用中央任务模块从他们保护的屏蔽坚固房间带到船上的逻辑室进行安装。
这涉及冗长的紧急代码和协议的交换,因为机器人询问代理关于指令的真实性。 最后机器人确信所有的程序都是正确的。 他们将备用中央任务模块从其存储箱中取出,从储存室中取出,从船上掉下来,进入空舱。
这提供了第一个重要的线索,说明这是错的。
进一步调查迅速确定了发生的事情。 一颗陨石在船上撞了一个大洞。 这艘船以前没有发现过这个,因为陨石已经整齐地将那艘船的加工设备的一部分弄碎了,而这部分加工设备本来是要检测这艘船是否被陨石击中。
要做的第一件事就是试图封锁这个洞。 事实certificate,这是不可能的,因为船上的传感器看不到有一个洞,而主pipe应该说传感器工作不正常,一直说传感器没有问题。 这艘船只能从机器人已经明显地掉出来的事实中推断出这个洞的存在,把它的大脑拿出来,这可以让它看到这个洞。
船试图聪明地思考这个,失败了,然后完全消失了一下。 当然,它没有意识到它已经消失,因为它已经消失了。 只是看到星星跳跃而感到惊讶。 第三次星星跳船后,终于意识到它一定是空白的,现在是时候作出一些严肃的决定了。
它放松。
然后,它意识到它实际上还没有做出严肃的决定,并感到恐慌。 它再次消失了一点。 当它再次醒来的时候,它将所有的舱壁密封在知道这个看不见的洞的地方。
它显然还没有到达目的地,它的思想是恰当的,但是由于它的目的地或者目的地已经不存在,所以似乎没有什么意义。 它咨询了它可以从中央任务模块的碎片中重build的小小的指令。
“你的!!!!! !!!!! !!!!!一年的任务是!!!!! !!!!! !!!!! !!!!! !!! !! !!!!! !!!!!,土地!!!!! !!!!! !!!!!安全距离!!!!! !!!!! ….. ….. ….. …..陆地….. ….. …..监视它!!!!! !!!!! !!!!! …“
其余的都是完整的垃圾。
在船舶完好无损之前,船舶必须将这些指令传递给更加原始的辅助系统。
它还必须重振所有的船员。
还有另一个问题。 当船员们处于冬眠状态时,所有船员的头脑,记忆,身份和对他们所做的事情的理解都已被转移到船的中央任务模块中,以保证安全。 机组人员不会有最清楚的想法,他们是谁或他们在那里做什么。 好吧。
就在它最后一次消失之前,这艘船意识到它的引擎也开始放弃了。
该船及其复员和困惑的船员在其附属的自动系统的控制下进行了巡航,只要他们能够发现陆地和监视任何他们可以发现的任何地方,它们就会着陆。
尝试采取现有的开源解释型语言,看看你是否可以调整其实施,以包括其中的一些function。 Python的默认C实现embedded了一个内部锁(称为GIL,全局解释器锁),用于通过轮stream每个'n'VM指令来“处理”Python线程中的并发。 也许你可以挂钩到这个机制来检查代码的状态。
如果程序在机器断电的情况下继续执行,不仅需要将状态保存到某个地方 ,还需要“知道”才能恢复。
我认为在一种语言中实现一个“hibernate”function是可以做到的,但是在后台不断发生这种情况,所以如果发生什么不好的事情发生,就像操作系统的工作一样。
但是,它的主要特点是:如果电源死了,重新启动,它将停留在哪里(所以它不仅会记住它在哪里,还会记住variables状态)。 另外,如果它在文件拷贝中间停止,它也将正确恢复。 等等
……
我曾经看过二郎。 不错,它的容错特性是…它不能在一个powercut下幸存下来。 当代码重新启动时,你将不得不拿起件
如果这样的技术存在,我会非常有兴趣阅读。 也就是说,Erlang解决scheme将会有多个节点 – 理想情况下位于不同的位置 – 这样,如果一个位置发生故障,其他节点可能会收到松弛。 如果你所有的节点都在同一个位置,并且在同一个电源上(对于分布式系统来说不是一个好主意),那么你会像在评论后续提到的那样运气不好。
微软机器人小组已经推出了一系列似乎适用于您的问题的库。
什么是并发和协调运行时(CCR)?
并发和协调运行时(CCR)提供了一个基于消息传递的高度并发编程模型,它使用了强大的编排原语,可以在不使用手动线程,锁,信号等的情况下协调数据和工作.CCR满足了多核通过提供一种编程模型来提供并发应用程序,以方便pipe理asynchronous操作,处理并发性,利用并行硬件和处理部分故障。
什么是分散式软件服务(DSS)?
分散式软件服务(DSS)提供了一个轻量级的,面向状态的服务模型,它将代表性状态转移(REST)与forms化的组合和事件通知架构相结合,从而实现了构build应用程序的系统级方法。 在DSS中,服务作为可以通过编程和UI操作访问的资源公开。 通过将服务组合,结构化状态操作和事件通知与数据隔离集成在一起,DSS为编写在单个节点或整个networking上运行的高度可观察,松散耦合的应用程序提供了统一的模型。
大多数答案是通用语言。 您可能需要查看embedded式设备中使用的更专用的语言。 机器人是一个很好的例子。 当电源故障恢复时,您希望和/或希望机器人执行什么操作?
在embedded式领域,可以通过看门狗中断和电池供电的RAM来实现。 我写了这样的自己。
根据你对灾难的定义,它可以从“困难”到“实际上不可能”,把责任委托给语言。
给出的其他例子包括在执行每个语句之后,将应用程序的当前状态保持到NVRAM。 这只有在电脑不被破坏的情况下才有效。
如何知道在新主机上重新启动应用程序的语言级别function?
而在将申请恢复到东道国的情况下 – 如果已经过了很长一段时间,以前做出的假设/检查现在是无效的呢?
T-SQL,PL / SQL和其他交易语言可能就像“防灾”一样紧密 – 它们要么成功(而要保存数据),要么就没有。 排除禁用事务隔离,很难(但可能不是不可能,如果你真的努力)进入“未知”状态。
您可以使用像SQL Mirroring这样的技术来确保在事务提交之前写入至less保存在两个位置。
您仍然需要确保每次安全时保存状态(提交)。
如果我正确理解你的问题,我认为你是问是否有可能保证一个特定的algorithm(即一个程序加上环境提供的任何恢复选项)将完成(任意数量的恢复/重新启动后)。
如果这是正确的,那么我会提到你停止问题 :
给定一个程序和一个有限的input的描述,决定程序是否结束运行或将永远运行,给定的input。
我认为把你的问题归类为停止问题的一个例子是公平的,因为你理想的情况是希望语言是“防灾”的 – 就是对任何有缺陷的项目或混乱的环境赋予“完美”。
该分类将环境,语言和程序的任何组合缩减为“程序和有限input”。
如果你同意我的观点,那么你会失望地看到,停止的问题是不可判定的。 因此,没有“防灾”的语言或编译器或环境可以被certificate是如此。
但是,devise一种为各种常见问题提供恢复选项的语言是完全合理的。
在电力故障的情况下,听起来像我:“当你唯一的工具是锤子,每一个问题看起来像一个钉子”
您不能解决程序中的电源故障问题。 您可以使用备用电源,电池等来解决这个问题
有几个商业可用的框架Veritas,Sun的HA,IBM的HACMP等,它们将自动监视进程,并在发生故障时在另一台服务器上启动它们。
还有一些昂贵的硬件,如HP的Tandem Nonstop系列可以承受内部硬件故障。
然而,软件是由人民和人民build立的爱错误。 考虑IBM MVS附带的IEFBR14程序的警示性内容。 它基本上是一个NOP的虚拟程序,它允许JCL的声明位发生,而不真正运行一个程序。 这是整个原始的源代码:
IEFBR14 START BR 14 Return addr in R14 -- branch at it END
没有代码更简单? 在其漫长的生活中,这个程序实际上已经完成了一个bug报告,现在已经在版本4上。
那就是1行到3行的代码,目前的版本是原来的四倍大小。
错误会一直蔓延,只要确保可以从中恢复。
如果故障模式仅限于硬件故障,那么VMware Fault Tolerance会声称您需要类似的事情。 它在多个集群上运行一对虚拟机,并使用他们称之为vLockstep的主虚拟机实时发送所有状态到次虚拟机,所以在发生主要故障的情况下,执行会透明地跳转到辅助虚拟机。
我的猜测是,这不会造成通信故障,这比硬件故障更为常见。 对于严重的高可用性,您应该考虑分布式系统,比如Birman的进程组方法( PDF格式的文章或Reliable Distributed Systems:技术,Web服务和应用程序 )。
最接近的似乎是SQL。 这不是一个真正的语言问题, 这主要是虚拟机的问题。 我可以想象一个具有这些属性的Java VM; 执行它将是另一回事。
快速和肮脏的近似是通过应用程序检查点来实现的。 你失去了“随时死亡”的财产,但是非常接近。
我认为它的恢复不是一个突出的devise问题的一个基本的错误。 将环境责任排斥到环境之外导致了对内部缺陷的普遍脆弱的解决scheme。
如果是我,我会投资可靠的硬件,并devise软件,使其能够从任何可能的情况自动恢复。 根据您的示例数据库会话维护应由一个足够高级别的API自动处理。 如果您必须手动重新连接,则可能使用了错误的API。
正如其他人所指出的那样,在现代RDBMS系统中embedded的过程语言是最好的,而不需要使用外来语言。
一般来说,虚拟机是为这种事情devise的。 您可以使用VM供应商(vmware.et al)API来适当地控制应用程序中的定期检查点。
特别是VMWare具有重放function(增强型执行logging),可logging一切,并允许时间点播放。 很明显,这种方法有着巨大的性能,但它能满足要求。 我只是确保你的磁盘驱动器有一个电池支持写入caching。
你很可能能够findjava虚拟机中运行的java字节码的类似解决scheme。 Google容错JVM和虚拟机检查点。
如果你想保存程序信息,你会在哪里保存它?
它需要被保存到磁盘。 但是,如果磁盘出现故障,这不会有帮助,所以它已经不是防灾的了。
您只能在保存的状态下获得一定程度的粒度。 如果你想要像tihs这样的东西,那么最好的办法就是定义粒度级别,就每个primefaces操作前的primefaces操作的构成和保存状态而言。 然后,您可以恢复到该级别的primefaces操作点。
我不知道任何会自动执行此操作的语言,因为将状态保存到辅助存储的成本非常高。 因此,在粒度级别和效率级别之间有一个折衷,这在任意应用中很难定义。
- 首先实现一个容错应用程序。 其中,如果您有8个function和5个失效模式,则您已经完成了分析和testing,以certificate所有40个组合按预期工作(并根据特定客户的需要:没有两个组合可能会同意)。
- 其次,在受支持的一组容错function之上添加脚本语言。 它需要尽可能接近无状态,所以几乎肯定是非图灵完备的。
- 最后,研究如何处理适合每种故障模式的脚本语言状态的恢复和修复。
是的,这是非常火箭 科学 。
Windows Workflow Foundation可能会解决您的问题。 它基于.Net,被devise成一个具有状态和行为的工作stream程。
它允许持久化到数据库(自动或当提示)。 你可以在状态/动作之间做到这一点。 这将您的工作stream的整个实例序列化到数据库中。 当满足任何条件(特定时间,以编程方式再水合,事件火灾等)时,它将被再水合并且执行将继续。
当WWF主机启动时,它会检查持久性数据库并重新存储在那里存储的任何工作stream。 然后从持久性的angular度继续执行。
即使您不想使用工作stream程方面,也可以使用持久性服务。
只要你的步骤是primefaces,这应该是足够的 – 特别是因为我猜你有一个UPS,所以可以监控UPS事件,并强制持久性,如果检测到电源问题。
如果我正在解决您的问题,我会写一个守护进程(可能是C),在交易中进行所有数据库交互,所以如果被中断,不会插入任何不良数据。 然后让系统在启动时启动这个守护进程。
很明显,用C语言开发网页材料比用脚本语言开发网页材料要慢很多,但是它会更好,更稳定(如果你编写好的代码当然是:)。
实际上,我会用Ruby(或PHP或其他)编写它,并且像Delayed Job(或cron或其他调度程序)那样经常运行它,因为我不需要更新任何时钟周期的东西。
希望是有道理的。
在我看来,故障恢复的概念在大多数情况下是一个业务问题,而不是硬件或语言问题。
举一个例子:你有一个UI层和一个子系统。 子系统不是很可靠,但是UI层的客户端应该像以前那样对其进行encryption。
现在,想象一下,你的子系统崩溃了,你真的认为你想象的语言可以为你考虑如何处理UI层取决于这个子系统吗?
你的用户应该清楚地知道这个子系统是不可靠的,如果你使用消息传递来提供高可靠性,那么客户端必须知道(如果他不知道,用户界面可能会冻结等待响应,最终可能会在2周后)。 如果他意识到这一点,这意味着任何隐藏它的概念最终都会泄露。
客户端,我的意思是最终用户。 用户界面应该体现出这种不可靠性,而不是隐藏起来,在这种情况下,电脑无法为你思考。
“所以在任何时刻,一种能记住它的状态的语言,不pipe电源是否被切断,并继续停止。”
“继续下去”往往不是正确的恢复策略。 世界上没有任何一种语言或环境会试图猜测如何从一个特定的故障中自动恢复。 最好的办法是为您提供工具,以不干扰业务逻辑的方式编写自己的恢复策略,例如
- exception处理(快速失败,仍然保证状态的一致性)
- 事务(回滚未完成的更改)
- 工作stream(定义自动调用的恢复例程)
- logging(用于追踪故障原因)
- AOP /dependency injection(避免必须手动插入代码来完成上述所有操作)
这些都是非常通用的工具,可用于各种语言和环境。