# 框架重構 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)