蓋環境很難?是這樣的嗎?QA 需要自己蓋環境?


上一次的分享 之後,開始有 QA 的朋友找我聊很多他正在面對的問題。其中一個問題是:

Backend 開發人員說建立環境很難?是這樣嗎?

本文針對這個問題,整理背後可能的問題,以及實際可行的方法。全文整理自 09/18 在 FB 寫的草稿


Backend 開發人員說建立環境很難?是這樣嗎?

標題簡化了一些訊息,重現原本的提問:

我是一個 QA,我曾經找 Backend 開發人員問,我想自己建環境測試,他們說很難,Config 很雜亂、DB Schema 很複雜、Infra 很複雜,真的是這樣?

重新整理提問,整個問題是從 蓋環境 (專有名詞 Provisioning) 出發,對於測試人員來看,背後 動機目的 有以下:

  1. 因為執行測試過程會被自動觸發的 CI 部署打斷,希望不被干擾執行
  2. 想要透過了解環境,更確立問題的正確性
  3. 想要透過 Log 找問題,目前環境無法看到 Log
  4. 測試過程,想進去 DB 增加資料,查問題

從開發人員的回覆,可以看出背後有以下問題:

  1. Config 很雜亂
  2. DB Schema 很複雜
  3. Infra 很複雜

1. 現象:Config 很雜亂

Config 指的是應用程式在啟動階段透過外界指定的配置資訊,應該在 系統設計 (System Design) 過程就要確立的結構,這屬於 Application Interface 的範疇,也是 System Design 階段要確立的東西。

Application Interface 是我自己定義的名詞,用來描述一個應用程式的外顯介面。只要是使用者會接觸到的資訊,都屬於外顯介面,像是 Config / Environment Variables / Secret / API / Documentation … etc.

常見的 Config 大概可以分成以下幾個部分:

  1. 系統依賴:
    1. 會有 connection string 的,包含 ip / host、protocol、id / password 、parameters 等。
    2. 服務自己的基礎設施,像是對 Database / Cacche / Queue .. 等依賴
    3. 公司內部與第三方系統的依賴:
      1. 公司內部:像是依賴於內部的 簡訊服務、另一個服務的 API … 等。
      2. 第三方服務:像是依賴於 Google SSO、AWS S3 服務、Twillo 的簡訊服務、Paypal 的金流服務 … 等。
  2. 業務邏輯功能的初始與預設參數:
    1. 通常是 Feature Toggle 以及其參數
    2. 每頁商品數量的預設數量
    3. 其他 … etc
  3. 非功能的參數:
    1. Logging: Rotation 的規則、擋名規則、輸出模式 (File or Stdout) ..
    2. DI 框架的參數,像是 Autowire 掃描的規則
    3. 框架的設定

這些依照實際案例,會有所差異,不過我個人大概是這樣分。

Config 需要有經驗的人、經過有設計的過程,持續精煉與重構。因為沒有這個循環,隨著時間的推進 (通常是 >2y),會越來越複雜,隨之而來的是管理複雜度。如果再加上多環境部署 (不管 Test or Prod),管理問題就會浮上檯面。

Config 的設計概念參閱 Designing Configuration Loading Strategies

問題背後的問題 (QBQ)

  1. 開發過程沒有設計與管理:在新需求開發過程中,Config 很常會因為新需求而增加,這時候沒有適度的設計與管理,時間久了,一定開花。
    1. 不管用 K/V 結構 (.properies) 或者 object (XML / JSON / YAML),只要沒有配套的 技術管理機制,最後就是整串葡萄串大亂鬥
    2. 機制:透過統一個 ConfigLoader 限制,包含命名規則、資料結構驗證等
    3. 規範:要有設計與 Review 流程
  2. 沒有持續收斂設計:如果沒有適度的技術管理機制持續收斂,時間越久越亂是正常的
    1. 各種亂象出現在 Config 裡,像是在一個 JSON element 裡面塞入一個 XML string
    2. 在一個 XML 的 attribute 裡塞入整個 JSON payload
  3. 部署管理機制不踏實
    1. 不管有沒設計或收斂,都需要面對管理問題,因為只要有部署的需求,部署的環境越多,就要有管理流程。
    2. 實際上 APP 的部署第一關應該是 QA 要把關,這概念在 “DevOps 8 字環的誤區:左環問題“ 有深入說明。

理想 Config 實踐流程有以下的循環:

  1. 設計優先 (Design First): 系統設計的時候,#TechLead 必須把關規格
  2. 持續迭代 (Continuous Iteration): 每次更版都要做適度的調整與迭代
  3. 管理政策 (Management Policy): 也就是每次的更版要遵守的規範,例如 Key 的 增刪改 各自需要應對的措施
    • 這些規範背後需要技術支撐,像是 Config Migration 機制與流程

2. 現象:DB Schema 很複雜

DB Schema 很複雜 (或者很亂),其實背後本質是跟 Config 一樣的問題。

DB Schema (這裡指的是 Ralation DB, 不是 NoSQL) 一樣是要經過設計與收斂,透過迭代 去蕪存菁精煉。資料結構的設計難的是在初期 判斷預測 判斷資料溫度在未來的變化性,因為很難一次到位,所以通常都要透過以下方法:

  1. 設計階段 Tech Leader 需要把關 DDL 的設計
  2. 持續小部分的迭代與改進,調整資料溫度的配置,例如:
    1. 原本判定是 熱資料,後期變成冷資料,那應該就要設計 Archive 機制,轉入 OLAP
    2. 原本是以為是 冷資料,變成溫資料,那就要透過快取緩存改善
    3. 原本是以為是 熱資料,上線後發現根本沒有存取,所以要改成冷資料,或者一次快取。
  3. 規劃每次更版 DDL / DML Migration 機制與流程

這些都是透過 持續迭代 改善出來的,會越來越亂,都是因為 沒有持續迭代、或者 經驗不足能力不夠 造成的。經驗與能力我覺得找到適當的人就可以了,難的是專案管理過程中,沒有持續迭代,這也是普遍公司的問題。

看到這裡,不難發現, Config / DB Schema 的處理與管理手段是一樣的。

3. 現象:Infra 很複雜

再來談談 Infra 的部分,其實也是一樣的。

通常一個應用程式起來,都會有相應的依賴,常見的有:

  1. Database (RDB / NoSQL): MySQL / PostgreSQL / MongoDB / DDB … etc
  2. Cache: Redis / Memcached
  3. Queue: RabbitMQ / SQS
  4. Storage: File System / Object Storage (S3, GCS)

上述的排序:Structure to Non-Structure

這些東西,通常難的都不是建立 (Provisioning) 起來這件事情,因為這年代有 docker / container 這個技術,通常只要 config 講清楚,不會太難。上面列的最難的大概只有 RDB (Relation Database),因為他有 DDL 需要做 Migration,這個會稍微難一點。現在很多 ORM 都有對應的方法與策略,概念從 RoR (Ruby on Rails, 2008) 年代就有了,基本概念就是可以做到持續更迭 DDL。所以最難的沒了。

其他不管是 NoSQL / Cache / Queue / Storage …. 都談不上難。

  • NoSQL 本身就是沒有 DDL Migration 的問題,因為這東西本身就是 Non-Schema 的。
  • Cache 通常就是一些 Key / Value 的操作,所以只要知道 Key 的定義與結構即可
  • Queue 是通道的概念,大部分只要把通道規則弄好就好,一次性的。
  • Storage 目錄結構,不管是 Object Storage or Block Storage,搞懂目錄結構即可。

很多人想問,像那些 Replication / HA / Cluster 不是很難嗎?

這時候我會先分清楚目的性:Functional Test or NonFunctional Test

如果前者,基本上,不用考慮這些是。如果是測後者,才需要考慮這些事情,看你自己的 R&R。後者通常跟 架構 很有關係,因為 前述的 (HA, Cluster … ) 很多都跟 Reliability 有關係,可靠度本質就是工程 / 架構 要面對的問題,這才是真正的難。

相關概念參閱以下的文章:

除了這些,可能還有其他像是 Networking, Platform (K8s) 的依賴。


問題背後的問題 (Problem Behind Question, PBQ)

很雜亂?很難?

上述的東西,都很雜,談不上難,但是時間只要越來越久,就會由雜變成難。更多參閱: “問題的難與雜

只要有遵循前述的設計原則,持續迭代,給一台 Linux,足夠的 CPU / Memory / Disk,應該沒什麼做不到的。

去看看外面 Open Source ,我沒看過有哪個說一定要 K8s / AWS / GCP 才能安裝的?

我把問題歸類為:

  1. 設計問題
  2. 能力問題
  3. 執行力

對於 QA 而言,我自己親身經驗,裝軟體這件事情,只要上述條件具備,剩下的都是指日可待的問題。所以這問題,最後我的回答都是一樣的:

如果你覺得很複雜,那表示不夠熟悉;如果覺得很難,那代表基本功不夠紮實;如果覺得很亂,那大多都是管理問題。

團隊的問題

而蓋環境背後也可以看出整個開發團隊的問題:

  1. Backend 開發人員都覺得蓋環境難,表示不了解整體架構與對外依賴配置
    1. 有很多依賴問題:
      1. 例如強依賴於 Cloud Services,像是 AWS S3 / Secret Management,卻沒有做適度的設計。
      2. 像是用了 EKS 的 IRSA,或者 AWS IAM Role,就以為一定要 AWS 應用程式才能跑,其實這些都是不了解運作原理,以及沒有適度設 Config 造成的。
    2. 時間久了,導致連開發人員自己都蓋不起來,就連一些 Sr. Engineer 都搞不定。
    3. 沒有適度切割顆粒度,導致 Config 隨時間增長,複雜度過高。
      1. 切割顆粒度背後代表著要重構,一個 Method 有一千行,通常就要拆分職責。
  2. 太過依賴於所謂的 自動化,而自動化的程式本身的品質堪憂,導致部署難度越來越高。
    1. 只有寫自動化的人大概知道整個架構是怎麼一回事
  3. Config 的資訊只有開發人員知道,其他 (QA / Ops) 都不知道
  4. 蓋環境這件事情,在團隊裡是一個天方夜譚的 #能力

所以,得到結論:

蓋環境這件事情不可能
需要動用很多團隊

上述問題,在越有歷史、越有規模,但不注重軟體工程的公司,越容易發生。

翻譯:很多 (九成九) 公司都有這樣的問題。

怎麼解?

做好該做的基本功,只要想省略、或者用自動化掩蓋的念頭,時間越久會越雜。 OOP 之所以會出現,是因為 早期程式發展到複雜度而產生,而 OOP 背後的本質就是持續的分類與重構。

問題提到的 Config / DB Schema / Infra 其實都是要持續設計與改善的。不是只有自動化就天下太平,自動化只會粉飾太平。

公司已經 Run 一段時間 (>3y) 了,怎麼辦?這時候只能請 扁鵲 出場開刀了,不用懷疑,任何想要走捷徑的方法,最後一定死路一條。該開刀,就要開刀,沒有特效藥。

QA 需要自己蓋環境嗎?

QA 的職責之一是發現問題。

發現問題這個過程,背後代表要能證明 症狀 (Symptom) 真的是一個 問題 (Problem)。如果已經是問題了,那麼一定能夠提供完整的重現步驟 (Reproducable),有相關的證據,像是 Log、Config、Data …. 等。這個過程本身是非常講究科學方法的,

當掌握環境建置的時候,上述的過程才能夠有效地掌握,也才能找出有意義的 Defect。

對我來講,蓋環境,是 QA 的第一個條件,這段在 “Software QA 的職能條件“ 的技能段落排第一位。


延伸閱讀

Facebook 隨筆



Comments

  • 全站索引
  • 關於這裏
  • 關於作者
  • 學習法則
  • 思考本質
  • 一些領悟
  • 分類哲學
  • ▲ TOP ▲