programming-languages - popular - the top programming languages 2019



是否存在防災語言? (19)

在創建必須具有高可靠性的系統服務時,我經常最終編寫許多“故障保護”機制,以防萬一:通信已經消失(例如與數據庫通信),如果電源是什麼會發生什麼?丟失,服務重新啟動....如何拿起碎片並以正確的方式繼續(並記住,當拾取碎片時,電源可能會再次出現......)等等

我可以想像,對於不太複雜的系統,一種能滿足這一要求的語言非常實用。 所以這種語言在任何特定時刻都會記住它的狀態,無論電源是否被切斷,還是在它停止的地方繼續。

這還存在嗎? 如果是這樣,我在哪裡可以找到它? 如果沒有,為什麼不能實現呢? 在我看來,關鍵系統非常方便。

ps如果數據庫連接丟失,則表示出現問題,需要手動干預。 在他恢復連接的那一刻,它會在它停止的地方繼續。

編輯:由於討論似乎已經消失,讓我添加幾點(等待我可以添加獎金之前的問題)

Erlang的反應現在似乎是最高評價。 我知道Erlang並且讀過Armstrong(主要創作者)的實用書。 這一切都非常好(雖然函數式語言使我的頭部旋轉所有的遞歸),但“容錯”位不會自動出現。 離得很遠。 Erlang提供了許多監督程序和其他方法來監督進程,並在必要時重新啟動它。 但是,要正確地製作適合這些結構的東西,你需要成為erlang大師,並且需要讓你的軟件適合所有這些框架。 此外,如果電源掉電,程序員也必須拿起碎片並嘗試在下次程序重啟時恢復

我正在尋找的東西更簡單:

想像一種語言(例如像PHP一樣簡單),您可以在這裡執行諸如數據庫查詢,操作,執行文件操作,執行文件夾操作等操作。

然而,它的主要特徵應該是:如果電源消失,並且事情重新啟動它就會從它停止的地方開始(因此它不僅會記住它的位置,它還會記住變量狀態)。 此外,如果它在文件複製過程中停止,它也將正確恢復。 等等

最後但並非最不重要的是,如果數據庫連接丟失且無法恢復,語言就會暫停,並發出信號(可能是系統日誌)供人為乾預,然後繼續進行。

像這樣的語言會使很多服務編程變得容易多了。

編輯:似乎(根據所有評論和答案判斷)這樣的系統不存在。 並且可能不會在近乎可預見的將來由於它(接近?)無法做到正確。

太糟糕了....我不是在尋找這種語言(或框架)讓我登上月球,或用它來監視某人的心跳。 但對於小型定期服務/任務總是有大量的代碼處理邊框(在中間的某個地方斷電,連接丟失而不是恢復),......在這裡暫停,...修復問題,... ..並繼續你離開的地方方法會很好。

(或作為評論者指出的檢查點方法(如在視頻遊戲中)。設置檢查點....如果程序死亡,請在下次重新啟動。)

Bounty獎勵:在每個人都得出結論的最後一刻可能無法完成,Stephen C帶有napier88,它似乎具有我正在尋找的屬性。 雖然它是一種實驗性語言,但它確實可以證明它是可以完成的,並且它是值得研究的東西。

我將著眼於創建自己的框架(可能包含持久狀態和快照),以便在.Net或其他VM中添加我正在尋找的功能。

每個人都感謝您的投入和偉大的見解。

https://src-bin.com


Answer #1

然而,它的主要特徵應該是:如果電源消失,並且事情重新啟動它就會從它停止的地方開始(因此它不僅會記住它的位置,它還會記住變量狀態)。 此外,如果它在文件複製過程中停止,它也將正確恢復。 等等

......

我過去看過二郎。 不管它有什麼樣的容錯功能......它無法在斷電中存活下來。 當代碼重新啟動時,你將不得不拿起碎片

如果存在這樣的技術,我會非常有興趣閱讀它。 也就是說,Erlang解決方案將擁有多個節點 - 理想情況下位於不同的位置 - 這樣,如果一個位置發生故障,其他節點就可以獲得鬆弛。 如果您的所有節點位於相同的位置並且位於相同的電源上(對於分佈式系統來說不是一個好主意),那麼您將在評論後續跟踪中提到的運氣不好。


Answer #2

Microsoft Robotics Group引入了一組似乎適用於您的問題的庫。

什麼是並發和協調運行時(CCR)?

並發和協調運行時(CCR)提供高度並發的編程模型,基於消息傳遞和強大的編排原語,無需使用手動線程,鎖,信號量等即可協調數據和工作.CCR滿足了多核和通過提供有助於管理異步操作,處理並發,利用並行硬件和處理部分故障的編程模型來實現並發應用程序。

什麼是分散式軟件服務(DSS)?

分散式軟件服務(DSS)提供了一種輕量級,面向狀態的服務模型,它將代表性狀態轉移(REST)與形式化的組合和事件通知體系結構相結合,從而實現了系統級方法來構建應用程序。 在DSS中,服務作為資源公開,可以通過編程方式和UI操作訪問。 通過將服務組合,結構化狀態操作和事件通知與數據隔離相集成,DSS提供了一個統一的模型,用於編寫在單個節點或網絡上運行的高度可觀察,鬆散耦合的應用程序。

給出的大多數答案都是通用語言。 您可能希望研究嵌入式設備中使用的更專業的語言。 機器人是一個值得思考的好例子。 從電源故障中恢復後,您想要和/或期望機器人做什麼?


Answer #3

軟件事務存儲器(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個遠程類型的全面爆炸,接通電源,並重新啟動並重新啟動所有的電傳類型,好像什麼都沒發生一樣。 從嘈雜到沉默和背部的變化令人驚嘆,我知道,我不得不多次重複調試電源故障管理代碼,它當然做了很棒的演示(插上插頭,扼殺沉默,插回...... )。 這樣做的語言的名稱當然是彙編程序: - }



Answer #5

,不存在防災語言。

編輯:

防災意味著完美。 它提醒了一個過程的圖像,該過程應用一些智能以邏輯方式解決未知,未指定和意外的情況。 編程語言無法通過這種方式實現此目的。 如果你作為程序員,無法弄清楚你的程序將如何失敗以及如何從中恢復,那麼你的程序也無法做到。

從IT角度來看,災難可能以如此多的方式出現,以至於任何一個流程都無法解決所有這些不同的問題。 您可以設計一種語言來解決出現問題的所有方法的想法是錯誤的。 由於硬件的抽象,使用編程語言解決許多問題甚至沒有多大意義; 但它們仍然是“災難”。

當然,一旦你開始限制問題的範圍; 那麼我們就可以開始討論為它開發解決方案了。 因此,當我們停止談論防災並開始談論從意外的電湧中恢復時,開發一種編程語言以解決這個問題變得更加容易,即使在處理該問題時也許沒有多大意義。如此高水平的堆棧。 但是,我會冒險預測,一旦你將其範圍縮小到實際的實現,它就會變得無趣,因為它變得非常具體。 即使用我的腳本語言在一夜之間運行批處理過程,這些過程將從意外的電湧和網絡連接丟失中恢復(有一些人工協助); 這對我來說並不是一個引人注目的商業案例。

請不要誤解我。 在這個帖子中有一些很好的建議,但在我看來,他們甚至沒有任何東西,甚至遠程接近防災。


Answer #6

準確答案:

AdaSPARK旨在實現最大的容錯能力,並將所有錯誤轉移到編譯時而不是運行時。 Ada由美國國防部設計用於軍事和航空系統,在飛機等嵌入式設備上運行。 Spark是它的後代。 在早期的美國太空計劃中使用了另一種語言,HAL / S適用於處理由於宇宙射線導致的硬件故障和內存損壞。

實際答案:

我從來沒有見過任何能編碼Ada / Spark的人。 對於大多數用戶而言,最佳答案是DBMS上的SQL變體,具有自動故障轉移和服務器群集。 完整性檢查確保安全。 像T-SQL或PL / SQL這樣的東西具有完全的事務安全性,是Turing-complete,並且非常容忍問題。

原因沒有更好的答案:

出於性能原因,您無法為每個程序操作提供持久性。 如果你這樣做,處理速度會降低到最快的非易失性存儲速度。 充其量,你的性能將下降一千或幾百萬,因為任何比CPU緩存或RAM慢多少。

它相當於從Core 2 Duo CPU到古老的8086 CPU - 最多每秒可以進行幾百次操作。 除此之外,這甚至會降低。

如果存在頻繁的電源循環或硬件故障,您可以使用DBMS之類的東西,它可以保證每個重要操作的ACID。 或者,您使用具有快速非易失性存儲(例如閃存)的硬件 - 這仍然要慢得多,但如果處理很簡單,那就沒問題。

充其量,您的語言為您提供了良好的編譯時安全檢查錯誤,並將拋出異常而不是崩潰。 異常處理是現在使用的一半語言的一個特性。


Answer #7

在嵌入式領域,這可以通過看門狗中斷和電池供電的RAM來實現。 我自己寫過這樣的文章。


Answer #8

在我看來,失敗恢復的概念大多數時候是業務問題,而不是硬件或語言問題。

舉個例子:你有一個UI層和一個子系統。 子系統不是很可靠,但UI層上的客戶端應該像它一樣完善它。

現在,想像一下你的子系統崩潰,你真的認為你想像的語言,你能想到如何根據這個子系統處理UI層嗎?

您的用戶應明確意識到子系統不可靠,如果您使用消息傳遞提供高可靠性,客戶端必須知道(如果他不知道,UI可以凍結等待響應,最終可能在2週後出現)。 如果他應該意識到這一點,這意味著任何隱藏它的abstration最終都會洩漏。

客戶端,我的意思是最終用戶。 用戶界面應該反映出這種不可靠性而不是隱藏它,在這種情況下,計算機無法為您考慮。


Answer #9

大多數此類努力 - 稱為“ 容錯 ” - 都圍繞著硬件,而不是軟件。

最典型的例子是Tandem ,其“不間斷”機器具有完全冗餘。

在硬件級別實現容錯是有吸引力的,因為軟件堆棧通常由來自不同提供商的組件製成 - 您的高可用性軟件應用程序可能會安裝在操作系統之上的一些非常不穩定的其他應用程序和服務上。使用明顯易碎的硬件設備驅動程序..

但在語言層面,幾乎所有語言都提供了正確錯誤檢查的功能。 但是,即使使用RAII,異常,約束和事務,這些代碼路徑也很少被正確測試,很少在多故障場景中一起測試,並且通常在錯誤處理代碼中隱藏錯誤。 所以更多的是程序員的理解,紀律和權衡,而不是語言本身。

這使我們回到硬件級別的容錯。 如果可以避免數據庫鏈接失敗,則可以避免在應用程序中執行狡猾的錯誤處理代碼。


Answer #10

如果您確實希望保存程序信息,您將在哪裡保存?

它需要保存到例如磁盤。 但是如果磁盤發生故障,這對你沒有幫助,所以它已經不是防災了。

您只能在保存的狀態下獲得一定的粒度級別。 如果你想要像tihs這樣的東西,那麼最好的方法可能是根據構成原子操作的內容來定義粒度級別,並在每次原子操作之前將狀態保存到數據庫。 然後,您可以恢復到該級別原子操作的點。

我不知道任何語言會自動執行此操作,因為將狀態保存到二級存儲的成本非常高。 因此,在粒度級別和效率之間存在折衷,這在任意應用程序中很難定義。


Answer #11

如果我要解決你的問題,我會編寫一個守護進程(可能在C中),它在事務中完成所有數據庫交互,因此如果它被中斷,你不會得到任何錯誤數據。 然後讓系統在啟動時啟動此守護程序。

顯然,在C語言中開發Web東西要比在腳本語言中使用它慢得多,但它會表現得更好並且更穩定(如果你編寫好的代碼當然:)。

實際上,我會用Ruby(或PHP或其他)編寫它,並且像Delayed Job(或cron或任何調度程序)一樣經常運行它,因為我不需要更新時鐘週期的東西。

希望有道理。


Answer #12

如果故障模式僅限於硬件故障,則VMware Fault Tolerance會聲稱您需要類似的功能。 它在多個集群中運行一對虛擬機,並使用他們稱之為vLockstep的虛擬機,主vm將所有狀態實時發送到輔助虛擬機,因此在主要故障的情況下,執行將透明地翻轉到輔助虛擬機。

我的猜測是,這無助於通信故障,這比硬件故障更常見。 對於嚴重的高可用性,您應該考慮分佈式系統,如Birman的流程組方法( pdf格式的紙張 ,或書籍可靠的分佈式系統:技術,Web服務和應用程序 )。


Answer #13

我懷疑你所描述的語言特徵是否有可能實現。

其原因在於,定義常見和一般故障模式以及如何從中恢復將非常困難。 考慮一下您的示例應用程序 - 一些具有一些邏輯和數據庫訪問權限的網站。 並且假設我們有一種語言可以檢測電源關閉和後續重啟,並以某種方式從中恢復。 問題是,不可能知道語言如何恢復。

假設您的應用是在線博客應用。 在那種情況下,從我們失敗的那一點開始就足夠了,一切都好。 但是,請考慮網上銀行的類似情況。 突然間,從同一點繼續下去已經不再聰明了。 例如,如果我試圖從我的帳戶中提取一些錢,並且計算機在檢查之後但在執行提款之前就已經死了,然後它會在一周之後返回,即使我的帳戶在現在消極。

換句話說,沒有一個正確的恢復策略,因此這不是可以在語言中實現的東西。 什麼語言可以告訴你什麼時候發生了不好的事情 - 但大多數語言已經支持異常處理機制。 其餘的由應用程序設計人員來考慮。

有許多技術可以設計容錯應用程序。 數據庫事務,持久消息隊列,群集,硬件熱交換等等。 但這一切都取決於具體要求以及最終用戶願意支付多少費用。


Answer #14

我認為恢復的一個根本錯誤不是一個突出的設計問題。 獨占於環境的責任導致了一個通常脆弱的解決方案,不能容忍內部故障。

如果是我,我會投資可靠的硬件並以一種能夠在任何可能的條件下自動恢復的方式設計軟件。 根據您的示例,數據庫會話維護應由足夠高級別的API自動處理。 如果您必須手動重新連接,則可能使用了錯誤的API。

正如其他人所指出的那樣,嵌入在現代RDBMS系統中的程序語言是您在不使用外來語言的情況下獲得的最佳選擇。

VM通常是為這類東西而設計的。 您可以使用VM供應商(vmware..et al)API來控制應用程序中的定期檢查點。

特別是VMWare具有重放功能(增強執行記錄),可記錄所有內容並允許時間點回放。 顯然,這種方法會對性能產生巨大影響,但它可以滿足要求。 我只是確保你的磁盤驅動器有一個電池支持的寫緩存。

您很可能能夠找到在java虛擬機中運行的java字節碼的類似解決方案。 Google容錯JVM和虛擬機檢查點。


Answer #15

最接近的似乎是SQL。 然而,這不是一個真正的語言問題; 它主要是一個VM問題。 我可以想像具有這些屬性的Java VM; 實施它將是另一回事。

通過應用程序檢查點實現快速和骯髒的近似。 你失去了“隨時死亡”的財產,但它非常接近。


Answer #16

有一種稱為Napier88的實驗性語言(理論上)具有防災的一些屬性。 該語言支持正交持久性,並且在一些實現中,這擴展(擴展)以包括整個計算的狀態。 具體來說,當Napier88運行時系統將正在運行的應用程序檢查指向持久性存儲時,當前線程狀態將包含在檢查點中。 如果應用程序隨後崩潰並以正確的方式重新啟動它,則可以從檢查點恢復計算。

不幸的是,在這種技術準備好主流使用之前,需要解決許多難題。 這些包括確定如何在正交持久性的上下文中支持多線程,確定如何允許多個進程共享持久存儲,以及持久存儲的可伸縮垃圾收集。

並且存在在主流語言中進行正交持久性的問題。 已經嘗試過用Java做OP,包括由Sun(Pjama項目)相關人員完成的,但目前沒有任何活躍的。 如今,JDO / Hibernate方法更受青睞。

我應該指出,正交持久性在很大程度上並不是真正的防災。 例如,它無法處理:

  • 重新啟動後,使用“外部”系統重新建立連接等
  • 應用程序錯誤導致持久數據損壞,或
  • 由於檢查點之間的系統崩潰導致的數據丟失。

對於那些人,我不相信有一些實用的通用解決方案。


Answer #17

根據您對災難的定義,從“困難”到“實際上不可能”將此責任委託給語言可能會有所不同。

給出的其他示例包括在執行每個語句之後將應用程序的當前狀態持久保存到NVRAM。 這只有在計算機不被破壞時才有效。

語言級功能如何知道在新主機上重新啟動應用程序?

並且在將應用程序恢復到主機的情況下 - 如果已經過了大量時間並且之前做出的假設/檢查現在無效了怎麼辦?

T-SQL,PL / SQL和其他事務性語言可能與“災難證明”一樣接近 - 它們要么成功(並且數據被保存),要么它們沒有。 排除禁用事務隔離,如果你真的努力嘗試進入“未知”狀態很困難(但可能並非不可能)。

您可以使用SQL鏡像之類的技術來確保在提交事務之前將寫入同時保存在至少兩個位置。

您仍然需要確保每次安全(提交)時保存您的狀態。


Answer #18

考慮一個由非易失性存儲器構建的系統。 程序狀態始終保持不變,如果處理器停止任何時間長度,它將在重新啟動時停止的位置恢復。 因此,您的程序是“防災”,只要能夠在電源故障中存活。

這完全是可能的,正如其他帖子在談論軟件事務記憶和“容錯”等時所概述的那樣。好奇的人沒有提到'憶阻器',因為他們將提供具有這些屬性的未來架構,而且可能不完全是馮諾依曼建築也。

現在想像一個由兩個這樣的離散系統構建的系統 - 為了直觀說明,一個是數據庫服務器,另一個是在線銀行網站的應用服務器。

如果一個人暫停,另一個人會做什麼? 它是如何處理它的同事突然無法使用的?

它可以在語言級別處理,但這意味著大量的錯誤處理等等,並且這是一個棘手的代碼來實現。 這幾乎沒有比我們今天更好的地方,機器沒有檢查指向,但語言嘗試並檢測問題,並要求程序員處理它們。

它也可以暫停 - 在硬件層面它們可以捆綁在一起,這樣從功率角度來看它們就是一個系統。 但這不是一個好主意; 更好的可用性將來自具有備份系統等的容錯架構。

或者我們可以在兩台機器之間使用持久性消息隊列。 但是,在某些時候這些消息會被處理掉,而且它們可能在那時太老了! 在這種情況下,只有應用程序邏輯才能真正發揮作用,我們又回到了再次委託給程序員的語言。

因此,當前形式的防災似乎更好 - 不間斷的電源,準備好的熱備份服務器,主機之間的多個網絡路由等等。然後我們只需要希望我們的軟件沒有錯誤!


Answer #19
  • 首先,實現容錯應用程序。 其中,如果您有8個功能和5個故障模式,您已經完成了分析和測試,以證明所有40個組合按預期工作(並且根據具體客戶的需要:沒有兩個可能會同意)。
  • 第二,在支持的容錯功能集之上添加腳本語言。 它需要盡可能接近無國籍,所以幾乎肯定是非圖靈完成的東西。
  • 最後,研究如何處理適應每種故障模式的腳本語言狀態的恢復和修復。

是的,這幾乎是rocket science