蓋環境很難?是這樣的嗎?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

2022/09/25 11:08:00





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