---
# System prepended metadata

title: "\U0001F6D2 Microservice (微服務架構)"
tags: [DevOps]

---

# 🛒 Microservice (微服務架構)

:::spoiler 📚 目錄
[TOC]
:::

## 1. 什麼是微服務？

微服務（Microservices）是一種軟體架構風格，它 **將應用程式拆分成多個獨立的、小型的、專注於單一職責的服務**，每個服務都可以獨立開發、部署和運行。這些服務通常透過 **API（通常是 REST 或 gRPC）** 進行通信。


:::spoiler 名詞解釋
> - **API**: Application Programming Interface
> 
> - **REST**: REpresentational State Transfer (表現層狀態轉移)
> 
> - **gRPC**: google Remote Procedure Call
> 
:::


:::spoiler 什麼是 RPC ?

## 一、 RPC 的定義

「Remote Procedure Call」這個名字的本質意涵是：

- **讓「分散式系統的通訊」像「呼叫本地函式」一樣方便**，但實際上那個函式會在遠端系統執行。 (執行中的函式就是 Procedure)
- RPC **通訊協定** 會自動幫你完成序列化、傳輸、反序列化等動作。


## 二、RPC 的底層邏輯

傳統上，如果你要呼叫遠端系統的功能，要自己寫：

1. 建立 TCP 連線
2. 打包參數（序列化）
3. 傳送
4. 等待回應（反序列化）
5. 處理錯誤、重試、超時等邏輯

這些繁瑣又容易出錯。

所以 **RPC 的目標** 就是**把網路傳輸這些細節封裝起來**，讓開發者「像呼叫本地函式一樣」呼叫遠端邏輯。

例如：

```java
// 假設這個函式實際上在另一台伺服器
User user = userService.getUserById(123);
```

你看起來只是呼叫一個 Java method，但底層實際上是：

```bash=
Client → serialize request → send over network → 
Server → deserialize → execute real method → serialize response → send back → 
Client → deserialize → return result
```

---

## 三、RPC 底層技術在演進

| 層面   | 早期 RPC    | 現代 gRPC                |
| ---- | --------- | ---------------------- |
| 序列化  | 自定義二進位格式  | Protocol Buffers（二進位）  |
| 傳輸協定 | TCP / UDP | HTTP/2                 |
| 呼叫型式 | 單次請求回應    | + streaming（雙向流）       |
| 語言支援 | 通常單一語言    | 多語言自動生成 stub           |
| 安全   | 弱或無       | TLS / mTLS 支援          |
| 通訊樣式 | 同步        | 支援同步 / 非同步 / streaming |

:::

## 2. 微服務的核心概念

- **獨立部署**：每個微服務都是獨立的，可單獨部署與更新，而不影響其他服務。
- **獨立技術棧**：每個微服務可以使用不同的編程語言、框架和數據存儲技術。
- **單一職責（Single Responsibility）**：每個微服務只關注一個特定的業務功能，如用戶管理、訂單處理、支付系統等。
- **分散式架構**：微服務運行於不同的伺服器或容器內，透過網絡進行通信。
- **容錯性**：如果某個微服務失敗，不會影響整個系統，其他服務仍能正常運行。


:::info
微服務架構本質上就是分散式的概念，所以要建立在**分散式系統**上
:::

### → 這麼做能解決什麼問題？
#### ⚠️ 單體式架構 (Monolith) 的困難

- **難以維護**：隨著功能不斷增加，單體應用會變得龐大且難以理解。
- **部署風險高**：小改動也可能需要重新部署整個應用，增加出錯機率。
- **擴展性受限**：只能整體水平擴展，無法針對單一功能進行精準擴展。
- **技術選型受限**：整個系統被綁定在同一技術棧，不易引入新技術。
- **團隊協作困難**：多人同時開發會造成模組依賴與衝突，降低開發效率。

:::spoiler 什麼是 Monolith (單體式架構)？
### 📦 Monolith (單體式架構)

**定義**
Monolith 是一種 **將整個應用程式集中在單一程式碼庫或部署單位** 的架構風格。
應用程式的所有功能模組（UI、業務邏輯、資料存取…）都被打包成 **一個執行檔或一個應用程式**，並且一起部署、一起運作。

---

### 🏗️ 架構特徵

1. **單一程式碼庫（Single Codebase）**

   * 所有功能寫在同一個專案或 repo 裡。

2. **單一部署單位（Single Deployment Unit）**

   * 不論新增或修改哪一個功能，都需要 **重新打包、重新部署整個應用**。

3. **集中式資料庫**

   * 通常共用同一個資料庫，所有模組都會直接存取。

4. **緊密耦合（Tightly Coupled）**

   * 功能彼此相依，難以獨立修改或擴展。

---

### ✅ 優點

* **開發簡單**：新手容易上手，初期開發速度快。
* **部署簡單**：只需要部署一次，不用管理多個服務。
* **測試容易**：整個應用在一個環境裡測試即可。
* **效能好**：模組間呼叫是函式呼叫，不需跨網路。

---

### ⚠️ 缺點

* **維護困難**：程式碼龐大後，修改一處可能影響全域。
* **部署風險大**：小改動也要重新部署整個應用，出錯風險高。
* **擴展性差**：無法針對單一模組獨立擴展，只能整體水平擴展。
* **技術債累積**：不同功能模組強烈耦合，導致開發效率下降。

---

### 🖼️ 簡單範例

假設你有一個電商平台（購物車、支付、會員、商品管理）：

* 在 **Monolith 架構** 中，所有功能都寫在同一個專案裡：

  * `UserController`
  * `ProductController`
  * `CartService`
  * `PaymentService`
  * **同一個 JAR / WAR / 執行檔** 一起部署。

---

### 👉 總結：
**Monolith = 一個大盒子，所有功能都塞在裡面，部署和擴展都只能整體操作。**

:::


---

## 3. 微服務的常見技術

- **API Gateway**：Kong、Traefik、NGINX、Spring Cloud Gateway
- **服務發現（Service Discovery）**：Consul、Eureka、Zookeeper
- **微服務框架**：Spring Boot（Java）、NestJS（Node.js）、Quarkus（Java）、Go Micro（Go）
- **容器與編排**：Docker、Kubernetes（K8s）
- **分佈式追蹤**：Jaeger、Zipkin
- **Message Queue**：RabbitMQ、Kafka、ActiveMQ、SQS（AWS）


:::spoiler 什麼是 Message Queue？
## Message Queue（消息隊列）

### 1. 什麼是 Message Queue？

消息隊列（Message Queue，MQ）是一種 **非同步通信機制**，用於在分散式系統中傳遞數據（不限傳遞資料格式？）。它允許不同的服務之間使用「消息」進行通信，而不需要彼此同步運行，從而提高系統的**可擴展性**、**可靠性**和**解耦性**。

需要額外 Message Queue Middleware 協助，也會被稱作 **Message Broker** 或 **Message Bus**。

### 2. 為什麼需要Message Queue？

- **Decoupling （解耦）**：發送者（Producer）和接收者（Consumer）不需要直接通信，而是透過Message Queue進行數據傳遞。
- **Asynchronous Processing （異步處理）**：允許系統在不同步的情況下處理請求，提升性能與響應速度。
- **Traffic Smoothing （流量削峰）**：當流量突增時，Message Queue可以作為緩衝，防止系統過載。
- **Reliability & Fault Tolerance （可靠性與容錯）**：如果某個服務暫時無法處理請求，消息會被保留在Message Queue，等系統恢復後再處理。

### 3. Message Queue 的工作流程

1. **Producer（生產者）**：發送消息到Message Queue。
2. **Consumer（消費者）**：從Message Queue中獲取消息並處理。

### 4. Message Queue的類型

#### 1️⃣ 點對點（Point-to-Point）

- **特點**：一條消息只能被 **一個** Consumer消費一次。
- **應用場景**：任務隊列、訂單處理。
- **代表技術**：ActiveMQ、RabbitMQ、Amazon SQS。

#### 2️⃣ 發布/訂閱（Publish-Subscribe）

- **特點**：一條消息可以被 **多個** Consumer訂閱並處理。
- **應用場景**：事件驅動架構、日誌廣播、通知系統。
- **代表技術**：Kafka、Redis Pub/Sub、Google Pub/Sub。

### 5. 常見的消息隊列技術

| MQ 技術 | 特點 | 適用場景 |
| --- | --- | --- |
| **RabbitMQ** | 基於 AMQP 協議，低延遲，可靠性高 | 任務隊列、短時間存儲消息 |
| **Apache Kafka** | 高吞吐量，分布式流處理 | 大數據、日誌分析、事件驅動架構 |
| **ActiveMQ** | 兼容多種協議，適合企業級應用 | 分布式系統的通信 |
| **Amazon SQS** | 雲端託管，無需維護 | 雲端應用消息傳遞 |

---

### 6. Microservice 和 Message Queue 的關係

在微服務架構中，Message Queue 經常被用來**解決微服務之間的通信問題**，例如：

1. **Asynchronous Processing（非同步處理）**
- 訂單系統（Order Service）下單後，通過消息隊列通知庫存服務（Inventory Service）更新庫存，而不用等待庫存更新完成再返回結果。
2. **Event-Driven Architecture（ 事件驅動架構）**
- 當用戶完成支付（Payment Service），系統可以透過 Kafka 廣播「支付成功」的事件，通知其他微服務（如物流、通知等）。
3. **Traffic Smoothing （削峰填谷）**
- 當有大量請求湧入時，服務可以先將請求放入 MQ，慢慢處理，避免瞬間超載。
:::


---

:::danger
### 容器化 ≠ 微服務

| **容器化 Containerization** | **微服務 Microservice** |
| --- | --- |
| 一個容器只放一種應用程式 | 一種應用程式只做一件事情 |
:::

---


## 4. 微服務的優缺點

### ✅ **優點**

- **易於擴展（Scalability）**：可以根據需求對特定微服務進行獨立擴展。
- **高可用性（High Availability）**：故障影響範圍小，不會導致整個系統崩潰。
- **方便 CI/CD**：每個微服務可以單獨測試、部署，而不影響其他部分。
- **技術靈活性（Technology Flexibility）**：可以使用適合每個微服務的技術棧，而不是統一規範所有技術。

### ❌ **缺點**

- **運維複雜度提高**：需要管理多個獨立的服務，包含監控、部署、日誌管理等。
- **分布式通信開銷**：微服務之間需要透過 API 或 Message Queue 進行通信，可能會增加延遲和故障點。
- **數據一致性問題**：不同微服務使用不同的數據存儲時，確保一致性變得更具挑戰性（可使用分佈式事務或最終一致性策略）。

---

## 5. 轉成微服務架構可能會遇到的困難

### 1️⃣ 版本控制不易 (有 Mono-repo, Poly-repo 兩種方法)

1. **Mono-repo**
    - **所有微服務程式碼集中在一個倉庫**
    - 優點：方便統一管理、共享程式庫、確保版本一致性、CI/CD 流程簡單
    - 缺點：倉庫龐大，權限控管不易，不同團隊可能會互相干擾

2. **Poly-repo**
    - **每個微服務都有獨立的倉庫**
    - 優點：團隊自主性高、權限隔離清楚、符合微服務獨立的特性
    - 缺點：跨服務版本管理困難，CI/CD 複雜度提升，依賴套件難以同步

### 2️⃣ 太多 service 跟 pod 不易管理配置
(例：網路配置)


即便順利的將服務搬到 k8s 上，當 service/pod 一多，可以使用像是 **[Istio](#%E2%9B%B5-Istio-%E7%AE%A1%E7%90%86-ServicePod-%E9%96%93%E7%9A%84%E7%B6%B2%E8%B7%AF%E6%A9%9F%E5%88%B6) 的工具來統一管理各個 pod 間的網路連線**。


---

## ⛵ Istio: 管理 Service/Pod 間的網路機制
> "Istio is a service mesh."

Service Mesh 的基本概念就是在每個 pod 旁增加一個 side car，**把關於流量、網路的雜事都抽離出來**，接下來所有經過 pod 的 request 都是經由 side car 轉導，大大減輕開發者們的負擔。除了 Istio 常見的還有 Linkerd。

另外，Istio 也順帶整合了許多第三方的觀測工具(e.g. Prometheus, Kiali, Grafana, etc.)


### Istio 架構
Istio 會在各個 Pod 旁 Inject 一個 side car (叫做 istio-proxy) 來幫助我們轉發 request、蒐集資訊等；而上層則會==多一層 Control Plane 層，這是一個叫做 istiod 的 Pod== 來幫助我們控管服務，開發者可以**透過指令/設定去統一管控 Service/Pod 間的網路機制**。

而 istiod 中間的 Pilot、Citadel、Galley 等元件有個概念就可以了，一般 Istio 操作上應該是不會遇到它們。


### 是否使用 Istio 的比較
在原生 K8S 上，各 Pod 間的溝通是透過 Node 上的 kube-proxy(它會紀錄其他節點上的 Pod iptables)並做 request 轉發。
而在 Istio 上，則不用透過原生機制，因為==每個 Side car 就是個 proxy==，所以直接幫你做 request 轉發。
![image](https://hackmd.io/_uploads/B1cO4e3yge.png)

> CNI (Container Network Interface)

---


## 總結一下

### ❓ 解決了什麼問題（Why）
- 解決單體式應用在**維護困難、部署風險、擴展受限**等痛點
- 提升 **可用性**、**彈性**、**團隊協作效率**

### 🧱 核心概念與架構（What / How）
- 每個服務 **單一職責、獨立部署、獨立技術棧**
- 透過 **API Gateway / Service Discovery / Message Queue / Service Mesh** 等基礎建設串接
- 使用 **Docker + Kubernetes** 來管理部署與擴展

### 📈 專案適合引入 Microservice 的條件
- 系統功能龐大且持續擴充
- 使用者數量龐大，需要水平方向的擴展能力
- 團隊人數多，需要分工協作與技術多樣性
- 需要快速上線與頻繁迭代（CI/CD）
- 需要高可用與容錯性

---
