高性能、高容錯性的分佈式框架AKKA瞭解一下?

框架介紹

AKKA是一款高性能、高容錯性的分佈式&並行應用框架,遵循Apache2開源許可,基於經典的Actor 併發模型,底層經過Scala語言實現,提供Java和Scala API。程序員

  • 並行與併發:提供對並行與併發的高度抽象。
  • 異步非阻塞:Akka-Actor 消息通訊都是基於異步非阻塞。
  • 高容錯性:爲跨多JVM 的分佈式模型提供強勁的容錯處理,號稱永不着機。
  • 持久化:Actor 攜帶的狀態或消息能夠被持久化,以便於在JVM 崩潰後能恢復狀態。
  • 輕量級:每一個Actor 大約只佔300bytes ,1G內存可容納接近300 萬個Actor 。



郵箱:每一個Actor都有本身的郵箱,其餘Actor發送過來的消息都會進入該郵箱。Akka自帶多種郵箱類型,也提供自定義郵箱的接口。(默認郵箱類型爲UnboundedMailbox,底層爲ConcurrentLinkedQueue,無阻塞,無界隊列)編程

路由:消息除了經過普通的Actor 發送以外,也能夠經過路由發送。路由策略有輪詢、廣播等。路由也能夠是一個Actor。安全

狀態持久化:基於內存堆的日誌、基於本地文件系統的快照存儲以及基於LevelDB的日誌。bash

網絡:用於實現遠程Actor和分佈式集羣,包含I/O、網絡通訊(TCP/UDP)、序列化配置、分佈式通訊協議(Gossip)、節點管理、集羣分片等內容。網絡

HTTP模塊:Akka提供了簡單易用的HTTP模塊,支持完整的HTTP 服務端與客戶端開發,快速構建性能極強的Rest Web服務。併發

Actor 模型

Actor是1973年就提出的一個分佈式併發編程模型,設計是基於消息驅動和非阻塞的。認爲萬物皆Actor。框架

Actor是Akka最核心的概念,也是最基本的執行單元。Actor認爲並行計算的最小單元就是一個Actor實例,而每一個實例擁有本身的狀態和行爲,在一個大型系統中,可能存在成千上萬Actor 實例,它們之間經過消息的方式進行通訊,每一個Actor 都能發送消息給其餘Actor,也能從其餘Actor 接收消息。異步

參考文章:tcp

https://www.jianshu.com/p/d803e2a7de8eActor分佈式

Actor 特色

引用:不能經過傳統"new"的方式直接建立一個Actor對象,經過actorOf 或者actorSelection 等方式返回一個ActorRef 對象,該對象有可能存在於本地,也可能存在於遠程節點。

狀態: Actor 在不一樣時刻可能有着不一樣的狀態,這些狀態用變量來表示,可進行持久化操做。

行爲: Actor 有接收和發送消息的能力,每當它接收一條消息後,就能夠執行某個業務操做,同時也能夠把消息轉發到其餘節點進行處理。

監管策略: Actor 系統是一個層級結構,當任務被某個Actor分攤到子Actor 時,父Actor 就擁有監管子Actor的義務。在監管時,咱們須要根據不一樣的狀況選擇不一樣的處理方案(好比中止、重啓、恢復或者失敗上溯)和策略 。

線程安全: Actor 運行於線程池之上,AKKA爲每一個Actor抽象出一個輕量級的執行「線程」,因此單個Actor 老是線程安全的,而且自己在處理接收到的消息時是串行的。

輕量級: 在Akka 中, 每一個Actor 只佔用300 字節左右,支持分佈式模式。

Actor 定義

在Akka中,Actor 大體分爲兩類:

  • UntypedActor:基於經典的Actor 模型實現,消息驅動,推薦使用它來定義Actor 。
  • TypedActor :把正常OOP 的代碼包裝成異步執行的Actor ,比較符合程序員的API 調用邏輯,可是使用過程稍複雜,本次暫不討論。

經過繼承UntypedActor定義一個Actor,onReceive 方法是用於接收並處理消息的地方,對消息類型進行匹配,當匹配不到相應的消息類型時,使用unhandled進行處理。


Actor 建立

首先下載所須要的依賴

<dependency>    
    <groupId>com.typesafe.akka</groupId>    
    <artifactId>akka-actor_2.11</artifactId>  
    <version>2.4.1</version>
</dependency>
<dependency>
    <groupId>com.typesafe.akka</groupId>   
    <artifactId>akka-remote_2.11</artifactId>   
    <version>2.4.1</version>
</dependency>複製代碼

經過ActorSystem 的actorOf 方法建立Actor:

ActorSystem system = ActorSystem.create(「hiseePS」); ActorRef actorRef = system.actorOf(Props.create(ActorDemo.class),"actorDemo");

  • actorOf 返回的不是Actor 自己,而是ActorRef,即Actor 的引用,咱們就是經過該引用來進行消息通訊的。
  • 假如Actor 的構造函數有參數,能夠經過create 方法傳人。
  • 經過ActorSystem 建立的是一個頂級的Actor(即/user下的分支Actor),若是要建立層級關係的Actor 網絡,任務交給子Actor 去處理,父級負責去監督子級。能夠使用Actor中的getContext 來建立子Actor。

ActorRef childActor = getContext().actorOf(Props.create(ChildActor.class ),"childActor");


每一個Actor 在被建立後都擁有本身的路徑,該路徑遵循ActorSystem 的層級結構:akka://mysys/user/parentActor/childActor akka.tcp://mysys@l27.0.0.1:2554/user/parentActor/childActor

mysys 是ActorSystem 的名字,/user 是用戶建立Actor 的默認根節點, parentActor和childActor 分別是父子Actor。

Actor 消息

經過ActorRef 對象和Actor 進行消息通訊,有兩種方式給一個Actor 發送消息,tell 和ask 。它們都以異步的方式發送消息,不一樣的是,前者發完後當即返回,然後者期待獲得一個返回結果,假如在設置的時間(Timeout)內沒有獲得返回結果,發送方會收到一個超時異常。任何給Actor 發送的消息都會經過receive 方法收到。

tell 方法:actorRef.tell("Hello Akka", ActorRef.noSender());

第一個參數是「消息」,它能夠是任何可序列化的數據或對象,第二個參數表示發送者,即另一個Actor 的引用,noSender()表示無發送者(系統默認deadLetters的Actor)。若是在Actor內部要獲取消息發送者,能夠調用getSender()方法。在調用tell 方法後, Actor 就會異步的去處理該消息,不會阻塞後續代碼的運行。

ask 方法:當咱們須要從Actor 獲得一個返回結果時,能夠使用ask,這是一種典型的"請求一響應"模式。ask 方法會將返回結果包裝在scala.concurrent.Future 中(能夠理解爲Future模式線程),能夠(阻塞)獲取這個值,也能夠經過異步回調函數獲取這個值,考慮到性能問題,咱們每每會採用後者。

Ask 方法測試


Actor 消息轉發

消息轉發:

除了直接給某個Actor 發送消息外,咱們還能夠經過forward 方式對消息進行轉發,比較典型的使用場景是實現消息路由及負載等功能,消息發送者不會改變。


其餘用法

1.對於己存在的Actor,咱們能夠根據路徑來進行查找

ActorSelection=[ActorSystem/ActorContext].actorSelecton([path]);

2.Actor 行爲切換: 示例代碼(BecomeActor)

3.Actor 生命週期

Actor 在運行時中會經歷不一樣的階段,好比建立、運行、重啓和銷燬等,這一系列的過程或狀態,咱們稱之爲生命週期。

4.監督與容錯處理

5.Circuit Breaker (熔斷)

就不一一介紹了有興趣的同窗能夠本身瞭解一下。

好了AKKA的簡單介紹就到這裏了,第一次寫,寫的很差還望指點。

相關文章
相關標籤/搜索