只有累積,沒有奇蹟

顯示具有 Architecture 標籤的文章。 顯示所有文章
顯示具有 Architecture 標籤的文章。 顯示所有文章

2025年12月25日 星期四

[meetup] DevOps Taiwan Meetup #74 《建構多租戶 SaaS 架構》新書導讀

議程介紹
主題 : 《建構多租戶 SaaS 架構》新書導讀
《建構多租戶 SaaS 架構》新書導讀

課程大綱
▋ 從單體到多租戶:是升級還是修羅場?
  「從單體轉向多租戶」——你以為這是一場升級,結果它往往是一場墜落。
  一個讓系統變複雜、讓工程師變沉默的坑。
  剛開始以為只要多加一個 TenantId 就能搞定,
  結果查詢變慢、資料變亂、部署變痛,成本更是像記憶體洩漏一樣,一旦開始就難以回收。
  每解一個問題,就會掉進另一個坑——
  效能解了,卻出現租戶干擾;
  資料分開了,Migration 又成災;
  部署自動化了,成本卻無法對齊。
  本來以為自己能從從容容、游刃有餘地打造架構,
  結果變成匆匆忙忙、連滾帶爬地追著 bug、救著火。
  那一刻你會明白,這條路不是升級路線,而是一次又一次的試煉。
  你寫的不只是程式,而是一連串的補丁與懺悔。
  查 log、修腳本、追異常成為日常;功能開發成了奢侈。
  你以為自己在救火,但其實你正在為系統的複雜度繳學費。
  當團隊的焦點從「創造價值」轉為「維持穩定」,
  工程師也從「開發者」變成「問題管理員」。
  你才真正理解——
  → 多租戶不只是架構上的挑戰,它更是團隊心理韌性與工程紀律的考驗。
▋ 從坑到結構的覺醒
  當你從坑裡爬出來回頭看,你會發現這些問題早已不是偶發事件,
  而是每個 SaaS 團隊都得面對的共同考題。
  這也是《建構多租戶 SaaS 架構》真正想帶你看見的現實:
  → 多租戶不是一種部署方式,而是一場關於效能、資料、維運與成本的修行。
  理解這四件事,才是真正邁向多租戶成熟的起點。
一、效能:不只是跑得快,而是信得過
  如果你曾被客戶問過:「為什麼今天比昨天慢?」
  那你就知道效能不只是技術問題,而是信任問題。
  在單體架構時,你只在意系統跑得快不快;
  進入多租戶後,問題變成——誰讓誰變慢了。
  A 客戶開了一個報表,B 客戶就開始卡頓。
  這不是 bug,而是「Noisy Neighbor」的現實。
  → 效能不只是數字,而是一種信任契約。
二、資料架構:風險與效率的對話
  每一個架構師都會面臨這個靈魂拷問:
  要不要共用 Schema?要不要分庫?
  這些看似是技術問題,其實每一個決策背後都是風險選擇。
  共用架構代表成本低,但錯誤可能牽連所有租戶;
  獨立架構代表安全,但維運與版本控制的成本將倍增。
  → 架構沒有完美的答案,但成熟的團隊懂得在風險與效率之間,
  找到能讓產品長久運行的平衡點。
三、維運:從部署變成節奏
  當部署頻率越高、租戶越多,
  每一次上線都像踩在一個尚未確認的地雷區。
  單體時,部署只是動作;
  多租戶後,部署變成節奏。
  一次上線,影響所有租戶;
  你開始需要灰度釋出、分群升級、即時回滾。
  這不再只是 CI/CD 的自動化,而是整個團隊如何定義「穩定」的制度。
  → DevOps 在這裡不只是流程,而是一種信任治理的文化。
  維運,不只是穩定系統,而是穩定人心。
四、成本切分:從效率到價值的覺醒
  如果你曾在帳單前皺眉,
  你就知道多租戶最難的,不是效能,而是「看不見的成本」。
  A 客戶每天跑十次報表、佔滿資源;
  B 客戶只上傳一份 Excel,卻付相同的錢。
  久而久之,你會發現 SaaS 的瓶頸不在 CPU,
  而在於成本缺乏對應與衡量機制。
  沒有清楚的成本映射,團隊就只能憑直覺調整。
  真正成熟的架構,不是壓低成本,而是讓成本與價值產生對應。
  → 那不只是技術能力,而是經營能力。
▋ 從效能治理到價值治理
  在雲端時代,SaaS 不只是技術選擇,
  更是一種產品與營運思維。
  《建構多租戶 SaaS 架構》就是你的解藥。
  本書由 AWS 資深架構師 Tod Golding 撰寫,
  他以多年協助 SaaS 團隊轉型的實戰經驗,
  總結出多租戶設計、部署與營運的完整方法論。
  那些讓你掉坑的問題,書中都有出口 
  ・第 09 章〈租戶隔離〉:如何避免 Noisy Neighbor
  ・第 08 章〈資料分區〉:在共用與分庫間找到平衡
  ・第 12 章〈租戶感知營運〉:建立租戶級的監控與自動化
  ・第 14、17 章〈分級策略/指導原則〉:讓架構、營運與商業模式對齊
  Golding 在書中不斷提醒我們:
  SaaS 的本質不是「上雲」,而是「統一思維與多樣彈性之間的平衡」。
  從第 01 章〈SaaS理念〉到第 17 章〈指導原則〉,
  他帶領讀者看見 SaaS 架構不只是技術結構,
  更是一種願景、策略、組織與營運文化的總和。
  如果你還不懂多租戶,這本書會帶你從 0 到 1。
  如果你正陷在坑裡,這本書能讓你少走幾年冤枉路。
  如果你已撐過那些坑,這本書會幫你整理經驗,帶領下一個團隊走得更穩。

主辦單位 : DevOps Taiwan 技術社群
議程表 : 連結
投影片 : 連結



2022年5月1日 星期日

[Architecture] 架構設計 - 限流策略 Rate Limiting Strategies

前言
這一篇是紀錄閱讀 超大流量分佈式系統架構解決方案:人人都是架構師2.0 的讀書筆記,筆者在書中有介紹在面對大流量的請求洗禮時,常見的手段有以下幾種方式
  • 擴充
  • 靜態化
  • 限流
  • 緩存
  • 隊列
這篇文章是介紹上述方案中的限流方案章節筆記,在整理時內容加上自己理解的說明與圖片,其中若是自己有理解不正確的地方是錯誤的部分歡迎各位高手一同討論或給予指導


為什麼需要限流
大型電商網站主要技術挑戰可能來自短時間內客戶忽然的大流量與短時間內的高併發請求,像是之前大家在搶購的 Switch 動物之森主機(搶三次都沒搶到 怒),或是最近吵得很紅的 PS4 造型悠遊卡(搶不到again,怒怒),如果系統不對流量進行合理的管制,任意地讓所有的請求流量在短時間內衝擊系統,可能會導致一連串的問題發生,像是原本設定的 cache 機制因為超過負荷被撐爆、主機連線資源被耗盡,資料庫要處理大量的請求而造成回應時間變長,最後系統很有可能發生雪崩效應(Avalanche effect),造成服務的中斷。任何一個系統的容量都存在著上限,一旦用戶請求量過載超過上限,系統的吞吐量便會逐漸開始下降,流量管制的目的是保護系統,讓系統的負載壓力處於一個比較均衡的水位,有效的管理峰值的請求量。 從上圖可以得知,當處理大量的請求時前面可以使用 CDN (靜態資源),FrondEnd 或是 Backend 可以使用擴充的方式來承接更大的流量請求,但資料的異動最後還是會交由資料庫來進行處理,Database 數據庫的連線是一個非常昂貴且數量有限的底層資源,為了避免開發環境下連接數超過數據庫所能乘載的最大上限,合理的運用資料庫的連線池技術,確保系統在高併發時連接數不會超過資源的水位值(資源閥值)。

常見限流演算法
書中介紹常見的限流演算有令牌桶算法、漏桶算法以及計數器算法三種,以下就針對這三種作簡單介紹

令牌桶算法
令牌桶(Token Bucket)算法在 wiki 說明敘述如下
每 1/r 秒會新增一個令牌(Token)到桶(bucket)中
桶(bucket)中最多可容納 b 令牌。如果桶已滿時則丟棄該令牌(Token)
當傳送 n bytes 封包時,桶(bucket)中如果有 n 個令牌(token >= n),封包將會送至網路
當可用的 token < n 時,不會從桶(bucket)刪除任何 token,該封包會被視為不合格的

圖片來源 https://gateoverflow.in/39720/gate2016-1-54

令牌桶算法的原理是會以固定的速度將令牌(token)放入桶(bucket)中,當要處理請求時首先會先到桶(bucket)中取得是否有足夠的令牌(token),當桶(bucket)中的令牌(token)用完時則拒絕服務。

從上述原理可以得知桶(bucket)的容量大小就是系統的最大併發數;可能的瓶頸是令牌桶算法中會有一個執行緒專門在產生/更新令牌(token)數,如果要在很短的時間內要產生大量的令牌數量的話會消耗系統 CPU 資源,舉例來說如果需求是每 1ms 就產生一次 Token 數量,該執行緒就會頻繁的佔用系統 CPU 資源來產生需要的 Token 數量,關於更多令牌桶算法的討論可以參考此討論串 GATE2016-1-54,裡面有更多詳細關於該算法的速率解說與範例算式說明。


漏桶算法
漏桶(Leaky bucket)算法在 wiki 說明敘述如下
請求進入漏桶(bucket)裡,桶(bucket)容量是固定的
當桶(bucket)中的水量(請求)為空時,則不在流出水滴
流出水滴的速率為固定的,桶(bucket)滿了則會溢出


圖片來源 https://developpaper.com/rate-limit-scheme-of-gateway/

漏桶算法的原理較為簡單,水滴(請求)進入漏水桶(bucker),漏水桶流出水滴的速度為固定的,當水滴進入水桶的速度太快時就直接溢出。漏桶算法提供的機制是限制流量數據的流出速度,且流出速度是持續保持固定的。

上述是介紹 Leaky bucket 中的 meter 版本,在 wiki 中還有另外一種是 queue 版本
水滴(請求)進入漏桶(bucket)裡,桶(bucket)容量是固定的
當超過桶(bucket)容量限制時,排隊或者被丟棄
桶(bucket)流出水滴的速率為固定的



計數器算法
計數器算法算式最單純的限流算法,應用層面相當的廣泛,原理如下
在單位時間之內由一個計數器專門負責計算,當新的請求來的時候會與閥值(水位)進行比較,當請求數達到閥值或水位時,便會觸發限流機制的邏輯。
舉例來說,假設限流策略為每分鐘為 5 個請求數,每請求一次計數器便會遞增加一,單位時間內計數器與限流閥值相等時,後續的請求將會被執行限流處理,當單位時間過後計數器便會進行重置的動作,新的請求才可以繼續訪問,示意圖如下



漏桶算法 v.s 令牌算法
從本質上來看兩者算法都可以用於高併發與大流量的場景下進行流量管制,不會因為瞬間的大流量而讓系統被打爆。但需要注意這兩者的現流方向是相反的,令牌桶(Token Bucket)算法限制的是流量的平均流入速率,並允許一定程度上的突發狀況(大流量);而漏桶(Leaky bucket)算法限制的是流量的流出速率,而非流入速度,這種流出速度還是保持固定不變的;令牌桶算法的極限可能會是桶的容量加上生成令牌處理程式的最大併發能力。

HTTP Status
上面提到了一些常用的限流算法,接著來看 HTTP 協定中有提到定義當達到限流機制的 Status Code 代碼,在達到閥值(水位)值時,開發者可以使用 429 Too Many Request 告訴呼叫端(用戶)特定時間內發送太多的請求,並在 Response 中說明觸發條件的詳細訊息,以及多久後可以再進行重試(Retry-After),範例如下
HTTP/1.1 429 Too Many Requests
   Content-Type: text/html
   Retry-After: 3600
   
   Too Many Requests
   I only allow 50 requests per hour to this Web site per
   logged in user.  Try again soon.     
   

ASP.NET Core 實現限流策略
身為一位不專業的工程師,上面介紹這麼多之後當然也要介紹在 ASP.NET 好用的限速策略 Library 其中比較推薦的是 AspNetCoreRateLimit 套件,使用與設定上相當簡單,也可以根據不同情境像是 Request IP 或是 Client ID 進行限流的策略,Github wiki 介紹頁面如下

以上若有問題歡迎一起討論,或是有錯誤的地方也請高手大大們給予指導予糾正,謝謝


參考
Rate limiting
Scaling your API with rate limiters
High-performance rate limiting
An alternative approach to rate limiting
Leaky bucket
Rate limit scheme of gateway
流量调整和限流技术
rate limiting 之 leaky bucket
想通关「限流」?只要这一篇

2020年10月3日 星期六

[筆記] 《知行》: 技術人的管理之路

前言
這一篇是紀錄閱讀 《知行》: 技術人的管理之路 的讀書筆記,這本書是參加 TGONetwork 所舉辦的 TGONext - TGONetworks 導師計畫 成果發表會導師 Taien 所贈送的,能夠拿到導師所贈送的書自己也有點意外(當天上台分享時蠻掉漆 XD)。這半年來工作上寫 Code 的時間越來越少花很多時間都在與團隊同仁溝通,在規劃新項目或是簡報時不是那麼的流暢(得心應手)似乎總覺得少了什麼,因此決定靜下心來好好的把導師所贈送的書了解一番,才不會枉對導師對我的期待(自以為?)。這篇文章僅介紹第一章節 : 管理路口的徬徨,整理可能當開發者要轉換成技術管理職可能會遇到的一些問題,其中若是自己有理解不正確的地方是錯誤的部分歡迎各位管理大神一同討論或給予指導

工程師發展路徑
在書的一開始,作者提到過去有一群從 2005 年開始工作的工程師好友們,在某次聚會中整理這些好友目前的職務可以分為幾大類 (作者為大陸人,書中內容可能會因為場景或是地區不同有所差異)
技術類 : 架構師、技術專家
管理類 : 技術管理者、職業經理人
創業類 : 創辦人、技術合作者
顧問類 : 投資顧問、管理顧問
可能隨著能力的提升可以做的事情越來越多,提升架構能力後轉為架構師;或是專案管理及帶團隊能力越來越強,逐漸轉為技術管理者;有很好的想法想要做自己的一番事業,成為創業公司的技術合夥人;書中提到特點之一是 10 年後堅持做技術比例的只剩 20% 左右 (沒有一定,最自己而言做自己最喜歡與認同的角色即可)。不管是走上述哪一條路,有些基本能力可能會是通用的,像是規劃、帶人、管理、溝通及執行能力,也可以說是環繞著技術與管理這兩條路在走,只是不同職務所面臨與擔負的責任不同。

我到底要不要做管理
作者常常被工程師問到我適不適合做管理?您對我有甚麼建議,作者則會反問工程師幾個問題
做管理對您來說意味什麼? 您覺得它能給您帶來什麼
希望可以透過此問題來讓提問者去了解到做管理的初衷,而非直接透過回答的方式取得答案;如何審視管理對您來說是不是真愛呢,可以透過三個問題幫自己做判斷
您是否認同做管理的價值 ? 
您是否對管理充滿熱情 ? 並享受這些工作呢 
您是否看中在管理方面的成長呢 ?
管理與技術的挑戰不一樣,常常會需要接觸很多雜事像是面試、團隊溝通、規劃流程、與主管匯報、資源協調與績效評估等各式各樣的管理工作,與開發工作相較之下項目較多且較為雜亂,可能也很難從中獲得成就感與價值,如果不認為管理是有價值的可能較難持久下去,可能會有覺得寫代碼較為單純的念頭出現。但從另一個角度來思考,過去在開發可能只要做好主管交辦的項目即可,但轉做管理為了要帶領整個團隊前進,就須思考上級、同一層單位、下級各方面的期待與訴求,要求自己用更全面的角度來思考問題的解決方式,這些挑戰也會替您帶來成長,成就感與影響力。

我要不要轉回去做技術
俗語說《人窮則反本》,當人們遇到挫折就會想回到老路上。作者提到在訪談的 2/3 的新技術經理,都有類似的擔心跟問題,問題像是做了管理之後沒時間寫Code,覺得離本行越來越遠;不知道在管理與技術中如何取得平衡,兩者兼顧;管理工作瑣碎,技術越來越少接觸覺得心虛;因為技術人員常常會專心在代碼或是某些技術上,但對於職業生涯思考方向算是被動,可能不是主動的或是被動推到經理的位置上,過去沒有經驗且可能對管理沒有深入的了解,初期在不熟悉的情況下可能感到慌張或焦慮;或是覺得 技術才是自己的根本,在面對上述問題,作者提到親自寫代碼是很好的實現方式,但作為管理者必須要掌握更多的技術,快速判斷該如何搭配使用,所以必須有更高效的學習方式,建議如下
建立你的學習機制 : 思考團隊內可以建立甚麼樣的學習機制,可以借助團隊的力量提升技術判斷力,也讓團隊能力提升。
請教專家 : 借助平台找到該領域專家大神進行請教,能成為某領域高手都有深厚的知識累積,且能用簡單精準的說明讓人容易明白與了解。
共創 : 對於知識型工作者來說,和大家共創所收穫的成功,比自己埋頭思考高效許多。
如果您對技術充滿著熱情,目標是成為一位優秀的架構師的話,做管理所累積的能力是完全可以遷移到架構師上,在管理上所具備的全局視野、規劃能力、結果導向、專案規畫及溝通與協調能力,這些都是優秀的架構師必須具備的條件之一。其次,不管是做技術管理或是架構師角色,看事情的角度都必須從 High Level 的角度來思考,建議如下
從目標出發看待技術 : 目標明確,才可以選擇最佳的技術方案,做出最合理的技術決策。
從評估角度看待技術 : 必須清楚了解技術方案是透過哪一些維度來評估好壞優劣,當技術問題暴露出來時會造成甚麼影響,損失的邊界為何 ? 
從依靠自己技術到借助大家的技術 : 要熟悉團隊每位成員的技術情況,知道誰可以勝任做什麼事,適合做什麼,借助大家的技術去做事
即便做不好也不是沒有回頭路,在轉作技術管理者時離技術很近,如果嘗試下來認為管理工作確實不是自己想要的(天命),那麼回頭繼續做工程師是幾乎沒有門檻的,但前提是自己必須先全力以赴的去嘗試一段時間,盡全力的去做一件事之後才不會有遺憾,才可以知道自己到底適不適合做技術管理的工作。

如何保持技術競爭力
如何保持技術競爭力是自己最感興趣的議題,在轉型技術管理者之後,自己可以支配與寫代碼的時間會越來越少(最近感觸很深阿),書中提到當你的角色從《技術實現者》轉變為《技術管理者》時,與技術的關係就發生了變化,過去開發者對技術的追求可能是以《技術實現者》的角度出發,但現在是轉變為技術管理者的角色,對於技術能力這詞也就悄悄的開始轉變,應該以技術應用者的角度出發,技術評估能力變得為其重要,要關心與思考的是 why & what,也就是要不要做這件事以及這是件什麼事情?並在綜合評估之後做出決策與判斷。
那麼如何精進技術判斷力就會是一個重要議題,作者提到技術評估有以下三個維度

維度一 : 技術項目結果評估
在決策要不要做一個事情時,需要回答三個問題
這究竟是件什麼事情
希望得到的結果是什麼
要用什麼角度/維度衡量結果,從那些技術指標去驗收結果
有個目標與希望預期得到的結果,才可以有始有終的做出準確的判斷與正確的決策,舉例來說
  • 可能為了要提升服務穩定性,去調整服務架構
  • 可能為了提升數據的準確性,去改寫技術數據的收集流程
  • 可能為了提升系統效能指標,去調整數據庫效能讀寫模組
像是希望提升系統性能,如何衡量結果是否有提升? 要用甚麼技術指標來進行衡量? 如果結果無法衡量的話,我們如何判斷這件事是做得好或是不好,因此,技術管理對於技術項目結果的評估能力最為重要。

維度二 : 技術可行性評估
可行性有兩層涵義,分別是 能不能做值不值得
  • 能不能做 : 是指有沒有能力做到,這是能力問題
  • 值不值得 : 是指能力允許,全力投入之後的結果是否是值得的(效益),這是選擇問題
在不懂技術管理的管理者一般提問的是 能不能做,有經驗的技術管理者與資深工程師則考慮的是值不值得,另外還需要考慮成本與收益部分。 那麼通常的技術項目,都有哪些成本需要考慮的呢
投入的資源成本
技術維護的成本
- 技術選型成本
- 技術升級成本
- 問題盤查成本
- 代碼維護成本
機會成本
協作成本

維度三 : 技術風險評估
技術風險評估也叫技術風險判斷,也就是有哪些技術風險需要未雨綢繆,該技術方案帶來最大的損失的可能性是什麼,以及在甚麼情況下會發生。舉例來說,為了降低 DB Loading 可能會加上像是 Redis 的 cache 機制,在使用時可能要思考當快取發生異常時,快取 Server 重啟因為沒有對應的快取資料,這時請求全部都跑去訪問資料庫,可能會造成快取雪崩或是快取穿透的狀況發生,這時候的解決方案或是甚麼 ? 要如何防範以及團隊同仁要如何解決,這些都可能是上線後可能會遇到的問題。風險評估考驗技術管理者的技術經驗與風險意識,經驗越豐富則對風險的判斷也就越敏銳。去拓展技術視野與技術判斷力常見方式如下
建立技術學習機制
專項技術調研項目化
與技術專家交流
聽取工作匯報
另外,你不是一個人在戰鬥,因此風險評估上也需要借助團隊的技術力量做出準確判斷,並非只靠技術管理者的技術判斷力,能從周圍人群學到多少訊息與資訊,而不是在靠自學。
核心是在如何提升技術實現的能力,轉變為提升技術判斷力與技術評估能力,有些管理者擔心自己一旦不是團隊技術能力最強的人,會因此有團隊成員不服氣,但從另外一個角度來看,管理者的職責是帶領團隊高效的交付高質量的產品與系統上,隨著年紀的增長,團隊中比你優秀的人才會越來越多,是一種好的現象,如果多年之後你依然是團隊裡技術最強的一員,可能不是一個好的現象。

...To Be Contined

心得
這篇文章僅介紹第一章節 : 管理路口的徬徨的部分,擔任開發人員也有10年的時間,其實在最近幾份工作主管都有建議可以嘗試往技術管理的路前進,但由於自己認為技術能力還尚未到一定的水準所以都不小心選擇逃避帶過,趁這個中秋連假期把該有的基本知識給惡補一下,光閱讀第一個章節就感觸蠻深的,提到過去自己很多深藏在心中已久的問題,其中也提到在不懂的知識下要找專業人員求助,這也讓我想到與前主管常提到的人脈的重要性,平常就需要累積人脈與研討會會認識一些技術愛好者,當你工作遇到問題時就會透過這種方式向大神們請教相關問題,當然態度方面是很重要的(別人也不是一定要回答你,回答問題也是需要時間成本),因此這點也是需要格外注意,雖然書還沒完全看完但已經有不少幫助,希望日後還有時間可以繼續下去。

參考
《知行》: 技術人的管理之路

2020年9月9日 星期三

[Architecture] The 12 factor App 筆記

前言
最近在與同事一起規劃新系統的架構,在整理相關文件時想起參加前公司 Techday 由新加坡同事提起的 The Twelve-Factor App 方法論,提出此方法論的作者參與了超過一百個專案開發與部署,並透過 Heroku 平台見證了數十萬個應用程式的開發運作以及擴展的過程,整理了在 SaaS (Software as a Service) 開發時需要理想的實踐標準,方法論主要內容如下

Use declarative formats for setup automation, to minimize time and cost for new developers joining the project;
Have a clean contract with the underlying operating system, offering maximum portability between execution environments;
Are suitable for deployment on modern cloud platforms, obviating the need for servers and systems administration;
Minimize divergence between development and production, enabling continuous deployment for maximum agility;
And can scale up without significant changes to tooling, architecture, or development practices.
其中提到此方法論是不限定語言與後端服務開發的應用程式,因此這篇文章就來介紹關於 12 個方法論的一些重點項目,若有理解錯誤或是異常的地方歡迎隨時提出討論。

介紹
【文不如圖,圖不如表】再多的文字都比不上一張清晰的圖讓人容易了解,因此在一開始先 PO 出在網路上找到有關 12 factors 的小抄表,讓有興趣的朋友對於整個方法論有更清楚的 overview
接著,再來逐一介紹每個方法論的內容 備註 : Puppeteer 是 Playwright 的前身,其 API 與核心概念都很相似。

Codebase
一份基准代码(Codebase),多份部署(Deploy)
  • 使用版本控制系統來控管代碼,像是 Git、Subversion 等常見的版本控管工具
  • 一份用來追蹤代碼所有異動版本的數據庫被稱為 代碼庫 (code repository, code repo, repo)
  • 基準代碼指的就是這一份代碼庫,如果是 Git 分布式版本控制系統,基準代碼就是最上游的代碼庫。
  • 基準代碼與應用(Aplication) 是保持一對一的關係。
  • 在不同的環境會對應到同一份代碼庫,每個部署可能會使用到不同的版本

Dependencies
清楚的定義依賴關係(Dependency)
  • 應用程序不會隱式依賴系統級的類別庫,透過依賴清單清楚定義所有依賴項目
  • 透過依賴隔離工具來確保不會調用不存在的項目,此做法在 Production 與測試環境皆是如此
  • 為新的開發者簡化環境配置的流程,只需要透過建構指令 (build command) 即可安裝其依賴項目,即可開始工作
  • 舉例來說,在 Ruby/Bundler 就是透過 bundle install

Config
將 Config 定義在環境變數中
  • 代碼(Code)與配置(Config)嚴格分離
  • Config 在不同環境分別各自定義,代碼是一致的
  • 推薦將應用程式的配置定義在環境變數中 (Env vars, env)
  • 環境變數可以很方便的在不同環境修改,不用異動到代碼 (Code)與語言也無關
  • 舉例來說,與第三方介接時所需要的 Token,在與 DB 建立連線時需要的連線字串 Connection string

Backing Service
將後端服務(Backing Service)視為附加資源

  • 應用程式(Application)不會區別本地或是第三方服務
  • 對它來說兩者都是附加的資源,透過某個 url 或配置的服務定位 (locator/credentials) 來取得數據
  • 也可以在不用異動代碼的情況下,將本地 MySql 資料庫換成第三方服務(ex:Amaxon RDS)
  • 每個不同的後端服務都是一份資源(resource),這些資源與其附屬的部署保持鬆耦合(loose coupling)的關係

Build, release, run
嚴格分離建構與運行

  • 嚴格區分構建,發布,運行這三個步驟
  • 直接修改運行中的代碼是非常不可取的行為
  • 每次發布都要對應到唯一個發布ID,例如可以使用發布時的時間戳記 2020-09-10 22:33:44
  • 發布的版本一但發布就不能修改,任何代碼的變動都應該產新的版本
  • 備註 : 小弟公司是使用 Git commit 的 hash 值,方便盤查

Processes
使用一個或多個無狀態的 Process 運行
  • Application 的 Process 應該是無狀態且不能共享的(share-nothing),
  • 任何像是需要持久化的數據都要存在後端服務中,像是數據庫
  • 一些互聯網系統過度依賴於 session (sticky sessions),這在 12-Factor 是極力反對的,
  • Session 數據應該保持在像是 Memcached 或是 Redis 有帶過期時間的緩存中

Port binding
通過端口綁定( Port binding )來提供服務
  • 通過端口綁定(Port binding)來提供服務,並監聽發送至該 Port 的請求
  • 不僅限於 HTTP 服務

Concurrency
使用 Process Model 進行 Scale Out

  • Processes are a first class citizen
  • 開發人員可以運用 Unix process model for running servuce daemons,將不同的工作分配給不同的類型 (Process Type)
  • 舉例來說,HTTP 請求可以交給 Web 進城來處理;常駐的後台則交由 worker 來負責
  • Process 應該 stateless 和無分享的,方便進行擴充

Disposability
通過快速啟動和優雅關機,實現穩健性最大化
  • Processes 是可以瞬間開啟或是停止,易處理的 (disposable)
  • 追求最小啟動時間,理想狀態當輸入啟動指令到等待請求應該只需要很短的時間
  • 更快的啟動時間提供敏捷的發布與擴展,容易將 Process 容易的搬移到新的物理機器上
  • 收到終止信號(SIGTERM)就會優雅的終止,也就是停止監聽服務的 Port 拒絕所有的請求然後退出

Dev/prod parity
盡可能保持開發/測試/正式環境相同
  • 想做到持續部署應該縮小本地與線上的差異
  • 縮小時間差異:開發人員可以幾小時,甚至幾分鐘就部署代碼。
  • 縮小人員差異:開發人員不只要編寫代碼,更應該密切參與部署過程以及代碼在線上的表現。
  • 縮小工具差異:盡量保證開發環境以及線上環境的一致性。
  • 開發人員應該反對在不同環境使用不同的後端服務,降低使用上的差異以及突然出現的不相容問題

Logs
把日志當作事件流
  • 應用程式不應該煩惱 logs 存放位置,統一使用 stdout 直接輸出
  • 這些事件流可以輸出至文件,或是在終端實現觀察的
  • 輸出流可以發送到 Splunk 諸如此類的日誌索引及分析系統

Admin processes
後台管理任務當作一次性運行
  • 開發人員有可能會執行一次性的管理或是維護的一次性任務
  • 執行資料轉換
  • 執行控制台(REPL Shell)
  • 一次性管理程序應該使用相同的環境,並使用相同的程式碼跟配置


感想
以上針對 The 12 Factor 做了基本簡單的介紹,但在實務上某些部份可能實現的難度較高,舉例來說像是 Dev/Prod 環境要一致的要求,現實上可能會遇的問題是開發環境的 Server 已經包含 feature A,但在未驗證完全的情況下可能會也不會更新到正式環境;每一個原則都是開發與運維同仁在開發時需要注意的部分,日後有機會設計新架構或是既有系統調整時可以做為參考的準則之一,以上如果有不清楚的地方歡迎一起討論,謝謝 !

參考
12 factor

2020年5月17日 星期日

[筆記] TGONext 架構組 - 資料庫 Migration 及軟體架構的演進

前言
這一篇是紀錄參加 TGONext - TGONetworks 導師計畫架構一組第三次聚會的旁聽筆記,導師計畫歡迎小組間跨組討論因此自己只要時間允許會參加其他組的討論,參加完後也會整理討論的筆記方便日後回顧,在過去兩個月有參加的架構組筆記分別如下 為了日後讓自己可以更快理解因此整理筆記時有加上自己理解的說明與圖片,其中若是自己有理解不正確的地方是錯誤的部分歡迎各位高手一同討論或給予指導

Database Migration
在這次聚會的一開始同學拋出 Database Migration 的議題,程式碼有版本控制系統,遇到異常狀況時可以找到原本執行正常的程式碼快速進行 Rollback 的動作,那麼資料庫遇到類似狀況要如何 rollback 呢? Ant 請同學分享針對過去的經驗或是解法,可能的解決方案如下
  • 不刪除資料及欄位
  • 保存刪除資料,使用 Trigger 將資料複製到另一個 Table
  • 將要異動的 Table 建立一份 snapshot 快照
  • Rename & Copy
這問題沒有一定標準的答案,導師也提醒需要考慮在特定的法規中需要保留資料特定年限才能刪除,像是在金融業政府就規定交易紀錄須保存五年以上,方便稽核單位進行查核的動作。
導師 : 如果不刪除資料的話,大家覺得會有什麼問題?
如果資料庫有很多非必要資料或是欄位時,如果不刪除的話會占用 disk 或是 memory,在傳輸時會多占用網路頻寬;存放過多 Dirty data,後人在維護時也有可能因為不敢亂刪除資料或是欄位,因而繼續存放演變為技術債,也可能會讓 db 的 loading 越來越高,因此可能會影響到資料庫的效能,為了不影響資料庫的效能處理方式有很多種,常見有兩種方式處理
  • 將沒用到的放置在另一個 Table,如果之後 Database 需要 Migration 時可以將所需要資料移回來
  • 將不需要用到的資料 snapshot,有需要 Rollback 時再將 snapshot 資料回復到原本的資料庫中
Add New Columns
RDBMS 是 row base database,新增一個欄位所需要的時間取決於目前資料量的多寡,如果目前異動的 Table 有兩千萬筆 row data 時,這兩千萬筆資料都需要新增 columns,在 Production 的 Table 新增欄位會有 lock 的情況發生,也就是說可能會有 downtime 的狀況產生,在過去的經驗如果要在核心 Table 進行異動或是 index rebuild 的話,會在網站者使用者相對較少的時間進行停機告知用戶網站正在維修中(Under Maintenance),在交易量大的網站中對於 downtime 是格外重視的,在 PostgreSQL 11 與 MySQL 8 分別都有支援新增欄位不會 Table lock 的方法。
那麼不停機要新增欄位,要怎麼做會比較好呢? 
在 MySQL 有工具可以協助達到此目的 : gh-ost,原理如下 了解運作原理之後,那麼它可能的缺點會是什麼?舉例來說目前資料庫中有些 Table 近 2G 的空間,會進行 COPY Table 資料,可能問題會是 COPY 原有 Table 資料過程中,由於資料量非常龐大此時 Disk IO 會飆高,cpu high或是既有空間會不足的情況發生,這都是使用前需要留意的地方。

Row Based Database vs Column Based Database
在比較 RDBMS 與 NoSQL 的特性時,導師也提到可以從 Row Based Database 與 Column Based Database 的設計進行研究,這方面比較不熟因此列出網路上文章日後有時間拖稿再繼續研究

資料結構 : Tree
接著討論有關 RDBMS 資料庫與 NoSQL 本質上的差異,以及資料庫中的重要觀念 B Tree & B+ Tree,內容相信大家都了解這裡就不在說明,這裡列出幾個自己覺得說明蠻清楚的網站讓大家了解其原理

軟體架構演進
接著回到軟體架構的討論,在上次的討論中有提到 架構的演進,在討論的一開始導師又拋出問題給同學
導師 : 當單機承受不住的時候,為了支持更大的量,你會怎麼做 ? 

  • 機器硬體加大
  • 橫向擴充
  • 服務拆分
  • Cache Server
  • Queue
導師強調演進沒有一定的答案,每個解決方案都有適合他的情境,架構也有各自的瓶頸點,舉例來說選擇使用垂直擴充加強機器的硬體,但升級並不是無限擴充的會有物理的上限問題;如果選擇橫向擴充了100台機器,機器的管理就是一個問題,像是如何將新功能在最短時間佈署至100台機器,佈署策略要如何去定義,分散式系統的問題開始浮上檯面不得不面對;在上次聚會中提到 cache server 可能是其中的一種方法,但是團隊是否有能力可以處理 cache 帶來的問題,要如何處理因為 cache 異常引起的雪崩效應,常用的 cache 有 Redis 與 Memcached 兩種,Redis 相信大家都不陌生,在 Facebook 與 google 仍然在使用 Memcached,導師也請同學們思考看看背後的原因。

擴充方式
  • Scale up : 垂直擴充 (Scale vertically),提升單體 Server 硬體效能,像是增加 CPU 核心數、硬碟換為SSD、升級記憶體 Memory、升及網路卡速度,硬體升好升滿的概念。
  • Scale out : 水平擴充 (Scale horizontally),增加伺服器數量,使用更多機器一起來負擔更多的用戶與 Request 請求數量
  • 但在垂直擴充到某個程度可能會有硬體的物理上限,相對的硬體資源更好的伺服器費用也較為昂貴,
    使用大量硬體較便宜伺服器來實現提升整體效能成本上會來的較為便宜,機器異常時造成服務中斷的風險也比較低。

    Database 擴充
    在 RDBMS Database 相對於 Application 來說,擴充上是較不容易的(不考慮分散式系統或是讀寫分離的情況),如下圖所示

    此是一個簡易的前後端分離架構圖,當用戶透過瀏覽器發送請求到資料庫處理的流程來區分,網路可以透過 CDN 快取加速,前端 FrondEnd 網站與 Backend API 可以透過 local cache 或是 Redis 等快取機制加快處理速度,當 Server 機器數量不夠時可以透過 Scale out 擴充承接更大量的 Request 請求,前面假設機器加到 50 或 100 台 server 能夠應付更大的流量,最後在做資料異動還是需要透過 Database 來處理,由於 RDBMS Database 的特性(Atomicity、Consistency、Isolation、Durability) 注重資料的一致性,因此在擴充上是較難分為多台水平擴充,如果遇到效能的問題需要做擴充大多都會選擇硬體升級方向出發,但是升級都會遇到機器物理的上限無法無止境的提升,因此保護好資料庫變成一件很重要的事情。

    資源的限制
    在架構的選擇中,資源(Resource)也是考量的重點之一,常見的資源有 CPU、Memory、Storage space、Disk IO、Network bandwidth、Network latency 等,請大家思考哪一個項目是覺得比較難擴充的,有人回答 Disk IO,因為 Network 的問題或許可以靠 CDN 去解決,但 Disk IO 可能跟不上 CPU 的速度,大家都提出自己的觀點與看法,接著導師請大家思考
    導師 : 在雲端服務廠商裡面,上述提到的(Resource)有什麼服務是不能選擇的 ? 
    導師提出他的觀點 Network 是無法選擇的,Google 推出 Protocol Buffers 以及 MessagePack 等新的 format 就是為了解決網路傳輸的問題,主要是透過(使用CPU)壓縮的方式讓傳輸資料輕量化,以加快資料網路傳輸的速度,也就是用 CPU 去換傳輸資料輕量化。

    Queue
    導師 : 甚麼時候應該要用 Queue ? 它的特性應該是什麼 ? 
    • 有順序性,存放暫存的請求內容(狀態state)資料
    • 在架構設計上常會用於系統與系統間解偶(Loosely Coupled)
    • 像是非同步,處理完畢的時間不確定 (asynchronous 的缺點都有)
    使用上要注意的是要有(限制) 容量 (memory) 的上限,不能是無限制的使用;另一點要注意的是當 producer 要將請求內容放置到 Queue 的時候,如果遇到 Queue 已經滿了放不進去時該如何處理 ? 遇到 Queue 滿了是否有將 producer 的內容 block 住,保證內容不會因為 Queue 滿了而遺失,但也可能會因此造成連鎖效應,如果發生異常 block 住的數量過多要如何快速地消耗,是否團隊有建立監控機制來預防此狀況發生,與上次討論提到的 cache 相似,團隊在選用前應該了解會遇到的問題及如何解決,才不會在上線後踩雷後無法處理造成業務上的損失。

    Kafka & RabbitMQ
    接著討論到常見的 Queue service 有 Kafka 及 RabbitMQ,分別是使用 Java 與 Erlang 不同的程式語言所開發,分別有各自程式語言的特性,像是 RabbitMQ 預設記憶體超過 40% 時會發出 memory 不足的警告,當 GC (Garbage Collection) 機制回收時會消耗兩倍記憶體量為 80% (50% used memory + 50% Crach memory,確保失敗的記憶體可以復原),這是 Erlang 程式語言的 safe to crash 的特性也是可能在使用 RabbitMQ 必須要注意的地方(缺點);接著談到 Kafka,Kafka 是 Linkedin 開發的 open source,Kafka 快的原因是 Java 有使用 off-heap,off-heap 是 GC 的一種技術,在 Java 有提供 unsafe 基礎類別 API 可以自己去控制記憶體或回收記憶體 (備註1),從效能鐵三角的角度來看 Kafka 是追求高 throughput。

    備註1 : 當 GC 啟動在執行時記憶體回收時,正在進行的執行緒會將暫停直到 GC 回收完畢為止,為了解決內存記憶體過大造成 GC 回收時間過長的問題, JAVA 提供 off-heap memory,將記憶體放在 heap 中將控制權交由作業系統處理,(感謝 Ant 大協助 Review & 糾正)

    心得
    過去曾經在面試中被問到 RDBMS 與 NoSQL 如何選擇,自己當時回答得七零八落,但經過這兩次小組的討論陸續有講到 RDBMS、NoSQL與 NewSQL 的本質設計,對於這問題的答案自己也開始有些頭緒。如同於程式架構的演進一樣,從 RDBMS 到 NoSQL 到最近的 NewSQL,各有適用的強項(解決的問題)與適用的場景,沒有一招打遍天下的解決方案。另外在討論架構時也提到不同解決方案的差異,也提醒同學必須思考什麼情況下會從一種模式轉為另一種架構模式,考量的點會是甚麼,舉例來說如果架構中某個服務loading 較高時,可以選擇抽出來提高其可用性與吞吐量,其餘沒有問題的研究既有架構繼續使用,像是積木一樣做組合與分配,選擇可以解決問題的方案才是真正的王道。

    參考
    Elasticache : 比較 Memcached 和 Redis 的差別
    Queue 的應用(4) - ManualResetEvent 與 Lock 的 BlockQueue 補完
    堆外內存(off-heap),堆內存(on-heap)
    Java魔法类:Unsafe应用解析
    Apache Kafka 介紹
    Blocking Queue
    RabbitMQ性能优化
    Difference between Row oriented and Column oriented data stores in DBMS
    Rowise vs Columnar Database? Theory and in Practice
    關聯式與NoSQL 資料
    Multi-Tenancy Application #2, 資料層的選擇
    Protocol Buffers
    MessagePack

    2020年4月9日 星期四

    [筆記] TGONext 架構組 - 架構師的自我修煉

    前言
    上一篇 TGONext 架構組 - 高併發高流量 分享參加架構一組的書僮筆記,這一篇則是記錄由 Taien 擔任導師的架構三組討論心得,在 TGONext 導師計畫 開學儀式當天小組內的組員有各自做簡單的自我介紹,並針對工作上的痛點做簡單討論,導師與同學分享未來五個月聚會的主題與規劃,以及推薦可以幫助到大家的書籍清單,架構3組三月份討論主題是 架構師的自我修煉,預計討論內容如下
    心態與思想
    深耕專業技能
    團隊合作典範
    如何影響團隊
    這篇是根據微薄的記憶整理小組討論的筆記,部分內容為了讓初老症狀越來越嚴重的自己更好理解加上自己說明與圖片,若有問題或是錯誤的地方歡迎各位大大一同討論或給予指導

    推薦書籍
    在每次的聚會之前導師都有推薦的閱讀清單,清單如下
    • QBQ問題背後的問題 : 這本書之前主管 gipi 就很推薦部門同事一定要閱讀,在 T社也是將這本書列為要求新人必讀書籍之一,最近在博客來發現出了30萬冊紀念版,可見其受歡迎的程度。
    • 我編程,我快樂 : 談到程式猿的成長與職涯規劃之道,作者分享自己過去的經驗提醒程式猿不能只注重技術的提升,還要關注自己職涯上的發展,但礙於自己閱讀簡體字有障礙,目前只看一半還沒看完。
    • 軟體架構師的12項修煉 : 作者認為軟技能是架構師的必修課,整理出 3 大方面分別是關係、個人與商務技能,教導程序猿修煉如何將三大項底下的12 項軟技能點滿,才可以算是一位合格的架構師。
    除了上述提到的三本書之外,我個人也推薦 高效能程序員的修煉一書,其中一個章節提到程序猿應該培養寫作的習慣,當你學習到一技能/對某項事物有興趣/解決某個難搞的問題等事情都可以寫部落格文章,將所學到的內容消化最後在用自己理解的方式呈現出來,91哥也有寫過一篇文 我為什麼鼓勵工程師寫 blog,有興趣的朋友可以看看。

    技能樹
    由於組員來自四面八方每個人所擅長的技能都有所不同,組內有前端工程師、後端工程師、AI 資料工程師等,因此導師有先請同學在家整理以下資訊與同學分享
    專業技能:Skill Tree
    管理:Skill Tree
    職涯目標
    其中專業技能與管理希望同學用 Mind Map 呈現,並用顏色標示出對於技術的熟悉度,主要用意是希望大家都可以知道哪些技能是應該具備(守備範圍),自己目前已經會了那些,而那些內容是自己還不會或是還沒有機會學到的,這些資訊可以透過整理成 Mind Map 的過程中讓自己更加清楚;由於管理的層面涵蓋很廣,像是溝通管理、時間管理..因此可以盡量延展,沒有標準的對錯與答案,以下分享小弟整理的內容,若有疑問歡迎一起討論

    專業技能 Mind Map

    身為一位前端低能兒因此這是以 Backend 後端工程師角度出發,如果有經驗的工程師都會知道,開發不僅僅是把 Code 寫好交付就可以,程式上線後還需要進行應用程式的監控等重要的事情,因此在整理時從幾個環節出發分別是分析、設計、Coding、測試、上線、維護監控,從這幾點分別去整理對應到的技能或是工具,其中 CI/CD 與分散式系統設計是這一兩年希望自己加強的重點。在開發應用程式時隨著請求量的倍增,可能會從單一應用程式Scale up/out 擴充為多台應用程式,這時就需要依據當下的情境設計出合適的架構,如何在設計新架構時兼具效能與彈性讓系統可以承受高流量與高併發的考驗,亦有可能需要與舊架構為伍也就是常提到的讓飛行中的飛機換引擎,這之中有非常多的眉眉角角需要探討與研究的,也是自己覺得想挑戰的部分(自虐)。

    管理 Mind Map
    管理則是由架構師的角度出發,架構師除了基本要具備一定程度的技術能力,對於整個軟體開發流程從需求分析到系統上線後的監控與數據報表分析也都需要了解,從一開始的需求釐清與分析能力需要蒐集高階主管(長官)想要解決的商業問題是甚麼,才有可能在架構設計時選擇適合的方案;技術選型上需要了解選用的解決方案的本質與帶來的side effect為何,還有選用技術/產品的成熟度與穩定性,團隊的能力等多方面的考量出發,而非一昧地追求新技術而忽略帶來的成本與風險;除了技術能力之外軟技能也是不可或缺的項目之一,需要具備 Domain Knowledge 與商業思維而非一昧地以技術的角度出發來解決問題,須具備簡報技巧讓高層願意替你設計的新架構買單;高層 Buy in 後做出來的 POC 方案是否能讓團隊對於新架構是認同;最後是持續學習部分,需要持續學習與了解新技術增加自己的廣度,遇到問題時才有機會有更多解決方案而非單一解。(OS:為了不成為一位嘴砲架構師整理完發現列這麼多條件,覺得好像離架構師還有好長的路 XDDD)

    導師有針對大家分享的技能與管理 Mind Map 內容給建議,另外也補充大家在還沒那麼多經驗時可以多看 Github 上比較熱門的 open source 吸取經驗,熱心的同學也在會後在群組補充覺得不錯的 github 專案 system-design-primer 以及 blog 讓大家一起學習。


    HTTP Request Smuggling
    在討論中導師也提醒同學資安是不可忽視的重點之一,除了可以參考 OWASP TOP 10 之外 另外提醒大家最近一種新的攻擊方式 HTTP Request Smuggling,這種攻擊方式在2005年就被發現但一直被大家所忽略,Portswigger 主管 James Kettle 於2019年再次提醒大家其影響程度,以下就根據 HTTP Desync Attacks: Request Smuggling Reborn 原文做簡單的介紹與說明

    原理
    當客戶在網站上操作行為時會透過 Front-end 服務器 (nginx、CDN、負載均衡或反向代理) 將 HTTP 請求發送至 Web 後端 (Back-end) 伺服器,為了提高其傳輸速度與效率,通常會經由同一個後端網路來傳送多個請求 (HTTP/1.1 提供 Keep-Alive 允許單個連接上傳送多個請求),HTTP 會按照順序進行發送的動作,收到請求的伺服器會根據 HTTP 中 Request 表頭定義請求結束的位置 (Transfer-Encoding或是Content-Length),如下圖所示

    由上圖可以發現,Front-end 與 Back-end 是兩台不同的服務或伺服器,HTTP 請求偷渡是因為 Front-end(反向代理) 與 Back-end 後端處理請求的伺服器對於 HTTP 請求解析處理不一致,駭客可以透過不一致的差異在一個 HTTP 請求中放置 (偷渡) 另一個 HTTP 請求,後端接收到請求後會處理夾帶的攻擊內容 (橘色部分) ,直接在內部網路服務進行攻擊

    HTTP Request Smuggling 將 Content-Length標頭和Transfer-Encoding 放在 HTTP 請求中,在透過 CL.TE、TE.CL、TE.TE 漏洞進行請求解析不一致的動作,詳細原理與細節可以參考下列文章有更詳細的說明與內容
    Service Level
    在定義服務的品質通常會提到 SLA、SLO、SLI,三個名詞的全名如下
    • SLA : Service Level Agreement,服務等級協議
    • SLO : Service Level Objective,服務等級目標
    • SLI : Service Level Indicator,服務等級指標
    舉例來說,假設今天開發的是電商系統,為了給客戶更好的品質與速度因此定義 SLA 為 Latency <= 300ms ;為了達到目標,Sevel level 可能會定義如下
    • SLA : Latency <= 300ms
    • SLO : latency <=200ms,會定義比承諾客戶更小數字的目標以達到 SLA 標準
    • SLI : 每分鐘內 http status code 為 200 的 response,比較著重在指標的部分,常見的有throughput、latency、Availability或correctness等測量指標
    有管理經驗的朋友可以發現像是在定義部門目標使用 Bottom-Up 的方式向下延伸,從下往上看就是要做到這些指標內容SLA才有可能達到,以上只是簡單的說明,更詳細的內容可以參考 Google Cloud 中的 SLOs, SLIs, SLAs, oh my - CRE life lessons 或是 Ant 大的 軟體技術架構如何正確與商業需求快速對齊:談 MAU 換算至 RPS,SLA 回推至 SLI 兩篇文章內容的詳細說明;因此在架構設計上,除了要考慮到需求情境之外,還需要考量到 SLI、SLO及SLA三者的目標,反思設計出來的架構是否都有包含上述功能性與非功能性需求,不斷反思是否有更好的解決方案。


    Design Process
    接著導師整理在設計架構時需要注意的的流程與議題
    Defining the service (Rough, Structured design, Measurable)
    3, and 4: Three-tier architecture (Data Layer[Storage], Biz logic Layer[Compute], Presentation Layer[Networking])
    Resiliency, Availabilty, Scalaility, and Disaster Recovery
    Security
    Capacity planing and Cost Optimization
    Deployment, Monitoring and Alerting, and Incident Response
    
    比如說目標是承受同時在線 10萬人,要思考的是設計出來的系統架構可以乘載同時 10萬人的 request量;設計出來的架構是否有彈性與擴充性,遇到災難是要如何進行快速的復原;要如何確保系統的Security,像是密碼一定要做 hash之類;使用量一年會產生多少 cost 是否有 plan ?;最後是如何進行 deployment ? 如何監控線上的環境與機器服務,如何第一時間知道使用者出問題,出問題時要如何處理 ?
    為了讓同學們有更好的理解,導師也分享過去工作上架構設計的專案與跟同學說明為什麼這樣設計(原由),也提醒同學簡報技巧也是重要的技能之一,當我們想要說服老闆使用或引入新架構時,從老闆的角度來出發像是思考老闆可能最關注的點像是會增加多少預算、會帶來多少效益以及瓶頸會在那裡跟如何解決,節省老闆的時間也讓決策者方便快速做決策。


    Business/Product Methodology
    最後導師補充一些與 PM 比較相關的觀念,希望同學在鑽研技術之餘,多去了解或學習一些常用商業模型對架構設計也是有幫助的,由於這領域自己不太熟悉因此在介紹時會加上 wiki 連結介紹,讓有興趣的朋友請自行點擊深入了解,若對於方法論內容理解有錯歡迎糾正。

    AARRR
    AARRR 模型是一個有名的方法論,每個英文單字都代表指標分別是Acquisition、Activation、Retention、Revenue以及Referral,主要是在談怎麼樣獲取用戶,在導師介紹完模型的說明讓我想起(後知後覺)待過的T社部門職責分工相似,部門分別負責特定指標,公司為了協助達標每個部門都有自己的RD團隊來專心支援前線單位完成其指標,

    Lean Startup
    Lean Startup 精實創業 : 概念與 scrum 類似,當你今天有一個 idea 時候以最小可行產品(MVP)來實現,提早讓使用者來驗證 idea 想法是否有效,並在使用過程中加上 measure,再透過 measure 產生的 data 思考要如何調整 idea 讓它更好,試圖在 measure 的過程中尋找可能的商機(契機)。這方法論很常在創業的朋友討論中提到,在公司草創初期都希望在最短的時間找到可行的模式,早日度過黑暗期。

    Scrum - Most Important is Value
    Scrum 敏捷開發 是這幾年很紅的方法論,用小步快跑的方式快速提交最有價值的功能,網路上已經有非常多相關知識這不在多廢話。
    另外導師還提到了像是 Steve Blank - Customer Development、Alexander Osterwalder - Business Model Canvas 與 Value Proposition 等方法論,但礙於大腦容量有極限且未接觸過,這就筆記下來日後有機會再自行研究。

    心得
    這是小組的第一次討論,組員分享自己的技能樹時聽到過去很多自己未接觸到的名詞,可以學到不同領域的知識感覺挺好的;在過去自己對於其守備範圍理解都是較為零碎的,可能是發現甚麼重要就盡力的去點滿其技能,在這次盤點 skill tree 的過程中才真正的去思考自己的目標(Goal)為何 ?自己希望哪些技能是應該具備的,對各技能的熟悉程度與目前還尚缺那些技能,這些資訊擁有之後或許可以訂為日後的長期目標,定期 review 自己完成百分比(自虐again);在兩個半小時的討論過程中,導師也很熱心的與同學分享自己所了解知識與架構設計的經驗,也補充技術以外常見的幾個商業方法論,提醒大家偶爾可以跳脫技術學習不同的解決方案提升自己的商業思維;透過更多實作累積更多經驗,成為一位能夠真正解決問題不嘴砲的架構師。

    參考
    AARRR
    Lean Startup 精實創業
    Scrum 敏捷開發
    The Four Steps to the Epiphany
    Business Model Canvas
    Value proposition
    架構師的修練
    深度剖析什么是 SLI、SLO和SLA?
    SLOs, SLIs, SLAs, oh my - CRE life lessons
    從零建立商業技術團隊
    [ModernWeb2019] Taien - 高併發的道與術
    HTTP-Request-Smuggling (pdf)
    HTTP request smuggling
    HTTP Request Smuggling (HTTP 請求走私)
    軟體技術架構如何正確與商業需求快速對齊

    2020年3月25日 星期三

    [筆記] TGONext 架構組 - 高併發高流量

    前言
    在偶然的機會發現 TGONetworks 正在舉辦 TGONext 導師計畫 活動,活動邀請在 技術管理、技術創業技術架構有經驗的科技領袖 (大神) 擔任各組的老師,在五個月之間老師會帶領小組的組員深入討論相關的議題,身為一位打雜多年的工程師,看到可以與諸位大神近距離的學習的機會當然也不會錯過,運氣不錯的也順利通過兩階段的面試錄取,每個月都有小組的聚會討論,TGONext 也鼓勵不同組的組員彼此交流學習,有幸參加了由 Ant 帶領的技術架構一組聚會三月份討論主題是高併發高流量,當天討論議題如下
    Database 跟高併發的關係(Ex. NoSQL / RDBMS 在不同場景的負載能力,然後討論到原本的問題要怎麼選擇跟評估)
    Server 端口的集中管理 / 微服務的必要性及適用場景 的規劃(Ex. 已經了解整個 Application 的基本配置,要怎麼做出拓展然後發展出 SOA、微服務的架構)
    Domain Driven Design 對拓展性的影響(Ex. 傳統單體式的設計跟 MVC 的相關性,要拆分成微服務後 DDD 的設計是否更有利、為什麼有些語言的框架設計都是採取 DDD 的方式)
    如何設計一個電商系統,可承載 100 萬人同時在線上,SLA 可達到 99.9% 的架構?(回顧題)
    請問 Computer Science 的 Bound Categories 有哪些?可以如何偵測出來?
    Cache 的缺點有哪些?模式有哪些?什麼時候應該採用?
    高併發高流量與程式語言的哪些特性有關?程式語言選用時可以注意什麼?
    高併發高流量在各階段的架構演進可以如何設計?分布式模型的引用?一致性的需求? 
    這篇是根據微薄的記憶整理旁聽的筆記,部分內容為了讓初老症狀越來越嚴重的自己更好理解加上自己說明與圖片,若有問題或是錯誤的地方歡迎各位大大一同討論或給予指導

    架構的演進
    在討論的一開始 Ant 先回覆同學們詢問開幕式提到的 SLA 的計算方式,接著進入到主題高併發高流量,請大家先思考應用程式架構是如何演進的,開始畫圖向大家說明常見的 Application 演進的過程

    Monolithic Architecture
    在初期 (可能) 會規劃 Application 與 Database 放置在同一台 Server,節省資源與費用避免不必要的浪費,也就是大家常聽到的傳統單體式設計 Monolithic Architecture

    Application 與 Database 分離
    當使用者逐漸變多時,由於 Application 與 Database 是存放在同一台伺服器主機,共用相同 CPU 與 Memory 資源,可以選擇將 Application 與 Database 分開存放在不同主機以避免資源互搶的狀況發生,以提高可負擔的 Request 請求量。
    這時導師拋出一個問題讓大家思考
    導師 : 假設單純的 Application 遇到性能瓶頸問題,一般來說第一件事會做甚麼 ? 
    Cache Server
    最常見的作法就是加上 Cache 機制,舉例來說電商平台首頁大多都有商品介紹,用戶在瀏覽商品資料或是相關頁面時,會發送讀取商品資料的請求至資料庫伺服器,如果同時有 100 位用戶在瀏覽就會有至少100+ 個 Request 請求發送至 Web Server,加上 cache server 可以考慮將這些資料異動不頻繁,或是不那麼重要的資料庫查詢結果資料放置在 Cache Server 中,以提高 Application 回應速度與分擔 Database loading。

    導師 : Cache 的優缺點是什麼 ? 什麼時候該採用呢 ? 
    Cache 優點部分主要可以降低伺服器的負擔與增加回應速度,還可以減少網路頻寬的浪費與保護資料庫的功能;但在導入之前團隊也必須要了解 Cache 的問題不能只靠乖乖保佑,避免異常發生時不知道該如何處理只能大眼瞪小眼,可能需要注意的有下列幾點
  • 適合情境 : 什麼樣的資料需要放在 Cache 中 ? 假設今天 Database 資料已更新的時候,快取內的就會是未更新的資料(贓資料),用戶讀取到舊的資料影響會是甚麼? 
  • 資料一致性 : 當資料發生不一致時,更新快取的策略是甚麼 ? 是使用 CronJob 排程定時去資料庫更新快取、還是設定快取有效時間讓快取自動失效、或是更新資料庫時同步更新快取內容、或是先淘汰快取後再寫到資料庫 (小弟目前是使用這種方式)。
  • 異常處理 : 當快取 Server 發生異常或是故障時,團隊是否了解該如何快速恢復,如何在一開始建立快取的 HA 機制 ? (如果是使用 Redis 可以設定 master-Slave 與 Sentinel,透過 Sentinel 的哨兵機制,可以在 master 發生異常時快速切換到 slave instance 機器,不用手動進行切換;如果沒有設定 master-Slave 機制,可以使用 Redis 的持久化設定 進行還原的動作 )

  • 雪崩效應 (Avalanche effect)
    在討論的過程中,導師也提到了高併發高流量可能會遇到的雪崩效應,發生情境可能是單一時間同時湧入大量的請求(ex : 五月天搶票),當 cache server 無法承受發生異常或重啟時,由於 Application 是先打 cache server 取得資料,當 Cache server 重啟後沒有資料時會先向 Database 資料庫撈取相關資料再存放到 cache (或是排程固定撈資料),如果程式判斷沒有處理好或是資料庫語法沒寫好的情況下,有可能就會發送多個請求向 Database 撈取同樣的 cache 資料,資料庫同時接受到大量的 cache 資料處理請求短時間無法回應,使用者同時又不斷點擊向 Web Server 送出更多的請求,最後造成 Database 無法提供服務,接著 Web Server 跟 Cache 也因為前面的 Request 請求未處理完塞車的關係相繼的無法使用,應用程式被用戶各個擊破(誤,示意圖如下
    在討論時導師拋出了這些引入 Cache 快取可能存在的問題,因此提醒學員開發團隊在使用前必須先釐清上述可能會遇到的問題,像是Cache 資料的一致性或是更新策略,到後來 Cache 異常時處理方式,團隊成員如果對於 cache 解決方案不夠熟悉而盲目導入的話,又不巧的遇到高流量的請求時 cache server 異常,就會發生團隊無法處理而延長了網站恢復的時間的憾事發生。

    Microservice 微服務
    隨著新的商業需求越來越多,開發者會不斷的在原本的 Application 添加新功能,原先的代碼可能會隨著時間的關係變得更加龐大難以維護,結構變得模糊質量也隨著下降,代碼的建置與部屬周期時間都相對的拉長,單體架構的問題會陸續浮上檯面,為了解決此問題,有人提出使用最近幾年很流行的微服務來解決此問題,世界上有些著名的公司也在使用微服務架構像是 Netflix、eBay和 Paypal。接著導師請大家思考下列的問題,希望決定架構前,必須先了解架構本質上的問題以及導入後帶來的影響
    導師 : 微服務的本質是什麼 ? 什麼時候需要導入微服務呢 ? 
    在討論微服務時前導師先提到 Performance 鐵三角 觀念
    Throughput 
    Latency 
    Memory footprint 
    如同三角形的三邊,任何一邊的改變都會影響到另外兩邊。Microservices 將系統拆分為多個部分將職責相同的功能或模組區分為單一個服務,提高內聚力與降低彼此耦合度,開發與布署時不在互相依賴,各自服務可獨立擴充與伸縮,可使用不同的語言進行開發或合適的資料庫存放資料。了解完本質之後,接著來看導入微服務會帶來哪些挑戰
  • 服務如何拆分 : 首先遇到的問題會是系統要如何拆分為不同的服務,服務之間的業務領域守備範圍該如何定義,如何界定服務的系統邊界 ? 這幾個問題可能會是設計階段需要討論的,因此,在 InfoQ Using Domain-Driven Design When Creating Microservices 文章中提到在微服務使用 領域驅動設計 ( Domain-Driven Design DDD ) 在架構設計上會幫助。
  • 服務之間如何溝通 : 在過去單體式架構可能起一個 Thread 或是 Task 就可以完成的事情,在微服務中可能變為呼叫多個服務才有機會取得結果,在服務之間的通訊機制(溝通)方式是什麼 ? HTTP、TCP 或是其他更適合的溝通方式 ?
  • 部署與監控方式 : 在微服務的架構下服務數量也相對提升,代碼的建置到部署到也隨之變的複雜,如何做到每個服務的監控,像是取得應用程式CPU、記憶體、網路傳輸量等基本資訊,甚至到業務邏輯點的應用程式 Request 執行成功或錯誤率,是否有 Log 視覺化工具可以協助快速將問題定位 ?並在服務發生異常時,並第一時間做出處理與事後根本問題分析。

  • 基礎建設也是微服務重要的環節之一,導師接著提到在微服務中常見的名詞像是 Service Mesh、API Gateway、Zookeeper 等基礎建設,並請學員們思考這些服務/Pattern 分別是為了解決甚麼問題,優缺點是什麼 ? 

    Service Mesh
    在微服務中服務可以使用不同的程式語言來進行開發,但使用不同的程式語言會發現有些 [功能] 是可以共用的,像是驗證機制、監控方式、配置設定、Logging、流量控管、Healthcheck、Circuit Breaking 等功能,以上功能都需要使用各自的程式語言實作出符合某項規範,緊密的耦合相對了也增加了應用程式的整體複雜性,Service Mesh 可以將這種複雜性與應用程式分離開來,提供像是流量管理、Logging、監控、身分驗證、Circuit Breaking 等基礎(通用)功能,讓應用程式可以專心關注處理負責業務邏輯。可以透過設計模式中的 Sidecar Pattern 實現,如果有看過美國隊長電影的人可以回想有一幕美國隊長騎著軍用摩托車,旁邊有加裝一台沒有輪子的側車依附在軍用摩托車上,這是所謂的 sidecar,同樣的在軟體結構中 sidecar 也連結到主應用程式並擴充與增強其功能,示意圖如下
    如果對 Service Mesh 演進有興趣可以參考 Pattern: Service Mesh;另外 The Rise of Service Mesh Architecture 與 Sidecar Design Pattern in your Microservices Ecosystem 對於 Service Mesh 與 Sidecar 優缺點都有更進一步的說明,有興趣的彭油可以參考看看。

    另外,在 Martin fowler 部落格有篇文章 MicroservicePrerequisites 也有提到,建議沒有具備 Basic Monitoring、Rapid provisioning、Rapid application deployment 這三種能力之前,不應該考慮使用微服務架構;另外在 MicroservicePremium 文章也提到微服務帶來的複雜性,當盲目導入可能會帶來更大的麻煩,舉例來說如果今天遇到的問題是系統效能不佳,閉著眼睛導入微服務架構不會改善問題 (加了K8S也不會!!),微服務解決的 Throughput 無法降低 Lateency。因此,架構師或是技術團隊高層必須謹慎的評估,在組織定的商業目標與技術發展兼做出抉擇,選定適合的技術解決方案。

    補充 : Monolithic > SOA > Microservice 
    在提到簡化系統的方法也會讓人聯想到 SOA (Service Oriented Architecture) 架構模型,將可重用的部分抽成服務 Service,降低其複雜性與提高服務的可重用性,在找尋相關資料中幸運發現 Best Architecture for an MVP: Monolith, SOA, Microservices, or Serverless? 文章中解釋 Monolithic、SOA 與微服務三個架構簡單的示意圖


    架構與組織的關係
    系統架構與公司的組織的關係也是密不可分的,也是所謂的康威定律 ( Conaway's Law),wiki 說明如下
    設計系統的架構受制於產生這些設計的組織的溝通結構。  
    舉例來說,當系統規模不大時可能初期會使用單體式架構(Monolithic),背後開發人員會是有一個團隊擔任維護與開發的動作,隨著生意越做越大組織架構可能會跟著調整,陸續因為需求量越來越大而開發團隊加入更多的開發人員(新鮮的肝),接著代碼越來越雜亂與溝通成本越來越高,演變為每個服務後面都會是一個團隊 Team 來進行開發,以加速整體的開發速度,示意圖如下
    同樣的,如果今天是跨國企業不同國開發人員都會有不同的開發專案,彼此要溝通時會透過討論定義 API 簽章內容,降低直接在不熟的情況下修改對方專案造成改A壞B或是資料異常的延伸問題。

    資料庫選擇
    在討論資料庫時候提出下列問題
  • RMDBS、NoSQL、NewSQL 本質的差異 ?
  • RMDBS、NoSQL、NewSQL 優缺點是甚麼 ?
  • NoSQL 興起的原因為何 ? 優於 RMDBS 的原因是什麼 ? 
  • 如何選擇資料庫 ? 
  • 這部分的討論由於小弟在處理公司事務,因此筆記可以參考兩位認真上的同學的筆記內容(被打
  • TGONext: 從缺點選擇架構
  • TGONext - 高併發高流量 

  • 心得
    在討論架構演進的過程中很多名詞過去可能在 meetup 都曾經聽過,可以觀察到在這次的討論中導師不斷引導在場的同學們,希望大家思考這些名詞與技術《本質》是甚麼 ? 解決什麼樣的問題 ? 學習或是引進一門技術時不只是要看它的優點,還要了解它帶來的影響或 side effect 是什麼,可以提出他的優缺點才算是真正了解。也因為如此讓我在寫這篇旁聽筆記時花更多時間思考關於《本質》這件事,學習到用不同的角度來看待事情,謝謝 TGONext 讓我們有這機會可以與技術領域的高手們學習的機會,也期許自己在每次的聚會中學到更多的知識可以分享給更多需要的朋友 :)

    參考
    martinfowler microservice 系列文章
    Microservice Trade-Offs
    How to extract a data-rich service from a monolith
    Microservices and the First Law of Distributed Objects
    Best Architecture for an MVP: Monolith, SOA, Microservices, or Serverless?
    Microservices - Not A Free Lunch!
    Microservices Journey from Netflix OSS to Istio Service Mesh
    瞭解 Microservices 架構
    什么是Service Mesh
    微服務架構 #1, WHY Microservices?
    微服務架構應用指南

    Copyright © m@rcus 學習筆記 | Powered by Blogger

    Design by Anders Noren | Blogger Theme by NewBloggerThemes.com