iT邦幫忙

2022 iThome 鐵人賽

DAY 4
1

核心概念

以下是 Moleculer 涵蓋的所有核心觀念[1]。

服務

最基本的 JavaScript 模組,用於撰寫一個複雜應用的其中一小部分。由於每個服務都是獨立的,可以中斷、隔離甚至發生錯誤時,也不會影響到其它的服務。

節點 (Node)

節點是建構在本地或外部網路上的簡單系統處理程序,每個節點可以託管一個或多個服務。

本地服務

在單一節點中運行 2 個以上的服務將被視為本地服務。它們共用相同的硬體資源以及使用本地匯流器與其它服務無網路延遲通訊(沒有使用 Transporter)。

遠端服務

分散在多個節點上的服務是被認為遠端服務的。在這種情況下會通過 Transporter 來通訊。

服務代理 (Broker)

服務代理是 Moleculer 的核心。它負責本地與遠端服務的管理與通訊,每一個節點至少要有一個服務代理實例。

訊息傳輸器 (Transporter)

訊息傳輸器是一個通訊匯流器用來交換訊息。它能傳輸事件、請求及響應。

閘道器 (Gateway)

API 閘道器將 Moleculer 服務公開給終端使用者。閘道器是一個正規的 Moleculer 服務,用於執行 HTTP、WebSockets 等伺服器。它能處理傳入的請求,將他們映射到相對應的服務,然後返回合適的響應。

整體來看

舉個商店的例子,可以將服務分為 gateway 與 products 兩個獨立的服務,前者負責處理用戶的請求並傳送給 products ,後者負責產品的 CRUD 管理,然後將兩個服務分別放到兩個節點 Node 1 、 Node 2 。

假設服務啟動後,實際上的運作流程如下:

  1. 首先用戶向服務器發送了請求 ( GET /products ) ,進入 Node 1 的 gateway 進行解析請求。
  2. 接著 gateway 會將請求傳給 Broker 。
  3. Broker 則將請求送到 Transporter 。
  4. Transporter 將任務分派給 Node 2 的 Broker 。
  5. 接著會將請求傳給 products 服務
  6. 最後由服務取得產品清單資料,返回並響應給用戶。


Fig. 1. 用戶的請求流程圖

執行實作

我們有了完整的架構定義後,就可以來實作商店了。

此範例採用了 NATS 作為 Transporter,需要先 下載安裝 或是使用 Docker 來啟動。

筆者這裡使用 Docker Run 來快速建立 NATS 服務:

docker network create nats
docker run --name nats --network nats --rm -p 4222:4222 -p 8222:8222 nats --http_port 8222

接著建立範例程式需要的套件 moleculer 、 moleculer-web 、 nats :

{
  "name": "moleculer-store",
  "dependencies": {
    "moleculer": "^0.14.21",
    "moleculer-web": "^0.10.4",
    "nats": "^2.7.1"
  }
}

然後建立主程式 index.js 用來定義需要的服務:

index.js

const { ServiceBroker } = require("moleculer");
const HTTPServer = require("moleculer-web");

// 建立 node-1 Broker
// 定義 nodeID 及設定 Transporter
const brokerNode1 = new ServiceBroker({
    nodeID: "node-1",
    transporter: "NATS"
});

// "gateway" 服務
brokerNode1.createService({
    // 定義服務名稱
    name: "gateway",
    // 載入 HTTP Server
    mixins: [HTTPServer],

    settings: {
        routes: [
            {
                aliases: {
                    /*
                     * 當接收到 "GET /products" 請求時,
                     * 則映射到 "products" 服務內的 "listProducts" 功能項 (如果存在的話)。
                     */
                    "GET /products": "products.listProducts"
                }
            }
        ]
    }
});

// 建立 node-2 Broker
// 定義 nodeID 及設定 Transporter
const brokerNode2 = new ServiceBroker({
    nodeID: "node-2",
    transporter: "NATS"
});

// "products" 服務
brokerNode2.createService({
    // 定義服務名稱
    name: "products",
    // 定義功能項
    actions: {
        // 定義服務功能項,響應可用的產品清單
        listProducts(ctx) {
            return [
                { name: "Apples", price: 5 },
                { name: "Oranges", price: 3 },
                { name: "Bananas", price: 2 }
            ];
        }
    }
});

// 啟動所有的 Broker
Promise.all([brokerNode1.start(), brokerNode2.start()]);

服務在終端機啟動後,結果如圖所示:


Fig. 2. 服務啟動結果

可以在瀏覽器打開 http://localhost:3000/products 連結,結果如圖所示:


Fig. 3. 瀏覽器執行結果

其它範例

Moleculer 另外還提供了兩個較完整的專案範例,包含了更多功能實作給開發者作為參考:

https://moleculer.services/docs/0.14/examples.html

參考文獻

[1] Core Concepts, https://moleculer.services/docs/0.14/concepts.html

家家酒小劇場

  • Otter - 今天的流程繞來繞去,看得我都頭昏眼花了 +_+
  • Boxy - 沒關係的,因為這些複雜的流程, Broker 都已經幫我們處理好囉,只要將功能寫進去再設定一下就行了。
  • Otter - 太好了,那我就可以專心在功能開發了 >w<

上一篇
Day 3 : Hello Moleculer
下一篇
Day 5 : Broker
系列文
Moleculer 家家酒 共 31 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
json_liang
iT邦研究生 2 級 ‧ 2022-09-04 10:38:20

感謝大大解說微服務概念

我要留言

立即登入留言