---
# System prepended metadata

title: Actor Model（角色模型）介紹
tags: [摳Sense]

---

###### tags: `摳Sense`

# Actor Model（角色模型）介紹

<br>

## 簡介

Actor Model 首先是由 Carl Hewitt 在1973定義，由 Erlang OTP 推廣，其目的是為了解決分散式運算中一系列的問題。

Actor Model 是一種並行運算的模型，Actor 則是一種程式上的抽象概念，被視為並行運算的基本單元，通過元件方式定義並行程式設計正規化的高階階段，避免使用者直接接觸多執行緒並行或執行緒池等基礎概念，其訊息傳遞更加符合面向物件的原始意圖。

<br>

## 特點

* <font color=#FF0000>**Actor**</font>
指的是一個最基本的計算單元，可以被用來代表各種不同類型的目標物。它本身類似一個黑盒的物件，封裝了自己的狀態跟行為，因此 Actors 之間是互相隔開的，它們不互相共享記憶體，也不互相呼叫，只有訊息通知。也就是說，一個 Actor 能維持自己的狀態，並且不被其他的 Actor 所改變。

* <font color=#FF0000>**Actor Model**</font>
是一種非同步訊息模式的分散式平行計算模型。這種模型有自己的一套規則，規定了 Actor 的內部計算邏輯，及 Actors 之間的通訊規則。在其模型中，Actor 是唯一組成部份，每個 Actor 都會有一個地址，以便與其它 Actor 互相傳送訊息。
![](https://i.imgur.com/gV6DUwj.png)

* <font color=#FF0000>**MailBox**</font>
Actor 只能有順序地並且一次處理一條訊息，當 Actor 正在處理訊息時，新接收到的訊息會儲存到Actor 內部的一個佇列中，我們把它形象化稱做 MailBox。
![](https://i.imgur.com/aZROZiQ.png)

* <font color=#FF0000>**容錯性**</font>
Erlang 引入了「隨它崩潰」的哲學理念，運行的程式碼被監控著，監控者的唯一職責是知道程式崩潰後要做甚麼（例如將計算單元重置為正常的狀態）。
Erlang 將一個 Actor 視為一個 Process，這個 Process 完全獨立，意味著它的狀態不受其它 Process 的影響。另外我們會有個 Supervisor（實際上也是 Actor），當被監控的 Process 掛掉，Supervisor 會收到通知並且嘗試處理它的狀態，這裡會有多種策略，最常見的是根據初始狀態重新啟動 Actor。

* <font color=#FF0000>**分散性**</font>
Actors 之間互相發送訊息，它並不會在意對象是在本地或是遠端，只要訊息能送達就行了，這種模式允許了我們在多台機器上建構集群系統。

* <font color=#FF0000>**與Thread的關係**</font>
Actor 底層的實作實際上就是由 Thread Pool 進行實作，每一個 Actor 就是一個 Thread，只是我們在編寫程式碼時看不到 Thread 的影子。

<br>

## 工作原理

### 工作流程

![](https://i.imgur.com/4d1XiKV.png)

1. Actor1 向 Actor2 發送訊息，訊息被放入 Actor2 的 MailBox 佇列之中。
2. Actor3 向 Actor2 發送訊息，訊息被放入 Actor2 的 MailBox 佇列之中。
3. Actor2 從 MailBox 佇列中依次取出訊息執行相應的操作，由於 Actor1 先把訊息發送給 Actor2，因此 Actor2 先處理 Actor1 的訊息，然才後處理 Actor3 的訊息。

### 訊息傳遞流程

![](https://i.imgur.com/n4lZ3f6.png)

1. 組件 A 創建一個 Actor System，用來創建並管理多個 Actor。
2. 組件 A 產生 QuoteRequest 訊息（即 mail 訊息，比如經過處理後資料），並將其發送給 ActorRef。 ActorRef 是對應 Actor System 所創建的組件 B 其下的一個 Actor 的代理。
3. ActorRef 將訊息（經過處理後資料）傳輸給 Message Dispatcher 模塊。 Message Dispatcher 類似於快遞的中轉站，負責接收和轉發消息。
4. Message Dispatcher 將訊息（經過處理後資料）加入組件 B 的 MailBox 佇列中。
5. Message Dispatcher 將 MailBox 加入執行緒。需要注意的是，只有當 MailBox 是執行緒時，才能處理 MailBox 中的訊息。
6. 組件 B 的 MailBox 將佇列中的訊息（資料）取出後刪除並作處理，進行模型訓練。

<br>

## 計算模式

### 三要素

* <font color=#FF0000>**狀態（State）**</font>：Actor 元件本身的資訊。
* <font color=#FF0000>**行為（Behavior）**</font>：Actor 的計算邏輯與處理操作。
* <font color=#FF0000>**訊息（Mail）**</font>：Actor 的訊息以郵件的形式在多個 Actor 之間通訊傳遞，每個 Actor 都會有一個自己的郵箱，用於>接收來自其它 Actor 的訊息。

### 關鍵特性

* <font color=#FF0000>**實現了更高級的抽象**</font>：前面提到過，Actor 封裝了狀態和行為。但是 Actor 之間是異步通信的，多個 Actor 可以獨立運行且不會被干擾。
* <font color=#FF0000>**非阻塞性**</font>：在 Actor 模型中，Actor 之間是異步通信的，所以當一個 Actor 發送信息給另外一個 Actor 之後，無需等待響應，發送完信息之後可以在本地繼續運行其他任務。也就是說，Actor 模型通過引入消息傳遞機制，從而避免了阻塞。
* <font color=#FF0000>**無需使用鎖**</font>：Actor 從 MailBox 中一次只能讀取一個消息，也就是說，Actor 內部只能同時處理一個消息，是一個天然的互斥鎖，所以無需額外對代碼加鎖。
* <font color=#FF0000>**並發度高**</font>：每個 Actor 只需處理本地 MailBox 的消息，因此多個 Actor 可以並行地工作，從而提高整個分佈式系統的並行處理能力。
* <font color=#FF0000>**易擴展**</font>：每個 Actor 都可以創建多個 Actor，從而減輕單個 Actor 的工作負載。當本地 Actor 處理不過來的時候，可以在遠程節點上啟動 Actor 然後轉發消息過去。

<br>

## 總結

![](https://i.imgur.com/VEOY6UN.png)


