早安,我是今年參與「第 55 屆全國技能競賽英雄榜暨第3屆亞洲技能競賽及第 48 屆國際技能競賽國手選拔賽青年組雲端運算職類」並入圍二階國手選拔的選手,寫這篇文章是為了分享我在比賽過程中的一些心得和經驗。
在開始分享之前,先客套的感謝一下主辦單位、裁判及工作人員們的辛勤付出,讓這次比賽能夠順利進行。雖然比賽過程中浪費了點時間在處理設備問題,但整體還是很順利的。
簡單介紹一下我自己:
- 逢甲大學資訊工程學系畢業
- 國立中央大學資訊工程學系碩士
- 第 53 屆全國技能競賽雲端運算職類 第三名、入圍二階國手選拔1
- 第 54 屆中區技能競賽網頁技術職類 第二名、
全國賽請假跑去學海築夢爽2 - 第 55 屆全國技能競賽雲端運算職類 一階國手選拔第一名、入圍二階國手選拔3
- 自籌 2025 中區雲端運算訓練營 講師兼出題仔
第一次接觸到雲端運算職類是在第 53 屆,當時的我接觸雲端還不到一年,但不知不覺就拿到了個全國賽第三名還進入二階國手選拔,可惜當時的我實戰經驗不夠,與法國里昂的國際賽無緣。 今年的比賽帶著更充足的準備和實戰經驗,在全國賽的五個科目中全部拿下第一,希望 9 月的二階國手選拔也能如此順利。
比賽流程
扣掉第一天報到跟最後一天的頒獎,比賽共有五個科目,各科目約為 3 小時且內容獨立。
比賽內容不公開,但這次題目都是用 AWS Workshop,賽後 Google 一下關鍵字能找到蠻多有的沒的資源。這篇文會分享一下科目一的題目和我的解題過程。因為科目內的題目內容高度糾纏,比完賽出來就快記不起來了,有錯誤歡迎指正。
競賽過程中會有 Scoreboard 顯示目前的分數和排名,分數則是根據解題進度來計算,但有些靠北的題目送錯答案或是做太慢會被扣分,這點要特別注意不要一口氣把題目全開。
科目一: Unicorn.Rentals
這題目考驗的是怎麼動態調整 Compute 資源,能應付忽大忽小的 HTTP 流量,同時保持可用性、回應時間與成本最佳化。
題目只有一個送出欄位讓你提交 endpoint URL,後臺會自動發請求到你的 endpoint,並根據每個 request 的回應時間來計算分數。 同時每分鐘會根據使用的資源來做扣分,只要流量得分小於成本扣分,分數就會被扣爛。
該題目提供了一個既有的 AWS 環境,內容大致如下:
- 1x VPC
- 有點忘記 resource map 長怎樣,但記得沒有 S3-gateway
- 1x 有 Elastic IP 的 EC2 instance
- 完全獨立,endpoint 預設指在這台
- 1x Application Load Balancer (ALB)
- 1x target group
- 2x EC2 instances,都有 public IP
EC2 裡面跑的是 Python HTTP server,題目文件中也有提供 user data 來協助設定環境,大概長這樣:
bash
#!/bin/bashwget https://s3.amazonaws.com/xxx/web-binary.py -O /website/web-binary.pychmod +700 /website/web-binary.pypython3 /website/web-binary.pyshutdown -h now
沒記錯的話整場的流量大概長這樣:
CloudFront 快取
這題的重點在於使用 CloudFront 快取來降低計算資源的使用率,同時降低回應時間。
在題目文件中我們可以看到請求會長的像這樣:
GET /calc?input=xxxxx
我們可以推測一個 input
只會對應到一個結果,所以可以利用 CloudFront 的 Cache policy 來做快取。
透過在 CloudFront 建立一個 Cache policy,設定 Default TTL 不要太低(預設一天即可)、指定 Cache key settings 中的 Query strings 為 All
,並於對應的 behavior 中使用該 policy 即可。
比賽結束前幾分鐘看到 CloudFront 的 Hit Rate 大概為 10.5%,對於回應時間和成本的優化都有很大的幫助。
Auto Scaling
題目提到流量會隨時間變化,開一台大機器接請求肯定是不划算的,因此需要使用 Auto Scaling 來動態調整 EC2 instance 的數量,應對變化的流量需求。 當然這題也可以用 ECS 或 EKS 來做,但礙於時間有限加上懶得寫 Dockerfile,所以就直接用 EC2 來做了。
在做 auto scaling 之前,我們可以看到 user data 裡面只有對外抓取 S3 上的程式碼,所以我們可以不給他 public IP 跟 NAT gateway,直接透過 VPC endpoints 來存取 S3 gateway,省下 IP 跟 NAT 的費用。
新建一個 VPC,資源如下:
接下來建立一個 Launch Template,指定 AMI、user data、disable public IP 等。從 S3 抓程式碼是用 wget,可以得知不需要 IAM role。
接著建立一個 Auto Scaling Group,指定 VPC 為剛剛建立的 VPC,subnets 選擇建立的兩個 private subnets,並指定 Launch Template。 最省錢的作法會是用 t3.nano 的 spot instance,但我忘記而是用 t2.nano on-demand,賽後跟其他選手討論後才得知每台可以少被扣 4 分。
最後建立一個 Application Load Balancer,並將 ALB 的 subnets 改為 public subnets (預設會自動選跟 EC2 的一樣,但 ALB 需要 internet gateway,只有 public subnets 才有)、target group 指向 Auto Scaling Group,這樣就完成了。
對於 Auto Scaling Policy 的設定,單看 EC2 的 CPU 使用率並沒有太大變化,因此我使用 Request Count per Target 來做 scaling policy,設定為每分鐘約 15 個請求。
除此之外還有幾點可以優化的地方:
- Target group 的 algorithm 可以改成 least outstanding requests,讓流量優先分配到請求較少的 instance 上。
- 降低 Auto Scaling 設定的 health check grace period,讓 instance 在啟動後就能更快開始接收請求。
- 降低 Load Balancer 的 connection draining 時間,更快釋放要縮減的 instance。
建完後記得回到 CloudFront 建立新的 origin,並把對應的 behavior 指向新的 origin。
更新版本
題目在後期會有一個叫你更新 server-binary.py 版本的步驟,因為我們已經建好 launch template 了,直接建立新版本並在 Auto Scaling Group 中做 instance refresh 即可(慢到靠北,追求速度的話直接 terminate 再開其實也行)。
猴子
在競賽過程中會遇到「猴子」來亂條你的設定,這時候就需要透過監控來快速反應,把它亂改的設定改回來。 賽後跟其他選手討論總結出來被改到的地方只有 Auto scaling group 的 desired capacity,透過監控 scaling activity 便可快速發現並修正。 但我還是花了點時間搞了 CloudWatch Dashboard 來監控整體流量、回應時間以及 CloudFront 狀態(不知道為什麼有時候會突然跑出幾個 504)。
科目心得
第一步先看懂文件並清點預設環境內有哪些資源跟它的邏輯蠻重要的,像我一開始就發現它建好了個可以用的 ALB,連上去測也是正常的,套完 CloudFront 就直接上線開始賺分,整場沒被扣分過。
雖然更新版本的過程中被其他選手分數反超,但我把 auto scaling 的 scale-in/out 設定得很極致,最後半小時流量上上下下依舊穩定輸出,直接把分數拉回來,最後領先 2000 分守住了第一名。
這幾天會再寫其他科目的心得,一個科目一篇,慢慢寫到 Part 5。有興趣的話可以關注一下或是請我喝杯咖啡或吃一頓好料 🥰。