Elastic APM Agents 的任務主要有兩件事:
要做到以上的兩件事,代表我們需要程式運作時,收集這兩種的資訊,以下分別針對這兩種情境來說明一般的做法。
要分析某段程式運作效能時,最簡單與古老的做法,就是在程式開始時,先記錄當下的時間,在程式結束之後,記錄結束的時間,也因為這種需求太普遍,各種語言當中的 Framework 或 Library 也都有支援這種計算 time elapsed
的工具,不過當記錄這些 Performance Metrics 時,常會有以下的問題:
time elapsed
的地方,才收集得到數據』,但是要埋的地方可能有非常多,一開始不會都埋好,實務上常常會變成『發生問題時,才改 code 來埋 log、重新出 build、deploy、想辦法讓問題再次發生時,取得 log 』,這樣會變成是背動的狀況,甚至遇到不容易 reproduce (重製) 的例外狀況時,也會很不容易收集到能協助判斷及解決問題的資訊。使用例如 try
catch
等 Error handling 的方法,並且在錯誤發生時寫 Logs,而這樣的做法常會遇到:
Elastic APM Agent 在協助收集 Performance Metrics 時,提供幾種的方式:
也可以稱為 Build-in Instrumentation (內建檢測),不論是哪種程式語言,在開發的時候常會使用各種 Framework,並且在 Framework 透過已經建立好的一些機制,例如:HTTP 請求的處理、Database 的存取,Logging 的機制、Scheduling (排程) 的功能…等。
APM Agents 在各種語言的支援上,都有盡量整合最熱門的一些 Framework,讓使用者簡單的設定後就能直接使用,自動依照 Framework 的功能,收集相關的資訊,並且以結構化的方式,將收集到的數據的格式定義在 Elastic Common Schema 之中。
在沒有使用支援的 Framework 的時候,APM Agents 也有提供 Instrument (檢測) 資料收集的工具,讓使用者能很簡單的將自己程式中要觀察的某個處理行為,能包裝成為 Transaction
或 Span
,並且透過已經定義好的架構與提供的 Utility,能輕易的收集 Performance 相關的 Metrics 並且加上要額外記錄的資訊,並且由 APM 幫我們將這收集到的事件,與其他前後的事件連結在一起。
APM Agents 在運作時,會在背景定期的收集系統的 Metrics,能夠配合我們所收集的 Transaction
或 Span
的資訊,來協助掌握某個要觀察的時間點,系統整體的狀況。
目前有支援的語言,後端相關的如下:
前端相關的有兩個
以下使用 Golang 為例:
Elastic APM
套件go get -u go.elastic.co/apm
import (
"go.elastic.co/apm/module/apmgin"
)
func main() {
engine := gin.New()
engine.Use(apmgin.Middleware(engine))
...
}
ELASTIC_APM_SERVER_URL
:APM Server 的位置ELASTIC_APM_SERVICE_NAME
:目前的服務名稱,這個會是之後在 APM UI 中用來識別服務的重要設定。ELASTIC_APM_ENVIRONMENT
:目前的 Environment,這也是在 Kibana APM UI 中篩選的主要功能之一。ELASTIC_APM_GLOBAL_LABELS
:有一些自訂的 Labes 是屬於全域型的,也就是在這個服務裡全都要加上的,可以定在這裡。建立自己定義的 Transaction
:
tx := apm.DefaultTracer.StartTransaction("GET /api/v1", "request")
defer tx.End()
...
tx.Result = "HTTP 2xx"
tx.Context.SetLabel("region", "us-east-1")
在 Transaction
當中加上 Span
:
span, ctx := apm.StartSpan(ctx, "SELECT FROM foo", "db.mysql.query")
defer span.End()
由於每一種語言實作的方式都會有些不同,每一種 Framework 的行為有不同時,支援的方式也會有所差異,以上只是最簡短介紹 APM Agents 的使用方式,讓大家有個感覺,詳細的使用方式,請參考 官方文件 - APM Agents [1] 每個語言的版本。
APM Agents 在運作時,一定會佔用到原本服務需使用的系統資源,這些處理會使用到:
另外再從兩個部份來分析:
另外 APM Server 如果無法正常接受 APM Agents 所傳送的資料時,APM Agents 最終會選擇放棄傳送,設計上也是以不影響原本服務執行為主。
特別注意:先前專案的團隊實際在使用 PHP 版本的 APM Agents 時,在壓測時有明確的因為加上 APM Agents 後,原本服務的 QPS 下降將近一半,猜測和 PHP 的實作版本沒有實作 async call 可能有關,若有使用 PHP 版本的話會需要特別留意。
既然使用 APM Agents 收集 Instruments 數據時,一定會佔用到系統的資源,也就是多少都會影響到原本服務的效能,這時候 Sample Rate (取樣率) 就是一個很重要的設定,不過這個值沒有一定的標準,但是在量級非常大的系統之中,1 ~ 3% 的取樣率一般已經足夠有一定的代表性,也就是若是有問題發生時,一般都會能取得到樣本,當然這個設定值還是會依照使用的情境與硬體的規格需進行壓測及調整。
capture_header
、 capture_body
,這個在 Sample Rate 較高、量級較大的環境之中,應該考慮關掉 capture_body
,這個會於效能會有明顯的影響。span
,這種情況應該設定好 transaction_max_span
來避免這種意外發生。api_request_time
、或是每批的大小 api_request_size
。查看最新 Elasticsearch 或是 Elastic Stack 教育訓練資訊: https://training.onedoggo.com
歡迎追蹤我的 FB 粉絲頁: 喬叔 - Elastic Stack 技術交流
不論是技術分享的文章、公開線上分享、或是實體課程資訊,都會在粉絲頁通知大家哦!