Elastic APM 上報數據分析(鏈路跟蹤)與應用


在入正題之前我們再回顧下它的架構圖:

本文章主要分析AMP各索引的作用,與及結合1.7環境上已接入的服務數據對比后,對索引中的主要字段進行解析。文章分為四個小章節。

1、索引類型

apm索引分為四種類型:

系統指標索引(System status metrics),索引名稱格式:apm-version-metric-yyyy.dd.mm,主要儲存進程資源指標,如:內存信息、cpu信息、gc信息等。

具體異常索引(Error-specific data),索引名稱格式:apm-version-error-yyyy.dd.mm,主要存儲進程error級別的經過json格式化后的異常信息棧。

跨度(或鏈路)索引(Span-specific data),索引名稱格式:apm-version-span-yyyy.dd.mm,主要存儲跨本進程調用鏈的信息,如:代碼執行鏈、跟蹤id,跨度id,跨度類型、跨度用時等。特別指出的是這個索引的數據是形成整個事務、鏈路的一部分。

事務索引(Transaction-specific),索引名稱格式:apm-version-transaction-yyyy.dd.mm,主要存儲事務的持續時間,單位微妙(PS:這里的事務跟TPS同一個概念:指一個客戶機向服務器發送請求到服務器做出相應的過程,這里除了客戶機請求之外,還包括內部的執行任務,如:定時任務),如:進程id,TPS值,事務類型,發生時間,請求接口。

ps:以下標紅字段是個人認為比較有價值的字段。

2、索引字段說明

這些索引中,有很多字段都是公共的,所以我在其中某個索引中提及到了,在其它索引就不再單獨做說明項了。

2.1、系統指標索引

 jvm.memory.non_heap.committed

java進程非堆的內存空間可用大小,單位是bytes。針對jdk8以上就是元空間大小。

jvm.memory.non_heap.max

 java進程非堆的內存空間最大值,單位是bytes。針對jdk8以上就是元空間最大值。由系統參數:MaxMetaspaceSize設置

jvm.memory.heap.max

java進程堆內存最大值,由系統參數-Xmx設置

jvm.memory.heap.used

java進程堆內存使用量,單位字節

jvm.memory.heap.committed

java進程堆可用內存大小,它的值一般為大於或等於已使用大小,小於等於最大內存空間,小於是因為Xms與Xmx設置不一樣,為了系統內存不波動,建議設置初始值和最大值一樣。

jvm.memory.non_heap.used 

 java進程非堆已使用大小

 jvm.thread.count

JVM中當前活動線程的數量

jvm.gc.alloc

代碼中是計算java進程所有線程使用的內存總量(包括已死去的線程),但是字面理解是堆內存中分配的內存總量相當於heap.max,個人認為性能調優上沒什么參考價值

process.pid

對應的終端進程id

processor.name

代表事件類型:metric
processor.event

代表事件類型:metric

process.title

jdk安裝目錄

service.name

對應的終端服務名稱,就是elastic.apm.service_name參數指定的值

service.runtime.name

運行環境,如是java進程該值就是java

service.runtime.version

jdk版本

host.ip

終端進程所有服務器ip

jvm.gc.count

jvm垃圾收集次數

jvm.gc.time

每次GC使用時間,單位是毫秒

labels.name

GC方式:如G1 Young Generation或G1 Old Generation

@timestamp

收集時間

system.process.memory.size

進程占用的虛擬內存

system.process.cpu.total.norm.pct

自上次上報以來該進程占用CPU的百分比。需要乘以100%。

system.cpu.total.norm.pct

自上次上報以來終端所在的機器當前cpu的使用率,需要乘以100%

system.memory.actual.free

操作系統當前可用內存(字節),由空閑內存加緩存和緩沖區組成

system.memory.total

操作系統總內存

字段使用分析:

從以上索引字段解析可以讓我們實時了解該進程所在機器的ip、當前cpu的使用率、內存使用率、被監控進程的堆、非堆內存分配情況、內存使用率、cpu使用率、GC次數、GC使用時間、GC類型。比如:生產上內存分配一般是4GB,如果分配低於1GB我們可以當成一項告警指標,知道了配置的總內存和使用內存,又可以算出內存使用率,那么當內存使用率達到90%即可做出告警事件,GC使用時間、頻率。GC的用時和頻率沒有什么標准來衡量,根據服務實際情況來優化,能滿足當前需求和體驗感能接受即可,但以我們目前服務部署的情況來分析,高發很少突破100以上的情況下,每個服務內存都不超過4GB的,比較合理的YGC一分鍾內不能超過10次,每次不能超過20毫秒,FGC應該0次出現。可以以這個目標來優化靠攏。(下次我會寫一篇關於G1里為什么能讓我們指定時間內完成GC——啟發式算法)

2.2、異常索引

 parent.id

指向父節點的id,意思是上個服務請求的標識id,用於服務之間異常調用鏈路跟蹤

transaction.id

事務id,這里的事務不是數據事務,代表一個完整的請求流程或一個內部任務。用於異常事件鏈路跟蹤,結合數據看與parent.id值相同,說明代表服務id並不是固定死

error

異常棧

error.exception.message

拋出的異常信息,如:xxx屬性為空、500 Server Error、The user specified as a definer ('test_seq'@'%') does not exist

error.exception.type

異常類型,如:java.lang.RuntimeException、com.segi.uhomecp.ifs.activiti.exception.WorkFlowException、java.sql.SQLException

error.culprit

異常發生的根源,就是哪個類里的哪個方法哪行代碼發生的異常。如:com.segi.uhomecp.redis.RedisUtil$18.execute(RedisUtil.java:444)

error.id

此次異常事件的標識id

error.grouping_key

異常分組id,按error.exception.type分組

processor.name、processor.event

事件類型和名稱是同個東西,就是代表span、error、還有metris

observer.hostname

apm服務的主機名

observer.type

默認都是apm-server

observer.version

apm服務版本號

observer.version_major

apm服務主版本號

trace.id

跟蹤id

host.hostname

被監控的終端服務主機名

transaction.type

此事代碼被執行的方式,意思是被http請求還是內部執行的定時任務。如:request、scheduled

transaction.sampled

 監控數據事件是否包含跨度、上下文等全部相關信息,默認是true

timestamp.us

事件發生時間,微妙

url.path

接口uri,如:/lease-stat/admin/businessSummary/list

url.scheme

url類型,如果是http.其值就是:http,非http為空

url.port

接口對應的端口

url.domain

接口對應的ip或域名

url.full

接口完整url

http.request.method

請求方式,get或post,非http為空

http.response.status_code

http相應狀態碼,如:500

還有些一些用戶http請求的信息字段,如:瀏覽器,用戶終端類型,http版本等。

數據結構圖:

字段使用分析:

好了,經過我們分析了這個索引的核心相關字段后。就可以知道這個索引能給我們解決什么問題了,首先最有價值的是error異常棧,我們碼農級別最喜歡看的東西都這error doc里,從異常棧我們可以分析出錯的原因,error.culpri觸發異常的地方,除了這些信息我們從中還可以知道:異常接口、異常的服務進程、異常服務ip、http異常狀態碼、關連的異常鏈路。

2.3、跨度索引

span.id

跨度標識

span.stacktrace

這個是跨度調用鏈,記錄了調用的文件名,調用行,調用方式等信息

span.duration.us

跨度耗時,單位微妙,這個時間是記錄span.stacktrace內調用棧的用時。跨度是什么意思呢? 是指除了本進程內調用之外都算是跨度調用,比如:數據庫操作、調ice等

span.type

跨度類型,數據庫就是db,http就是external,相對subtye,它細粒度大些。

span.subtype

跨度調用子類型,有http、mysql、tcp(占不支持)等

span.name

給這個跨度調用取的簡單名稱。如:SELECT FROM ACT_RU_EXECUTION、SELECT、POST 192.168.1.7

span.action

跨度事件類型,像數據庫查詢,類型就是query

字段使用分析:

這個索引最有價值的調用鏈了:span.stacktrace和執行過程中所花的時間

2.4、事務索引

transaction.duration.us

整個流程的處理時間,單位微妙,這個時間包含了跨度時間在內

transaction.name

整個事務的名稱,用接口名、方法入口名來命

span_count

記錄跨度數

字段使用分析:

transaction.duration.us是整個請求過程所使用的時間,可以根據這個時間推斷出指定該接口所在的服務,所屬的進程的性能,還有schemes類型,根據這個可以判斷是不是http請求,這個索引的數據主要是結合跨度索引一起使用。

 

2.4、鏈路跟蹤

兩個應用之間的調用關系怎么關聯起來的呢?transaction和span又有什么關聯關系呢?在machine learning中調用鏈是怎么關聯起來的?

在解答數據關聯關系之前,我們做這樣的測試:分別監控三個服務:sample1、sample2、sample3。其中sample1的SampleController#list調sample2的SampleController#list(對應的http接口:../sample2/list2)調sample3的SampleController#list(對應的http接口:../sample3/list3)

服務名稱 接口函數 調內部函數 http接口 調用接口
sample1 SampleController#list
aaabb
../sample/list ../sample2/list2
sample2 SampleController#list
aaabb
../sample2/list2 ../sample2/list2
sample3 SampleController#list
aaabb
../sample2/list2

  測試步驟:

 

  • 直接在瀏覽器地址欄請求 sample1接口../sample/list
  • 查看這時上來的索引數據(transaction和span)

圖一:

圖二:

說明:1、圖一,一次請求生成了三條 transaction數據,每條數據對應一個服務,每條都有自己唯一對應的transactionid,transaction的記錄其實是對應一個服務處理一個請求開始到響應的信息收集,細粒度比span大

         2、圖一,每條數據的traceid都是相同,說明是同個請求

         3、圖一,每條都有parentid字段,但第一個服務為空,點開內容查看http相關字段和url,會發現就是我們瀏覽器請求的../sample/list,parentid為空就是鏈路的起點,即trace root

         4、圖二,總共有8條數據,為什么呢?span是函數調用棧的收集信息,每進入函數都會創建一個並開始一個span,到退出時,會結束span。因為sample1和sample2除了有接口函數list之外,還有內部的aaabb和去調下個服務            接口的函數。所以sample1和sample2會產生三條span數據,而sample3只有接口函數list和內部函數aaabb。所以sample3只有兩條span數據

        5、那么transaction和span有沒有關聯呢?又是怎么關聯的呢? 答案是有的,transaction的id可以是span的parentid,span的id也可以是transaction的parentid。怎么解釋呢?首先一個http請求進來,創建一個transaction對象            (數據) ,該對應就是鏈路的根,parentid為空。然后執行對應的接口函數(SampleController#list) 會創建第一個span(數據),此時該span的parentid就是transaction的id,同時這個請求關聯的span(同個transaction) 的                        transactionidid都是該transaction對應的id,  如上圖一和二的transactionid=aa194e9568b40954,即是第一個span的parentid同時也是transactionid。那么什么時候span的id是transaction的parentid呢?

        6、我們看看上圖spanid=34d55c4d4a1501fd的sample2服務數據,它的subtye是Http,說明是向外發出http請求,那么進入下第個服務(sample3),我們說過transaction創建是一個服務被請求開始。此時span會把id放到head,          傳給下一個transaction,transaction把該span的id做為它的parentid。如下圖spanid=34d55c4d4a1501fd的sample2數據,對應的sample3的transaction的parentid:

       

 

     

3、實踐應用

經過了一翻上報索引數據的分析后,我們來實踐一下。

  1. 首先為每個接入服務名稱定義規范
    apm監控是以進程為目標。如果要接入多個服務的情況下,要分辯某個或哪些服務是做什么的,比較難辨別出來了。所以需要為每個接入監控服務的名稱統一定義一個命名規范。
    所以我們統一規定服務監控名稱格式為(服務名稱必須符合此正則表達式: ^[a-zA-Z0-9 _-]+$ . 用較少的regexy術語:您的服務名稱只能包含ASCII字母,數字,短划線,下划線和空格中的字符):segi-環境-業務組名稱-服務名稱-服務所在的機器ip,如:segi-saas-lease-uhomecp-lease-220。

現成的界面指標分析

  1. 默認主界面(services):

  2. 說明:第一列是被監控的服務名稱,就是對應上面我們給他命的名稱 ;第二列被代監控的環境;第三列是每個監控服務平均響應時間(對所有請求作出響應所需要的時間平均值,其接近於所有TPM總和的平均);每三列是每分鍾事務處理數;第四列是每分鍾發生異常數。
     在這順便科普下幾個衡量一個服務的性能指標:TPS、並發數、響應時間
    TPS:每秒傳輸的事物處理個數,即服務器每秒處理的事務數。包括一條消息入和一條消息出。
    並發數: 系統同時處理的request(或事務)數
    響應時間: 對請求作出響應所需要的時間,一般取平均響應時間(響應時間:網絡傳輸時間:N1+N2,應用服務器處理時間:A1+A3,數據庫服務器處理時間:A2,響應時間=N1+N2+N4+A1+A3+A2)
    這三者之間的關系:並發數 =  TPS*平均響應時間

    有用指標:平均響應時間:從這個直接看出服務的性能等級:毫秒級別的響應屬於非常有吸引力的用戶體驗;2秒之內給用戶是不錯的體驗;3秒之內可以接受;5秒之內遭用戶嘆氣;10秒之內60%用戶不使用;大於10秒90%以上用戶選擇離開。

    EPM:直接反映服務使用穩定性,出現error直接影響服務的使用。

  3. traces界面

    說明:這個鏈路界面跟服務界面指標差不多。展示的是所有服務的所有http接口的響應時間、TPM、接口訪問頻率
    有用指標:平均響應時間
  4. 服務界面
    圖一:

    圖二:

    圖三:

    說明:圖一,服務的事務監控,可以看出這個服務下的每個接口的事務處理平均時間、第95百分位,每分鍾處理事務數、訪問頻率、每分鍾的訪問量。有用指標:第95個百分位(是統計學的一個術語,可以理解為有5%的請求超過多少時間),通過這個值我們可以直接看出這個接口的性能,比如:95百分位數是1,560ms的,那么意味着有5%的請求接口事務處理時間超過這個值,這個指標的意義是:反映服務(上面的波浪線圖就是整個服務的95th)或接口的穩定性,如果在不同的時間段內95百分位數的值波動不大說明接口沒有問題,如果不同時間段內波動越明顯,就越能夠放大問題,主要用於性能分析,而接口平均處理時間就可以直接反映該接口的性能,我們可以按上面的響應時間做為標准來優化
    圖二,是反映異常信息,主要有異常簡單信息、在選定的時間段內發生的異常次數(如上面的5K,就是5千次)、最后一次發生的時間,異常的指標都是有用的了。
    圖三,這個監控界面所展示的指標個人認為是最為主要的了,直接能反饋這個服務的使用性問題,服務所在機器的資源問題、服務本身的資源問題。由於上面的一些指標已經說明過,這時就只解釋CPU使用和內存使用,以及它的意義。
    cpu使用圖分別有這些指標:服務所在的主機cpu的最大使用率、平均使用率、服務本身占主機的最大使用率、平均使用率,這些指標都是有用指標,比如我選在一天內,這個機器的cpu使用波動很大,那么這個機器就有問題,同理服務本身的cpu使用也是一樣;內存使用圖指標:服務所在機器內存使用最大值,和平均值。這里我們還可以自己加入服務進程本身的jvm內存最大值、使用率指標,還有GC圖展示:GC次數、用時、GC類型。
  5. 鏈路界面

    說明:這個界面主要是反映我們監控的接口內部服務調用鏈(包含跨度), 接口處理總時間、和每個調用的耗時,主要作用:為開發人員調性能接口提供幫助。

4、高級應用 

制作我們的儀表板:

通知告警:

【版權聲明】

本文版權歸作者(深圳伊人網網絡有限公司)和博客園共有,歡迎轉載,但未經作者同意必須在文章頁面給出原文鏈接,否則保留追究法律責任的權利。如您有任何商業合作或者授權方面的協商,請給我留言:siqing0822@163.com

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM