[Erlang 0060] Joe Armstrong 論文《面向軟件錯誤構建可靠的分布式系統》筆記


  周末讀了兩篇論文"On Designing and Deploying Internet-Scale Services"和Joe Armstrong的論文"面對軟件錯誤構建可靠的分布式系統",這兩篇論文實戰內容相當多,整理筆記於此,備忘.
 
On Designing and Deploying Internet-Scale Services [ HTML]
英文版"Making reliable distributed systems in the presence of sodware errors"  [PDF
中文版 《面向軟件錯誤構建可靠的分布式系統》 [PDF
 

架構的定義

 
  An architecture is the set of significant decisions about the organization of a sodware system, the selection of the structural elements and their interfaces by which the system is composed, together with their behaviour as specified in the collaborations among those elements, the composition of these structural and behavioural elements into progressively larger subsystems, and the architectural style that guides this organization—these elements and their interfaces, their collaborations, and their composition.
                                                                                                        Booch, Rumbaugh, and Jacobson [19]
   
  在我接觸到的架構定義中,Joe Armstrong論文中提到的定義相當務實,相當具有實踐指導價值;首先和Martin Fowler等人對架構的共識是架構是一組系統組織方式的重要決策;決策包含系統有哪些構成元素,元素之間的接口,元素之間的協作方式;是一種把這些結構和行為元素構建為更大子系統的的合成方式;也是一種構建風格,在其指導下把元素,元素接口,元素協作和合成方式組織起來.
   

  把架構的抽象概念映射到具體實踐過程,可以從六個具體方面去考量,這時候我們已經從萬里高空下降到陸地上了.
  
1.問題領域——我們的架構是為解決什么類型的問題而設計的?軟件架構一定不是通用的,而是為解決某一類特定問題而設計的.缺少了關於用來解決哪類問題的描述的架構是不完整的.
 
   筆記 :同樣的,缺少上下文描述的編程語言比較也只是一場關公戰秦瓊的亂斗而已;遇到過一些"技術牛人"身居要位,硬是把之前項目的設計方案強制應用在當前的項目上,這都不是偷懶那樣簡單,而是缺少對項目負責的專業態度.而更為糟糕的是一旦項目做失敗了,就甩手走人,留下一個爛尾的工程留給團隊;對團隊的傷害,需要更長時間進行修復.

2.哲學——  軟件構造方法背后的原理是什么?架構的核心思想是什么?
 
   筆記 :在解決了問題或者完成了一個設計之后,我們一定要回顧一下解決問題的思路和設計的原理;具體的技術細節可能無法服用,但是思維方式和設計方法都是可以復用的.在閱讀開源項目時,學習語言技巧是一方面,更為重要的是看這個項目是解決了什么問題,如何解決的,整體思路是怎樣的.
 
3.軟件構造指南——我們如何來規划一個系統?我們需要一個明確的軟件構造指南集.我們的系統將由一個程序員團隊來編寫和維護——所以對所有的程序員和系統設計者來說,理解系統的架構和它的潛在哲學是很重要的.從實用性的角度來講,這些知識以軟件構造指南的方式表現出來更便於維持.一個完整的軟件構造指南集包括編程規則集,例子程序和培訓資料等等.
 
  筆記 :這個還是深有感觸的,現在有一些項目比如PlayStation®Suite SDK把C#當作腳本使用,但是你會發現在這些項目里面雖然同是C#語言但無論是類庫組織還是命名規范都是有自己的規則和風格的.
 
 
4.預先定義好的部件——以“從一組預先定義好的部件中選擇”的方式進行設計遠比“從頭設計”的方式要來得容易.Erlang 的OTP庫包含了一個完整的現成部件集(稱之 behaviour 庫),一些常用的系統都可以使用這些部件構建起來.例如 gen_server 這種 behaviour 就可以用來構建client-server 系統,gen_event 這種 behaviour 可以用來構建基於事件(event-based)的程序. 
 
   筆記 :學習語言,其中一個重要的部分就是掌握這個語言所提供的類庫;一方面是不重復造輪子,能夠直接使用高質量類庫;另一方面從類庫中可以學習這種語言的編程風格.
 
5.描述方式——我們如何描述某一部件的接口?我們如何描述系統中兩個部件之間的通信協議?我們如何來描述系統中的靜態和動態結構?為了回答這些問題,我們將介紹一些專門的符號.其中一些用來描述程序的API,而其他的則用來描述協議和系統結構。 
 
   筆記 :學習一種新知識,其中的門檻一方面是來自於概念,另一方面就是來自於符號系統;這兩種都是對信息進行了簡化,背后包含了較大的信息量,沒有額外的信息支持難以理解.在最初接觸一種新知識的時候,由於不了解這個領域的術語和概念,我們甚至都不能正確的描述遇到的問題.

6.配置方式——我們如何來啟動,停止和配置我們的系統?我們可以在系統工作過程中進行重配置嗎?
 
   筆記 :編程完成業務功能並沒有萬事大吉,還要考慮到配置,部署,這些問題的考慮時機甚至在設計之初就要考慮;針對不同的硬件設備,配置也有所不同;考慮到日常維護,還要准備一些給運維使用的腳本.
 
 

Erlang 故障隔離

 
   為了構建出在軟件存在錯誤的時候仍具有合理行為的可容錯軟件系統,Erlang的解決問題的思路是:
1.任務層次化,盡力完成頂層任務
2.如果完成任務過程中出現錯誤,如果無法糾正錯誤,就立即取消重新啟動新的任務
 
   這其中最本質的問題就是故障隔離,操作系統通過進程的概念實現了故障隔離, 進程提供了保護區域,一個進程出錯,不會影響到其他進程的運行.不同程序員編寫的不同應用程序分別跑在不同的進程中; 一個應用程序的錯誤不會對系統中運行的其他應用程序產生副作用.這種選擇當然滿足了初步的要求.然而因為所有進程使用同一片 CPU,同一塊物理內存,所以當不同進程爭搶 CPU 資源或者使用大量內存的時候,還是可能對系統中的其他進程產生負面影響. 進程間的相互沖突程度取決於操作系統的設計特性.
 
  Erlang進程和並發編程是語言的一部分,而不是由宿主操作系統提供的,Erlang應用程序是通過大量互相通信的並行進程構建起來的,這樣做的原因是:
 
   架構基礎設施 ——我們可以用一組相互通信的進程組織起我們的系統,並定義出進程間消息傳遞的通道,我們就可以很方便地把系統划分成定義良好的子部件,並可以對這些子部件進行單獨實現和測試.

   巨大的潛在效率 ——設計成以許多獨立的並行進程來實現的系統,可以很方便地實現在多處理器上,或者運行在分布式的處理器網絡上. 注意這種效率的提升只是潛在的,只有當應用程序可以被分解成許多真正獨立的任務時,才能產生實效.如果任務之間有很強的數據依賴,這種提升往往是不可能的.
 
   故障隔離 ——沒有共享數據的並發進程提供了一種強大的故障隔離方法.一個並發進程的軟件錯誤不會影響到系統中其他進程的運行.
 
     在並發的這三種用法中,前兩條並不是其本質特性,可以由某種內置的調度程序通過在進程間提供不同的偽並行(pseudo-parallel)時分方式來獲得.第三個特性對於編寫可容錯系統的軟件來說,則是本質性的.每一項獨立的活動都在一個完全獨立的進程中來執行.這些進程沒有共享數據,進程之間只通過消息傳遞的方式進行通信,這就限制了軟件錯誤造成的影響. 
    一旦進程之間共享有任何公共資源,譬如內存,或指向內存的指針,或互斥體等等,一個進程中的一個軟件錯誤破壞共享資源的可能性就存在.因為消除大型軟件系統中的這類軟件錯誤仍然是一個未解的難題,所以我認為構建大型的可靠系統的唯一現實的方法就是把系統分解成許多獨立的並行進程, 並為監控和重啟這些進程提供一些機制, 
 
  從某種意義上講,操作系統提供了“被編程語言設計者遺忘了的東西”.但是在 Erlang 這樣的編程語言中, 操作系統是幾乎不需要的.OS真正提供給 Erlang的只是一些設備驅動程序,而 OS提供的諸如進程,消息傳遞,調度,內存管理等等機制都不需要. 
 
 

面向並發編程語言COPL

 
  COPL編寫這樣的並發程序相當容易,它有三個步驟:
1.從真實世界中的活動中識別出真正的並發活動 
2.識別出並發活動之間的所有消息通道
3.寫下能夠在不同的消息通道中流通的所有消息
 
   值得注意的是,COPL 提供的並發性一定是真正的並發性,因此以進程的形式存在的對象都是真正並發的,進程間的消息傳遞也是真正的異步消息,而不像許多面向對象語言中一樣是通過遠程過程調用(remote procedure call)來冒充.
 

Erlang世界觀概覽

 
• Everything is a process.
• Processes are strongly isolated.
• Process creation and destruction is a lightweight operation.
• Message passing is the only way for processes to interact.
• Processes have unique names.
• If you know the name of a process you can send it a message.
• Processes share no resources.
• Error handling is non-local.
• Processes do what they are supposed to do or fail. 
 

思維導圖

Erlang
View more documents from ligaoren


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM