天天看點

Akka架構——第一節:并發程式設計簡介

本節主要内容:

1. 重要概念

2. actor模型

3. akka架構簡介

多核處理器的出現使并發程式設計(concurrent programming)成為開發人員必備的一項技能,許多現代程式設計語言都緻力于解決并發程式設計問題。并發程式設計雖然能夠提高程式的性能,但傳統并發程式設計的共享記憶體通信機制對開發人員的程式設計技能要求很高,需要開發人員通過自身的專業程式設計技能去避免死鎖、互斥等待及競争條件(race condition)等,熟悉java語言并發程式設計的讀者們對這些問題的了解會比較深刻,這些問題使得并發程式設計比順序程式設計要困難得多。

scala語言并沒有直接使用java語言提供的并發程式設計庫,而是通過actor模型來解決java并發程式設計中遇到的各種問題,為并發程式設計提供了更進階的抽象。

1 重要概念

(1)并發和并行

并發和并行從宏觀來看,都是為進行多任務運作,但并發(concurrency)和并行(parallelism)兩者之間是有差別的。并行是指兩個或者兩個以上任務在同一時刻同時運作,;而并發是指兩個或兩個以上的任務在同一時間段内運作,即一個時間段中有幾個任務都處于已啟動運作到運作完畢之間,這若幹任務在同一cpu上運作但任一個時刻點上隻有一個任務運作。圖121給出了多核處理器下的現代作業系統程序和線程模型,圖中程序2的線程1被調用度到處理器的核2上運作、程序3的線程1被排程到處理器的核3上運作,程序2的線程1和程序3的線程1是并行的,它們可以同時運作,而程序1的線程1和線程2都排程到處理器的核1上運作,此外它們還共享線程1的記憶體空間,在運作時面臨着資源競争包括cpu、記憶體及其它如io等,它們在同一時候隻能運作一個,但在一段時間内都可以運作,是以程序1的線程1和線程2是并發執行的。

Akka架構——第一節:并發程式設計簡介

圖1 程序、線程模型

(2)橫向擴充和縱向擴充

所謂縱向擴充(scale up)指的是增加程式的進度或線程數量,提高程式的并發性;而橫向擴充(scale out)指的是程式可以擴充到其它機器上運作,即通過分布式系統來提到程式的并行度。傳統的java并發程式設計模型不容易進行縱向擴充,是以并發的線程數越多,程式行為便會變得很難了解和控制,更多的線程加入到資源競争,出現死鎖等情況的機率增加。橫向擴充比縱向擴充困難更大,此時的程式變為分布式環境下的應用,情況更為複雜,對開發人員的要求更高。scala提供的actor模型可以解決并發應用程式的橫向擴充和縱向擴充問題,如圖2、圖3給出了基本actor模型的橫向擴充和縱向擴充。

Akka架構——第一節:并發程式設計簡介

圖2 縱向擴充

Akka架構——第一節:并發程式設計簡介

圖3 橫向擴充

2 actor模型

在使用java語言進行并發程式設計時,需要特别關注共享的資料結構,線程間的資源競争容易導緻死鎖等問題,而actor模型便是要解決線程和鎖帶來的問題,actor是一種基于事件(event-based)的輕量級線程,在使用actor進行并發程式設計時隻需要關注代碼結構,而不需要過分關注資料結構,是以actor最大限度地減少了資料的共享。 actor由三個重要部分組成,它們是狀态(state),行為(behavior)和郵箱(mailbox),actor與actor之間的互動通過消息發送來完成,actor模型如圖4所示,狀态指的是actor對象的變量資訊,它可以是actor對象中的局部變量、占用的機器資源等,狀态隻會根據actor接受的消息而改變,進而避免并發環境下的死鎖等問題;行為指的是actor的計算行為邏輯,它通過處理actor接收的消息而改變actor狀态;郵箱(mailbox)建立起actor間的連接配接,即actor發送消息後,另外一個actor将接收的消息放入到郵箱中待後期處理,郵箱的内部實作是通過隊列來實作的,隊列可以是有界的(bounded)也可以是無界的(unbounded),有界隊列實作的郵箱容量固定,無界隊列實作的郵箱容易不受限制。

Akka架構——第一節:并發程式設計簡介

圖4 actor模型

不難看出,actor模型是對現實世界的高度抽象,它具有如下特點:(1)actor之間使用消息傳遞機制進行通信,傳遞的消息使用的是不可變消息,actor之間并不共享資料結構,如果有資料共享則通過消息發送的方式進行;(2) 各actor都有對應的mailbox,如果其它actor向該actor發送消息,消息将入隊待後期處理;(3)actor間的消息傳遞通過異步的方式進行,即消息的發送者發送完消息後不必等待回應便可以傳回繼承處理其它任務。

3 akka并發程式設計架構

scala語言中原生地支援actor模型,隻不過功能還不夠強大,從scala 2.10版本之後,akka架構成為scala包的一部分,可以在程式中直接使用。akka架構作為akka是一個以actor模型為基礎建構的基于事件的并發程式設計架構,底層使用scala語言實作,提供java和scala兩種api,它屬于lightbend公司(原typesafe公司)體系結構的一部分,如圖5所示。

Akka架構——第一節:并發程式設計簡介

圖5 lightbend 體系結構[ ]

akka架構意在簡化高并發、可擴充及分布式應用程式的設計,它具有如下優勢:

(1) 使用akka架構編寫的應用程式既可以橫向擴充(scale out)、也可縱向擴充(scale up)。

(2) 編寫并發應用程式更簡單,akka提供了更高的抽象,開發人員隻需要專注于業務邏輯,而無需像java語言那樣需要處理底級語義如線程、鎖及非阻塞io等。

(3) 高容錯,akka使用“let it crashes”機制,當actor出錯時可以快速恢複。

(4) 事件驅動的架構,akka中的actor之間的通信采用異步消息發送,能夠完美支援事件驅動。

(5) 位置透明,無論是actor運作在本地機器還是遠端機器上,對于使用者來說都是透明的,這極大地簡化了多核處理器和分布式系統上的應用程式程式設計。

(6) 事務支援能力,支援軟體事務記憶體(software transactional memory,stm),使actor具有原子消息流的操作能力。

akka架構由下列十個元件構成:

(1) akka-actor :包括經典的actor、typed actors、io actor等

(2) akka-remote:遠端actor

(3) akka-testkit:測試actor系統的工具箱

(4) akka-kernel :akka微核心,用于運作精簡的微型應用程式伺服器,無需運作于java應用伺服器上。

(5) akka-transactor :transactors 即支援事務的 actors,內建了scala stm

(6) akka-agent – 代理, 同樣內建了scala stm

(7) akka-camel – 內建apache camel

(8) akka-zeromq – 內建zeromq 消息隊列

(9) akka-slf4j – 支援slf4j 日志功能

(10) akka-filebased-mailbox – 支援基于檔案的mailbox

scala學習(公衆微信号:scalalearning)每天為大家帶來一點scala語言、spark、kafka、flink、akka等大資料技術幹貨及相關技術資訊。技術永無止境,勇攀高峰,一往直前!

覺得文章不錯?掃描關注

Akka架構——第一節:并發程式設計簡介