---
title: "TGONext: 追蹤和技術債"
date: 2020-05-11T00:00:00+08:00
publishDate: 2020-05-11T00:19:35+08:00
lastmod: 2022-01-17T14:20:52+08:00
tags: ["心得","TGONext","架構"]
series: "TGONext"
toc: true
permalink: "https://blog.aotoki.me/posts/2020/05/11/TGONext-Tracing-and-Technical-Debt/"
language: "zh-tw"
---


在 TGONext 期間我們基本上有 4 ~ 5 次的聚會，而這次算是表定上的最後一次聚會。在可能是最後一次的聚會，我們先討論了幾個原本沒有要討論的主題。

這次聚會中，我們會討論關於日誌追蹤跟如何處理技術債。

<!--more-->

## 日誌追蹤 {#log-tracing}

會討論這個是因為我們之中有人在工作中對於日誌蒐集這件事情有一些疑問。

### 蒐集 {#collection}

在大多數情況下會選擇直接將日誌放到本機端的硬碟，不過當我們的服務成長後這反而變得很難從日誌中進行除錯。

在我的公司，基本上我們因為客戶基本上只有單一伺服器所以會把紀錄放在本機上。或者我們會讓我們的客戶將紀錄上傳到一些第三方的 SaaS 服務來節省建置日治伺服器的時間。實際上我們也已經有非常方便的工具可以選擇，像是 AWS 的 CloudWatch 或者 [Papertrail](https://www.papertrail.com/) 都可很容易的整合到 Rails 上。

### Open Tracing

當整個服務的數量成長之後，單純的日誌也不再足以去追蹤整個系統，而且我們會需要更多資訊去了解我們的系統。

Open Tracing 是一個標準定義了該如何追蹤我們的系統. 我們可以選用 [Jagger](https://www.jaegertracing.io/) 或者 [Zipkin](https://zipkin.io/) 這類支援 Open Tracing API 的工具。

> 選用 Open Tracing 可能會是個不錯的選擇，大多數商業解決方案都已經支援 Open Tracing API 也因此我們可以輕易的在他們之間切換。

### Application Performance Monitor

我們可以視為這是 Open Tracing 的一部分，他提供我們追蹤 Function Call 或者 API Call 的花費時間。在我的經驗中，一些商業解決方案像是 [Datadog](https://www.datadoghq.com/), [NewRelic](https://newrelic.com/)、[ScoutAPM](https://scoutapm.com/) 和其他服務，都提供我們更多詳細的資訊來幫助我們可以追蹤效能上的問題。

不過開源的專案像是 [ElasticAPM](https://www.elastic.co/apm) 就有比較多限制以及追蹤的資訊相對的簡單。

> 在商業解決方案大多支援記憶體的追蹤而且對記憶體問題的處理非常有幫助，不過像是 ElasticAPM 就還在計畫中而沒有支援。

### 時間 {#time}

在我們分享經驗跟工具後，我們的導師點出了一個追蹤工具的關鍵點。

當我們使用這些工具追蹤服務時，他大多是跟時間相關的。為了避免網路延遲，這些工具大多會選擇使用本地的時間當作時間戳記然後發送到追蹤伺服器上。

這表示如果我們有兩台機器的時間是不同步的，我們就會得到一個錯誤的時間線從而導致我們在儀表板上看到的錯的資訊。

舉例來說，我們有三個 API 呼叫（A => B => C）在這個追蹤內，其中一個 API 伺服器（B）有錯誤的本地時間。我們可能會發現 B 在時間線上早於 A，但是這跟實際上的順序是不一致的，這就可能造成我們無法準確的追蹤問題。

### 儀表板 {#dashboard}

另外一個重要的點則是儀表板，我們想要在短時間內找到問題通常仰賴一個設計優良的儀表板去幫助開發者追蹤問題。

這也是為什麼商業解決方案相對開源專案還成熟很多，而在自己搭建的方案中會選擇 ElasticSearch 來作為解決方案。

建構一個強大的儀表板是不容易的，何況追蹤大多不是在產品開發中最優先的事項。

這也是為什麼大多會偏向使用 SaaS 或者現有的開源方案。

## 技術債 {#technical-debt}

這部分我們分享了我們在決定重構或者安排解決技術債的經驗。

我想我們大多同意這沒有一個正確的解答，不過我們還是有一些方向可以遵循。

### 測試 {#the-test}

為了解決技術債，我們大多會去重構我們的程式碼。而重構重程式碼就會需要透過測試來保證不會破壞任何東西。

在我自己的經驗裡「規格」是很重要的。如果我們沒有正確的規格，測試也只會專注在錯誤的目標從而撰寫出一些沒有幫助的測試。

### 已知跟未知的技術債 {#the-known-and-unknown-debt}

在工作中，我們通常不會有足夠的時間去撰寫一些理想的程式碼。這表示即使我們不想產生技術債，我們還是因為時間的限制被迫留下技術債。

在這個情況，我們通常會加入 `TODO` 作為註解表示我們需要去重構他，在另一方面，我們也可能撰寫了一些不恰當的程式而沒有自覺。

為了解決技術債，我們大多同意去「主動」的消除他們，至於未知的部分也只能等待他被發現的時候再去處理。

不過「追蹤」其實能夠幫助我們更快找到隱藏的問題，這剛好和我們前面討論的部分互相呼應。

> 程式語言的版本太舊是另外一種情況會造成技術債。當程式語言被改善或者升級後，可能會放棄掉一些語法，而這可能會導致我們無法繼續使用舊的程式碼在新版本的程式語言中繼續使用。

### 溝通 {#the-communicate}

在最後，我們的導師基於他的經驗給了我們一些總結。

造成技術在的原因通常是因為行銷或者產品團隊的需求，不過這些需求能幫助公司產生更多價值。

如果我們希望有時間去處理技術債就需要跟他們解釋其中的優缺點。

不過開發團隊的要求大多被拒絕，因為他們大多很難理解重構的重要性。

為了解決這個問題，我們需要將資訊轉換成相同的單位讓其他團隊能夠比較從而理解。

舉例來說，我們可以解釋重構將能夠改善 10% 未來在宣傳工能上的開發時間，這能夠讓行銷團隊更快的去推廣他們的新產品。不過這會需要付出 50% 的時間在這一次的開發上一併重構這個功能。

如果行銷團隊認為這個價值高於繼續維持現在的方法去加入新的宣傳功能，那們我們就會得到他們的支持來進行重構。

## 總結 {#conclusion}

實際上這次聚會比其他聚會還短了一些，不過在這幾次的聚會中我們大致上將我們希望討論的主題都討論了一遍。

在這些聚會中，我認為我學到了兩個重要的事情。第一個是要嘗試去找到我們正在評估的架構中的關鍵或者目標，這再讓我們選擇適合的解決方案跟避免他的缺點影響我們系統佔了很重要的角色。

另一個就是溝通技巧，實際上在我的工作中我是很重視的。不過我仍只有在跟工程師有嘗試做好，對於客戶或者非工程師的夥伴還是沒有辦法做得很好。在大多數情況下，我是希望 PM 能幫我做好這件事情，不過這個技能在我需要向非工程師解釋技術問題時就變得很重要。

