OpenTelemetry初體驗:實踐Chaos Engineering來Drive the Observability’s best practice

嗨,我是水球潘,這一年我在LINE Taiwan擔任TECH FRESH (實習生),前半年,我身在LINE Travel中與我的Mentor – Robert 習得了許多扎實的軟體設計和敏捷方法的知識;而後半年的我,則在LINE SRE團隊中,由我的Mentor – Bryan帶領著我,便開始了鑽研各式各樣技術的SRE旅程。

此文將會從SRE旅程的目標展開,途中我會介紹我如何使用領域驅動設計(Domain-Driven Design)來設計一個作為Benchmark的Uber-Like app,然後會把焦點轉移到重要的知識節點「Observability」身上,隨之會帶各位參觀OpenTelemetry在Java Spring Boot的整合下是有多麽地強大,最後則是在Chaos Engineering的精煉下,結束這場旅程。

Drive the Observability’s best practice

在與Bryan進行一番討論之下,最後我選擇了最適合我也最有挑戰性的一份任務,這項任務本質上是「Open-ended」的,意即,這是一場手裡拿著指針但對終點一無所知的旅程,而身在SRE,這個啟程是有趣、自由,且充滿挑戰性的。

由於這個專案的參與者只有我自己一個人,無論是風險還是時程的管理都容易可控,於是SRE的夥伴們欣然同意了讓我使用最基本的WBS來做專案管理和進度追蹤。

「Drive the Observability’s best practice」

這便是我這項任務的總結,我的旅程也便以這五個英文字作為目標,但單從短短這五個字來看,其實目標是過於廣闊並且無從下手的。而從另一面來看,這個目標也可以說是非常具體,因為要的只是「the best」practice,因此我決定用OKR的角度來思考這整趟旅程的樣貌。

  • 子目標及關鍵結果:
    • (O1) Technical Research
      • (KR1) 開發一個足夠複雜的PoC Application來彰顯Observability的優點
      • (KR2) 估算導入Observability的工程成本和效能成本。
    • (O2) Drive the Best Practice
      • (KR3) 列出有哪些Best Practices (In a declarative way)
    • (O3) Culture
      • (KR4) 將整個過程及結果於LINE內部進行分享。

本文將會著重於分享O1和O2的部分。

Waber Uber-Like APP

(KR1) 開發一個足夠複雜的PoC Application來彰顯Observability的優點

以往在軟體工程的研究中,為了要體現一個軟體工程方法論的Pros&Cons,會使用一個設計好的「需求」作為「Benchmark」來去衡量方法論的「Performance」。

而我的任務其實也有雷同之處,我需要一個足夠複雜的PoC Application來彰顯Observability的優點,其實本質上就是我必須要先設計好「Benchmark」來對我之後的Observability practice進行衡量,我希望這個「Benchmark」是一個足夠複雜的應用程式,而「複雜化一個應用程式最快的方式就是從領域知識開始複雜化起」。

DDD(領域驅動設計)其實是一個已經起源了好一陣子,不斷默默發展、曲高和寡的軟體設計知識,且由於近幾年「微服務」的興起,DDD也因此浮到檯面上備受矚目而DDD的方法論也隨著近代發展,變得越來越容易上手,越來越容易導入,其中一個最知名的「由團隊共創的系統分析」活動:「Event storming」便為其中一個方法論。

於是我召集我的好同事們,想要進行一場「Event Storming」來集眾人之力完成這個Benchmark的領域模型設計,我們決定以Uber-Like App—叫車APP,作為雛形來去執行Event storming。

(對於Event Storming的細節有興趣的讀者們,歡迎加入DDD TW的臉書社群: https://www.facebook.com/groups/dddtaiwan,社群每個月都會舉辦相關工作坊或是讀書會的活動,保證手把手帶你做好各個方法論的細節!)

隨著第一階段Process Modeling的階段結束後,我們得到了以下的結果:

隨後我們就立即進行下一階段的設計,觀察領域中重複出現的名詞,聚出Aggregate以及畫出Bounded Context:

基本上,到了這一步我們就算是把「認知中」Uber-Like APP的領域模型給建模完畢。

Microservices

為了讓Waber在技術上具備著複雜度,尤其是為了讓應用程式的行為變得更難以捉摸,Waber必須扛起分散式系統的大旗,而微服務架構就是最可行且實際的設計方案之一。

由於我們已經在Event Storming中圈出了數個Bounded Contexts,而在DDD中,Bounded Context常常被用來作為微服務架構的設計指導,因此我們可以從中來衍生出我們的系統架構藍圖:

Waber有五個微服務,其中四個是由Bounded Contexts衍生而來(User 乘客 / Match 叫車匹配 / Trip 載客旅程 / Payment 支付金流),另外加開了Broker service,用來作為Websocket推播的統一出口。微服務之間的通訊機制除了最直接的RESTFul API的上下游呼叫關係之外,也使用了RabbitMQ作為Message Queue將領域事件有效廣播到各服務去。

到了這邊,Waber的設計也已經趨近於完整,接下來就是使用Java Spring Boot將其開發出來,最後花了一個月的時間將後端完整使用Clean Architecture(刻意練習)的架構開發完畢,共計大約7000 SLOC。

本文並不會提及Clean Architecture的完整實作過程,Waber為開源專案,有興趣的朋友可以隨意閱讀(https://github.com/Johnny850807/Waber)。

有了這樣子的一個Benchmark可以隨意遊玩之後,接下來終於可以當個SRE實習生,好好「Tune」一下APP的Observability啦!

在進入整個旅程前,先來複習一下何謂「Observability」吧!

Observability 

應用程式本身都會具備一定程度的「行為」,平常在開發環境中,遇到Bug的時候為求方便我們都會開啟Debugger下中斷點來進行Debug,藉由中斷來確認應用程式的行為照預期所走。

但是我們無法不斷地依賴Debugger,一旦程式部署到各環境中,我們便不再能夠使用Debugger來中斷且觀察應用程式的行為。

因此,所謂的「Observability」(可被觀察性),指的是應用程式是否能夠在被部署到某個線上環境之中後,其本身還能透過「某種機制」來讓開發人員「方便觀察」應用程式本身在線上「各個時間點」的行為。

最常見的機制就是寫日誌 (Logs),並且在Cluster上使用某種蒐集器將各個容器中的Log搜集起來匯入到Storage中。Logs即為「Observability 3 pillars (三大支柱)」中的一員,另外兩個的支柱則為「Metrics」和「Trace」。

  • Logs:透過「文字」將在某個時間下發生的的事件、資料、和有意義的資訊記錄起來。
  • Metrics: 透過觀察一定時間之內而量化後的數據。常用的System metrics有Query per second (QPS)、Transaction per second (TPS),而常用的Business metrics有Daily active users (DAU)。
  • Trace: 定義為「a tree of spans」。Trace記錄著每個功能其應用程式完整的執行過程。由於執行過程會充滿著「上下游的呼叫關係」,我們將這些呼叫關係記錄起來便形成了一棵樹。

以Waber的實際使用案例為例,一個叫車的POST request有著以下的資訊和行為:

雖然附圖的呈現十分清楚,但是在技術上到底該如何做到如此詳盡的呈現?我們可以用Logs和Traces去記錄不同面向的資訊:

如果能夠簡易地在Logs和Traces之間交互導覽,則開發人員就能快速地理解應用程式的行為了。

在Grafana上,這件事被輕易地辦到了,我們能夠藉由點擊Log的衍伸欄位”traceId”,直接導覽到該Log其背後完整的Trace。

在右半部的Trace之中,你可以很明確地看上整個微服務網內互打的整個上下游的呼叫鏈。

雖然這個章節旨在複習Observability三元柱,但附圖也算是透露了「OpenTelemetry」的強大了…,我們接著走下去。

OpenTelemetry: The facade of Observability

(KR2) 估算導入Observability的工程成本和效能成本。

SRE一直以來都希望能夠最小化實踐Observability所造成的額外負擔,於是我們決定要嘗試多多研究OpenTelemetry這一項CNCF近期推出的技術框架。

「OpenTelemetry的發明並非為了要解決新的問題,而是一個在Observability三大支柱的需求下,實現單一標準的框架。」

為了帶各位瞭解OpenTelemetry被發明的必要性,我們先來看一下在以前,我們都是如何做到Distributed Tracing的?

  • OpenTracing + Jaeger

Reference: https://jaeger-cn.readthedocs.io/zh_CN/latest/

  • Zipkin
Reference: https://zipkin.io/pages/architecture.html

上述兩者Tracing system的系統架構圖並不是重點,但是讀者們可以感受一下其兩者之間其實是「大同小異」。

以OpenTelemetry的設計觀點來看,這種「大同小異」便有了可以實施統一標準的可行性。

而以物件導向設計的觀點來看,其實OpenTelemetry便是將這些「大同小異」的各個變動點封裝起來並實施單一標準來做依賴反轉

「Abstract common behaviors, and then invert that dependency!」

我們用以下這張圖來總結OpenTelemetry的設計:

  • Abstract common behaviors (萃取共同行為)

OpenTelemetry萃取出來的Abstraction中大致上分為四個元件:API(aka SDK) → Exporter → Agent → Collector

架構:在Application的source code中,使用OpenTelemetry SDK的API來進行「Instrumentation」,下一步Exporter會將instrument製作出來的log/trace/metrics用配置好的格式傳遞到Agent去,Agent只是作為資料傳遞的一個中介者,最後他會再把蒐集到的資料forward到Collector中。

  • Dependency Inversion (依賴反轉)

為了要在應用程式中做Distributed Tracing,以往我們都必須直接依賴Tracing system Vendor的SDK來去埋Trace,但如此一來,未來如果決定要更換Vendor時,則應用程式會有很大一部分需要重寫,這也是為什麼SOLID設計原則時時刻刻提醒著我們必須要做依賴反轉,並且高低層次之間必須依賴抽象。

此時OpenTelemetry扮演的就正是那一層抽象的Interface,以官方的口吻來說,他是一套標準,如果Application依賴的是OpenTelemetry的API,那未來要更換Vendor時,我們就只需要改變OpenTelemetry的配置就行了,任何一行程式都不需要重寫。

OpenTelemetry in Java Spring Boot: Step by Step tutorial

首先是要先到Github上: https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases 並下載其最新釋出的javaagent的jar檔案。

接下來只需要將這個jar檔案,在Dockerfile中將其Copy到映像檔中,然後在CMD執行Java程式的指令中,藉由javaagent參數指向jar檔案的位置一併執行就行。

除了引入OpenTelemetry這個套件之外,還需要把Tracing system的Vendor一併部署起來(e.g., Jaeger or Grafana Tempo)。

一個很基本的範例可以參考這個Repository: https://github.com/Johnny850807/Spring-Boot-Demo-Observability-with-Open-Telemetry

配置部署完整之後,「一行程式都不用寫」,就能夠產生出以下的Trace了:

什麼?一行程式都不用寫? – Auto-Instrumentation

“Application-level transparency
programmers should not need to be aware of the tracing system”  – Google Dapper

OpenTelemetry在Java的支援上,確實做到了Application-Level transparency,其底層原理是「Java Agent + AoP」。

開發人員不再需要親自埋Trace,不需要對Tracing system有任何的認知,更不需要為此寫任何一行程式碼。相反地,以Java Agent方式被執行的OpenTelemetry,會主動藉由AoP的機制,來在切面中擴增Instrumentation的行為。

舉例來說:OpenTelemetry會尋找所有被標注上 @RestController 的物件,並在其每個RESTFul方法的進行前主動進行Instrumentation,幫忙埋下適當的Trace,亦或是進行Trace的Context Propagation

Manual Instrumentation

在品嚐到Auto-Instrumentation的強大之後,任何一位技術決策者心中浮現的第一個問題肯定是「那如果我要客製化Instrumentation的話要怎麼辦?

此章節我們以Trace為主軸來進行說明,這個問題OpenTelemetry也給予了高度重視,分為兩個層次來做到客製化:

  • 第一個層次:藉由參數進行配置:”OpenTelemetry is highly configurable”,我們能夠藉由環境變數來去設置在Trace方面,希望OpenTelemetry include/exclude的類別或方法。
  • 第二個層次:在程式中使用@WithSpan這個註解來增加想要被放進Trace的方法。

以Waber中的實際案例來說:有兩個POJO物件:StartDriving 和 FindCurrentTrip ,也想要被加入到Trace之中。

由於這兩個物件只是單純的POJO,因此在預設的情況並不會被OpenTelemetry的切面給切到,為了將其加入到Trace之中,只需要其方法上加上 @WithSpan,就能夠得到以下的結果:

Bravo!

Asynchronous Flow Tracing

值得一提的是,OpenTelemetry也會針對Message Queue (以Waber為例的話,使用的是RabbitMQ) 的ProducerConsumer端藉由AoP來進行Auto-Instrumentation。

以下圖為例,Waber的trip service為Producer,match service和broker service為Consumer,一旦trip service發布了事件到Message queue中,OpenTelemetry也會自動化地做好Context propagation來達成圖中的Trace。

Drive the Observability’s best practice

上文我們設計了Waber的系統,然後走過了一遍OpenTelemetry in Java強大的功能面,也看到了使用上OpenTelemetry的Waber所呈現的Trace中,在呈現服務與服務之間的呼叫鏈面上有多麽地清楚。

坐擁OpenTelemetry這樣方便強大的工具,算是在Technical Research面上往前又走了一大段路。可惜,以SRE的觀點來看,即便OpenTelemetry是如此好用,但是如果沒有辦法在這些工具的使用上鑽研出有說服力的「Best Practice」的話,那麼也只是大材小用,效果不彰。

因此接下來的篇幅要來談論「How to drive the best practice?」

The Best Practice is driven by the Ground Truth

“The Best Practice is driven by the Ground Truth.” 

這句話是我由衷的一個想法。我認為,僅靠我淺淺的資歷,是不太可能以我自身的角度去定義何謂「Best Practice」。

要從一群實踐中去找尋最佳的那一個實踐,便代表著我必須要設計一種客觀的評斷方式,來從真實的實踐結果中得到回饋,而這種真實的實踐結果,便是「Ground Truth」所指之意。

經過了一番的思考與設計,最後我設計出了一個方法,其參考了「Chaos-Engineering」的精神,能夠營造出一個環境,讓這個環境告訴我「目前的實踐是否仍有缺陷」?

我把這個方法稱之為「Reinforcement Chaos-Engineering」。

但是目前僅有一個Waber這樣子的一個叫車系統,其實是還沒辦法開始Drive the best practice的,我們還需要寫一段程式來模擬乘客和司機的行為,來自動化地產生合理的叫車流程之Workload。

乘客/司機機器人 → 自動化地產生合理的叫車流程之Workload

如上所附的動畫所示,在經過數日的開發後,終於做出了一個簡單可愛的自動化叫車Workload產生系統。動畫中呈現的是在有五個司機,一個乘客的情況的模擬。Workload的產生皆必須是合理的,意即乘客和司機都必須遵守叫車流程,並且必須不斷地為叫車流程創造進展。

  1. 乘客進行叫車匹配
  2. 系統完成匹配,並且匹配到了某一司機。
  3. 該名司機開始此次載客服務,並且朝著乘客的上車地點開車,移動的過程中不斷地向伺服器更新自身座標。
  4. 乘客不斷接收到司機最新的座標。
  5. 司機抵達乘客的上車地點,確認乘客上車後,司機將狀態調整成「前往目的地中」。
  6. 司機開車前往目的地,移動的過程中不斷地向伺服器更新自身座標。
  7. 司機抵達乘客欲前往的目的地,結束了載客服務。
  8. 叫車流程結束,乘客將自己的座標更新到了隨機的位置並開始了下一次的叫車匹配。

在GUI上看似簡單的叫車流程,其背後的工作其實是必須由Waber五個微服務以及RabbitMQ來協作完成的,現在我們已經能夠創造大量且合理的Workload,總算可以來開始實踐Reinforcement Chaos-Engineering了。

Reinforcement Chaos Engineering

(KR3) 列出有哪些Best Practices (In a declarative way)

以往在談論Reinforcement的時候,多半第一個想到的是機器學習的增強式學習(Reinforcement Learning, RL),RL透過環境的回饋,來讓模型在一次次的「獎勵」或是「教訓」中學習並且增強。

而在我們的任務場景中其實也是具備類似的思維的,只是我們要增強的不是「模型」,而是「我」作為SRE──對Observability Best Practice的認知

那下一個問題就是,該如何評斷我對於Observability的認知是否增強了?

為了回答這個問題,我重新用Site Reliability Engineer的視角審視了一下我的任務對於目標本身所創造的價值究竟為何?

最後我得到了一個結論:「I’m here to minimize the MTTR (Mean-time-to-repair)」(以本例來說,便是要花多少時間Troubleshooting才能夠察覺以及修復好應用程式中的Bug)

如果我設計出來的Observability practice具有最小的time-to-repair,那便代表這正是對於Waber這個benchmark,到目前為止得到的best practice。

這下我便有了一個非常明確的標準來去比較不同Observability practice之間的好壞了,接下來要面對的難題只剩下「我該如何營造一個能夠讓我進行troubleshoot的環境?

現在我已經有了「自動化叫車Workload產生系統」,有了「評斷Observability practice的標準」,那剩下我最缺的就是「Bug」了。

Chaos Engineering 混沌工程

由於容器化微服務興起,而微服務等分散式系統在開發和運營上具備更高的門檻和複雜度,因此Chaos-Engineering便也開始被不斷提倡。以白話文來說,Chaos-Engineering便是「要有目的地對待測系統搞破壞來提早揭露系統的問題」。

而為了揭露系統的問題,我們需要先對待測系統定義出何謂「Steady 穩定」的狀態。以Waber來說,穩定的狀態便是「能夠完整且順暢地執行每一個叫車流程」。

借鑒了Chaos Engineering的思維,將其運用到Observability的場景之下的話,則是「要有目的地在Waber中搞破壞來提早去揭露Observability practice的缺陷」。

對此,由於我的使用場景較為特殊,為應用程式內部的Chaos-Engineering,對於是否有現存的第三方工具能夠滿足我客製化Waber中的各種Chaos並沒有太大的自信,因此我決定自己實作一個能夠實現Chaos-Engineering的技術架構,以下圖所示:

多開了一個新的Service(圖正中央),我稱之為Chaos-Server,而在Waber各個Service中都執行一個Chaos Client (aka Chaos Agent),Chaos-Server和各個Chaos-Client互相溝通,傳遞指令,來做到整個Chaos-Engineering的流程。

而我呢,則是只需要在Chaos的操作頁上對Chaos-Server下達命令就好了(如下圖)。

關於Chaos-Engineering的流程,我希望能夠把他設計得像一場遊戲、像一場競賽一樣,整個流程如下:

  1. 將部署好Chaos-Server和Chaos-Client的Waber執行起來,爾後也將自動化叫車Workload執行起來。
  2. 瀏覽Chaos操作頁 /api/chaos ,這個頁面Json頁面可以用來對Chaos-Server下達指令。
  3. 開始一個新的關卡:每一個關卡都可以由一串隨意的字串(我將其稱之為FunValue)來產生。
    1. 呼叫 /api/chaos/fun/56a8d709-9c22-489e-b44e-6d86f81796b2 這個API,來使用”56a8d709-9c22-489e-b44e-6d86f81796b2″這個FunValue來遊玩一個關卡。
    2. 這個FunValue會直接被雜湊成一群Chaoses,意即,當你輸入完FunValue後,一群特定未知的Chaos (i.e., Bug) 就被埋好在Waber的各個Service中了。
  4. 接下來繼續在Chaos操作頁上進行,操作頁上會顯示所有候選的Chaos名單(Chaos Candidates),並且還會顯示在這些後選Chaos中,有幾個真的被Activated(激活)了(從remaining屬性中得知)。
  5. 關卡開始後,自動化叫車Workload便會進入到「不穩定」的狀態,意即,由於Chaos的緣故,叫車流程將會受到影響而被阻斷。因此我們可以開始進行Troubleshooting了。
  6. 在Troubleshooting時,透過此次的Observability practice來去觀察應用程式行為,看看能否在最短的時間內找出問題來。
  7. 一旦找到任何潛在的問題,就對照Chaos操作頁上的候選Chaoses的名字,選擇最可疑的那一個將其Kill掉
    1. 由於Chaos的名字直接以他破壞的程式碼區塊進行命名,因此我們能根據他的名字來去進行揣測。
  8. 如果這一次的Kill成功,則Chaos的數量會少一個。反之,則會顯示訊息:”You are mis-killing trip.SaveTripDelay, he is not the mole!”。
  9. 反反覆覆地遊玩,直到將所有Chaos趕盡殺絕為止。
  10. 如果最後發現對於這次的關卡無力以對,則代表Observability practice不夠完整,此時應該要「記下筆記」、「提出對於問題的假說」、「進行修正」、「並再次進行同一個關卡」。
    1. 由於同一個FunValue會被雜湊成同一群Chaoses,我們就能夠重現出同一個關卡,也能夠在同個關卡中不斷練習直到征服為止。

 開始一個新的關卡!

接下來就來正式玩一次關卡吧!

首先到Grafana的Dashboard上,可以看到我開設好的三個基本面板:上方為Metrics,左上為即時的叫車匹配數量,右上為應用程式中的錯誤數量,而下方則顯示即時的Logs。

開始一個新的關卡,這個關卡的FunValue為56a8d709-9c22-489e-b44e-6d86f81796b2

發現叫車流程整個卡住了,看來,Chaos是真的開始在搞破壞了…。

一段時間之後,便在公司的Slack頻道上收到了一個Error Alert,告訴我們是時候執行hot-fix了。

同時也在面板上發現上方叫車匹配的數量急劇下滑,而下方也開始產生出了Error logs。

Troubleshooting

對Waber搜尋 “ERROR” logs,使用Loki的查詢語法:{container=~”waber-broker|waber-match|waber-payment|waber-trip|waber-user”} |~ “ERROR”

    點擊其中一個Error log,並且從Log的衍生欄位traceID,直接開啟右半部Jaeger的Trace畫面。

直接從trace上觀察,可以看到整個微服務的網內互打上半部是順利的,但到下方呼叫 [PATCH] /api/drivers/{driverId} 這個API時發生了錯誤。

同時,觀察這個Trace的執行時間(Duration),竟然高達了12秒!往細部來看會發現瓶頸為 [GET] /api/users/{userId} 這個API。

點擊Span可以看到更多詳細資訊,而從DriverController.setDriverStatus這個方法的Span中可以看見他的exception.message明目張膽地告訴你他就是Chaos!

回到操作頁面上,把對應到的兩個Chaos殺掉:一個為user.SetDriverStatusAPIBlocked,一個為user.FindUserDelay

Kill完兩個壞蛋之後,從頁面上可以看到接下來只剩下2個Chaoses。

從這之後回去看叫車流程,會發現錯誤似乎已經消失,但是整個叫車流程還是卡到不行。

因此接下來必須要來做Performance Tuning了。

這一步,到Jaeger這個Data source上去操作,搜尋在match service中近期的 traces,並且使用執行時間來從大到小排序。

從搜尋結果上來看,會發現一個明顯地效能瓶頸,竟然有一堆trace的總執行時間都高達六秒!點擊左側的TraceId,來導覽到Trace頁面。

注意到FindAvailableDrivers這個使用案例為效能瓶頸,他的執行時間就高達了6秒,這絕對是Chaos搞的鬼。

到Chaos操作頁上將其Kill掉!

接下來我們就只剩下最後一個Chaos了。此時看叫車流程,效能感覺好了一些,但是整個進展還是很緩慢,感覺還是有一些不明確的效能問題存在,我們重複使用相同的手法來排序traces,但這一次我們針對User service。

從這一次的搜尋結果中,我們便注意到了有許多的traces,竟然都花了長達3秒的時間,一樣點選左側的TraceId導覽的Trace頁面。

我們發現了效能的瓶頸可能為UpdateLatestLocation這個使用案例,乘客或司機在旅程行駛中,會不斷地執行這個使用案例來更新自身的座標。如果Chaos在這個使用案例中進行了延遲,也難怪叫車流程會如此緩慢了。

最後,我們就不必留情地把最後一個Chaos給Kill掉吧!

而遊戲的進行到這邊就結束了,我們終於征服了這個關卡…。

遊戲結束後,回去看叫車流程,會發現整個叫車流程的順暢度又回來了!

Waber又再一次地從災難中倖存了下來。

結論

到了這邊,我在LINE擔任SRE實習生的旅程,也算是漂亮地告了一段落了。我藉由DDD的方法,來去設計一個合理且複雜的微服務叫車系統,Waber。

Waber作為Observability的benchmark,其技術以及行為足夠複雜龐大到能夠體現出Observability的好,隨後我對OpenTelemetry進行了Technical Research,發現其在Application-Level Transparency上的成熟度做得十分完整。

最後我設計了我稱之為Reinforcement Chaos-Engineering的方法論,並且為此,在技術上,我藉由Java AoP實現了能夠Activate或是Kill掉Chaos的技術架構。

在擔任SRE成員的這段時間,學到了很多各式各樣的技術,更感謝我的Mentor以及其他成員們會在各個時機點給予適當的幫助,尤其在內部進行Presentation的前幾天,此時正好是禮拜五晚上,這時我才發現內部Cluster中的Jaeger突然不再正常運作了,下週的Presentation該如何是好?

在驚嚇之餘我傳了訊息到Slack上,心裡想著「大家應該都在休息了吧,該怎麼辦才好呢?」

好險SRE的團隊成員,在這種時候依然展現了「Minimized Mean time to repair」的超能力,突然現身回覆我的訊息,並且在數十分鐘內就修好了問題,拯救了我的演講。

而更重要的是SRE團隊非常願意給予我完整的信任來去執行如此特殊的研發工作,在最後的段落上,我想引用Google在其SRE文章中撰寫的名言佳句來作為總結。

“Be warned that being an expert is more than understanding how a system is supposed to work. Expertise is gained by investigating why a system doesn’t work.”

我想,”Observability is more of a culture rather than a practice.” ,下一步則是要好好思考,Observability的工具是否能夠像DevOps一樣慢慢地普及到各個團隊中?

而Reinforcement Chaos-Engineering這一套提早揭露「實踐瑕疵」的方法,是否也能夠被工具化,並且以遊戲化的方式融入軟體開發的生命週期中呢?技術和方法論都是基於學術面上的探討,而在實踐面上,則需要在文化上有更多的著墨。

關於 TECH FRESH 計畫

2021 年的 TECH FRESH 實習生計畫目前正在尋找對技術有熱情、積極解決問題、勇於接受挑戰的優秀同學,目前招募通道已經開啟了,即日起至 2021/07/14,馬上手刀申請送出履歷,下一位 TECH FRESH 就是你!

若想更了解關於這個計畫的內容,歡迎讀者們參閱以下兩篇文章,更多的 FAQ 都已經整理在其中: