---
# System prepended metadata

title: 框架重構

---

# 框架重構 Re-architect

## 一、文章說明：
首先，框架重構的定義為**將更具有效益的解決方案，替換舊有的架構**，也就是透過架構的重新調整，獲得更優異的業務處理效能。

本文將以模擬情境方式，引導讀者了解何謂**框架重構**，並透過實際操作流程，更深入了解**AWS RDS**, **Auto-Scaling EC2**, **EC2 AMI**。


## 二、情境概述：
OOOO 是一家提供電子商務平台的初創公司，該公司的應用前端應用和後端資料庫都使用同一個伺服器，導致伺服器過載和性能問題。目前公司期望通過分離數據庫來提高應用的響應速度和處理效率，通過分離資料庫來降低資料安全風險，並同時希望能夠優化網站負載需求。通過添加一台新的資料庫伺服器，並且為原本的網站伺服器添加負載平衡器與Auto scaling，來加強優化伺服器過載的性能問題。

### 需求評估：
由於前端應用和後端資料庫都集中在同一台伺服器上，導致處理效能遇到瓶頸。

我們可以透過**解耦伺服器**來進行重構作業，將前端應用與後端資料庫分離，再加上負載平衡器、Auto Scaling來增加擴展彈性，提高響應速度；為後端資料庫建置RDS，提升資料可用性、處理效率。

### 架構比較：
* 當前架構
![image](https://hackmd.io/_uploads/ryIaxf2ST.png)

* 調整後架構
![image](https://hackmd.io/_uploads/rkFNjy186.png)

## 三、產品簡介：

* **Auto Scaling** 
是一項 AWS 服務，它能夠根據設定的指標和規則，自動增減 EC2 執行個體的數量。這使得系統能夠應對流量的變化，無論是高峰還是低谷；由於Auto-Scaling 會因為擴容策略而隨時進行機器的新增或刪除，故其中的EC2會是無狀態的比較適合，需要先準備一台精簡過後的EC2，作為後續建立AMI的範本。


* **Application Load Balancer (ALB)** 
是一種提供高度可用性和伸縮性的負載平衡器服務，可將流量分發到多個 EC2 執行個體上。相較於傳統的負載平衡器，ALB 可以根據應用程式層面的資訊進行流量分發。

* **RDS** 
是一項全管理型的關聯式資料庫服務，旨在簡化資料庫的設定、操作和維護，使開發者能夠專注於應用程式的開發而非基礎設施的管理；支援多種引擎，例如：PostgreSQL, MySQL, MariaDB, Oracle 或 SQL Server。

### 成本評估：
> 報價可能因所屬地區而有所不同，這邊以香港地區為例。

| 項目         | 規格 | 用途 | 數量 | 價格                                                             |
| ------------ | ------------- | ---- | ---- | ---------------------------------------------------------------- |
| Auto Scaling | N/A  | 透過指標追蹤策略，自動擴展遞減EC2執行個體 | 1    | 建立本身不計價，費用會來自EC2執行個體、EBS磁碟區、CloudWatch指標 |
|        EC2      |   t3.micro   |   作為前端網站主機   |    1  |      按需付費                                                            |
|        EBS磁碟區      |  gp2 20GB   |   主機磁碟   |  1    |        1GB/ 0.1056 USD                                                          |
|        CloudWatch      |   指標、警報   |   提供指標給Auto Scaling執行擴展策略   | N/A     |                       0.3 USD/ 指標、0.1/ 警報                                           |
|        RDS      |   db.t3.micro /gp2 20GB  |  作為後端資料庫    |  1    | 執行個體 18.98 USD, 儲存磁碟 2.76 USD                                                                |


## 四、操作步驟說明：
* 建立EC2 AMI
* 建立Launch Template
* 建立Auto Scaling Group
* 資料庫備份
* 建立RDS for MySQL
* 資料庫還原


## 建立EC2 AMI
1. 選擇精簡後的EC2建立AMI，這邊點選『 Action 』-->『 Image and template 』-->『 Create image 』
![image](https://hackmd.io/_uploads/Sy8SRg7Bp.png)

2. 輸入映像名稱並依需求選定是否允許重開機
![image](https://hackmd.io/_uploads/S14lybXra.png)
![image](https://hackmd.io/_uploads/SJefkWQH6.png)
> 由於開機狀態會咬住某些服務，故重開機會讓映像檔製作較為完整

3. 接著去AMI 確認建立Image進度，會從Pending 變成 Avalible
![image](https://hackmd.io/_uploads/Hkxd1bmST.png)

## 建立Launch Template
1. 輸入開機範本名稱並勾選『 Auto Scaling guidance 』
![image](https://hackmd.io/_uploads/r1QlfrmS6.png)

2. 選定剛才建立好的AMI作為範本
![image](https://hackmd.io/_uploads/SJGXGS7ST.png)

3. 依需求選定Instance type、選定Key pair
![image](https://hackmd.io/_uploads/rJrB38VHp.png)
> 這邊以最低價格做示範

4. 網路設定不選擇指定子網路，後續可以設定，Security group選擇自定義好的就行
![image](https://hackmd.io/_uploads/HJpmJPEHa.png)
> 若需要SSH連線操作、提供網頁服務，安全群組就要設定22, 80, 443允許通過

5. 磁碟大小依需求調整
![image](https://hackmd.io/_uploads/SyfoewVBT.png)

## 建立Auto Scaling Group
1. 建立Auto Scaling Group（以下簡稱為ASG），輸入名稱、選擇剛建立好的開機範本
![image](https://hackmd.io/_uploads/HkQXbvVBa.png)

2. 選定要放置在哪個VPC, Subnet
![image](https://hackmd.io/_uploads/S1uibwNSa.png)

3. 選擇建立新的Load balancer，要處理HTTP/ HTTPS流量，故選擇ALB，並輸入名稱
![image](https://hackmd.io/_uploads/rkbGfP4S6.png)

4. 選擇Internal，在至少兩個AZ指定子網路，並建立新的Target group，輸入名稱
![image](https://hackmd.io/_uploads/B1oKID4Ba.png)

5. 打勾EC2健康檢查功能，方便從介面上確認設備狀態
![image](https://hackmd.io/_uploads/Bk0WrwVSp.png)

6. 附加功能依需求選擇即可
![image](https://hackmd.io/_uploads/rycVSwNST.png)
> Instance warmup用於確保新機器開機時能快速銜接處理業務，提前暖機的意思，有助於提高應用程式的穩定性。

7. 定義起始數量（啟用幾個執行個體）、定義最大數量
![image](https://hackmd.io/_uploads/HJBJ5PESa.png)

8. 選擇Target tracking policy，依據需求指標來制定擴展政策
![image](https://hackmd.io/_uploads/r1Jr9DESp.png)
> 以CPU指標追蹤策略為例，當CPU達50%時，會提前300秒啟動新的執行個體，並開始暖機。

9. 此處沒有特別需求的話就選No policy即可
![image](https://hackmd.io/_uploads/ryugovVra.png)
> 當EC2發生維護事件時，該選擇什麼策略來對應，旨在抉擇維持高可用性或是控制成本。

10. 執行個體縮容保護
![image](https://hackmd.io/_uploads/S1WGawVHa.png)
> 剛啟動的執行個體在進行一些初始化設定時，遇到縮容，新執行個體會被強制終止，從而影響應用程式效能；意指若不會影響應用程式的話就不須保護。

11. 定義哪些行為需要建立通知並傳送至SNS，可依需求設定
![image](https://hackmd.io/_uploads/SkdzWuErp.png)

12. 依需求建立tag方便管理資源
![image](https://hackmd.io/_uploads/B1EKb_VBp.png)

13. 等待建立完成
![image](https://hackmd.io/_uploads/rJ5Hf_VBa.png)

14. 點進去可以檢查當前開啟了幾個Instance，並且確認健康狀況
![image](https://hackmd.io/_uploads/BJTLFKVH6.png)


## 資料庫備份
這邊採用CLI的形式執行資料庫備份，並以兩種常見引擎做示範。
### MySQL
手動備份指令如下：
```bash!
mysqldump -u user001 -p testdb > full_testdb_backup.sql
```
>  -u 後面輸入使用者名稱
>  -p 輸入密碼
>  testdb 替換成欲備份的資料庫名稱 
>  full_testdb_backup.sql 備份檔案名稱
 
實際操作如圖所示：
![image](https://hackmd.io/_uploads/rJFgPuVrp.png)

### PosgreSQL
手動備份指令如下：
```bash!
pg_dump -h localhost -p 5432 -U smdick1995 -d testdb_1 -f testdb_1_bk.sql
```
> -h 後面輸入主機名稱
> -p 後面輸入欲開啟的埠號
> -U 後面輸入使用者名稱
> -d 要備份的資料庫名稱
> -f 後面輸入備份檔案名稱


![image](https://hackmd.io/_uploads/SkjrqpqS6.png)

## 建立RDS for MySQL
1. 依需求建立相應的資料庫引擎
![image](https://hackmd.io/_uploads/ByjCiOErp.png)

2. 建立範本
![image](https://hackmd.io/_uploads/rJ1lp_4rT.png)
> 僅示範，故選擇免費等級

3. 若選擇免費以外的選項，則可以指定是否跨多區域建立範本，當然費用也會提高
![image](https://hackmd.io/_uploads/BJK4SKEr6.png)

4. 輸入RDS執行個體名稱，設定此資料庫最高權限帳號、密碼
![image](https://hackmd.io/_uploads/Hy7PIK4ra.png)
> 可以使用Secrets Manager管理位於KMS的密鑰，自動輪換密碼更方便。

5. 選定執行個體規格
![image](https://hackmd.io/_uploads/B1RxdtNr6.png)

6. 設定磁碟型別、空間大小，是否開啟auto scaling
![image](https://hackmd.io/_uploads/HJZX_t4Ba.png)

7. 設定連線到哪個VPC中的哪台EC2
![image](https://hackmd.io/_uploads/rJW4otEBa.png)
> 也可以在建立完RDS後設定連線

8. 建立DB Subnet group
![image](https://hackmd.io/_uploads/SkPFjF4B6.png)

9. 建立DB Security group, 選擇加密憑證（預設即可）
![image](https://hackmd.io/_uploads/Bk4SnFNB6.png)

10. 是否開啟自動備份，指定保留天數並指定例行備份的時間點
![image](https://hackmd.io/_uploads/r1XH6YEB6.png)

11. 是否為RDS備份加密，是否要記錄Log
![image](https://hackmd.io/_uploads/ryyu6tVHT.png)

12. 建議指定設備維護時段，避免在營業時間遭到離線維護而服務中斷
![image](https://hackmd.io/_uploads/H1jyRFEr6.png)

13. 以上都設定完按下建立，即可在此頁面確認是否安裝完畢
![image](https://hackmd.io/_uploads/BkKLx9EHp.png)

## 資料庫還原
資料庫還原的目標是AWS RDS for MySQL，故接著會以MySQL指令做示範，並透過EC2來存取、操作資料庫。

首先，將資料庫備份檔案丟進EC2，接著在EC2執行MySQL資料庫還原指令。

1. 先確認下指令的路徑有資料庫備份檔案
![image](https://hackmd.io/_uploads/BykmxboBa.png)

2. 將本地端的備份檔案透過scp（secure copy）上傳至EC2，指令如下：
```bash!
scp -i demo.pem backup.sql ec2-username@public-ip:/home/ubuntu/
```
> -i 後面輸入EC2的金鑰
> "baclup.sql" 替換成要複製的檔案
> "ec2-username@public-ip" 替換成登入機器的資訊
> ":/home/ubuntu" 指定要丟在機器內的什麼目錄下

3. 上傳完會顯示100%
![image](https://hackmd.io/_uploads/SJOXSWiS6.png)

4. 接著登入EC2來確認備份檔案是否存在
![image](https://hackmd.io/_uploads/HyXNI-jHp.png)

5. 需要先登入RDS建立資料庫才能還原備份檔案，因此我們先透過EC2連線至RDS，指令如下：

```bash!
mysql -h wilson-testdb-1.clgihkjlr0vi.ap-east-1.rds.amazonaws.com -P 3306 -u admin -p
```
> -h 主機名稱或IP 
> -P 欲連線的埠號
> -u 使用者名稱
> -p 密碼

6. 建立一個同名稱的資料庫，mysql指令如下：
```sql!
CREATE DATABASE testdb;
```
![image](https://hackmd.io/_uploads/rJvyiZoB6.png)
建立完成後輸入`exit`離開mysql終端介面

7. 執行資料庫還原，指令如下：
```bash!
mysql -h wilson-testdb-1.clgihkjlr0vi.ap-east-1.rds.amazonaws.com -P 3306 -u admin -p testdb < full_testdb_backup.sql
```
> -h 主機名稱或IP
> -P 欲連線的埠號
> -u 使用者名稱
> -p 密碼

8. 透過sql query查詢users這張表的資料都存在，表示還原成功！
> 切換資料庫 `USE testdb;` 
> 查詢資料表 `SELECT * FROM users;` 

![image](https://hackmd.io/_uploads/B1yk3WiHT.png)



