APM體系
APM(Application Performance Management )
核心思想是什么? 在服務各節(jié)點彼此調(diào)用的時候,記錄并傳遞一個應用級別的標記,這個標記可以用來關聯(lián)各個服務節(jié)點之間的關系。比如兩個節(jié)點之間使用 HTTP 作為請求協(xié)議的話,那么這些標記就會被加入到 HTTP 頭中。因此如何傳遞這些標記是與節(jié)點之間使用的通訊協(xié)議有關的,有些協(xié)議就很容易加入這樣的內(nèi)容,但有些協(xié)議就相對困難甚至不可能,因此這一點就直接決定了實現(xiàn)分布式追蹤系統(tǒng)的難度。

監(jiān)控對象
-
數(shù)據(jù)維度 從數(shù)據(jù)類型劃分,大體可分為:
- 日志(
logs):自動埋點/手動埋點 - 指標監(jiān)控(
metrics):服務、端點、實例的各項指標 - 調(diào)用鏈(
tracing): 同一TraceId的調(diào)用序列
- 日志(
-
功能維度 從業(yè)務角度劃分,可分為:
- 基礎監(jiān)控 :應用服務的基本性能,物理機/虛擬機的指標
- 中間件監(jiān)控:kafka Db Redis Zk 等依賴項的性能
- 業(yè)務監(jiān)控:根據(jù)業(yè)務需求定制監(jiān)控內(nèi)容

功能模塊
所有現(xiàn)有的解決方案,都需要如下模塊的支持:
? 數(shù)據(jù)采集:如何在廣度和效率上進行數(shù)據(jù)采集 ——> Agent
? 數(shù)據(jù)加工:數(shù)據(jù)統(tǒng)一格式的整理、調(diào)用鏈集合 ——> Collector
? 數(shù)據(jù)存儲:將計算出的指標和聚合鏈路信息實時保存起來 ——> Storeage
? 數(shù)據(jù)展示:高顏值、多功能顯示 ——> UI
Skywalking & Pinpoint 生態(tài)下的四大組件

使用人群

現(xiàn)有的方法
目前的實現(xiàn)方式SkyWalking這種直接使用javaagent技術修改字節(jié)碼來自動埋點;也有類似于cat這種直接編碼進行手動埋點的,雖然方式不同,但是解決的問題相同。
- 收集組件的異構化。開發(fā)語言可能有
java,也可能有golang - 組件的多樣化。從前端埋點開始,nginx、中間件、db等鏈路都需要包含
- 調(diào)用鏈的完整性,技術難點的攻關,如異步、進程間上下文傳遞等
- 時效采樣。尤其在海量調(diào)用時,既要保證準確性,也要保證效率
調(diào)用鏈難題 & OpenTracing
相比較普通監(jiān)控和日志,調(diào)用鏈APM等就復雜的多了。除了有大量的數(shù)據(jù)產(chǎn)生源,也要有相應的業(yè)務組件來支持調(diào)用鏈聚合和展示??此普故镜慕Y果很直接簡答,但是過程卻很復雜。器復雜性主要體現(xiàn)在調(diào)用鏈數(shù)據(jù)的收集上。
如何統(tǒng)一囊括記錄日志、指標和調(diào)用鏈三個維度的數(shù)據(jù)?這是關鍵挑戰(zhàn)。
—— “Dapper, a Large-Scale Distributed Systems Tracing Infrastructure”
關于Tracing的數(shù)據(jù)結構,為了解決不同的分布式追蹤系統(tǒng) API 不兼容的問題,誕生了 OpenTracing(opentracing.io/ ) 規(guī)范。本質(zhì)上說是一套接口定義,主流的調(diào)用鏈服務端實現(xiàn)都兼容此規(guī)范,OpenTracing大有一統(tǒng)天下的架勢,它在其中融合Tracing、Log、Metrics的概念。
目前看標準化是大趨勢(CNCF Jaeger,SpringCloud,Elastic APM),至于國內(nèi)大公司的產(chǎn)品,也都在主動向其靠攏(阿里的鷹眼、聽云、OpenApm)。
系統(tǒng)架構實現(xiàn)方案
整體來說,整個APM體系就是將大三類數(shù)據(jù)(logs、metrics、trace)應用到四大模塊中(收集、加工、存儲、展示),并在四個難點(程序異構,組件多樣,鏈路完整,時效采樣)上不斷優(yōu)化
全開源方案
不同數(shù)據(jù)采取不同采樣數(shù)據(jù)源,過于笨重。依賴過多無法維護
根據(jù)自己的技術棧,DIY APM框架
[Dapper] (https://bigbully.github.io/Dapper-translation/)
通過AGENT生成調(diào)用鏈日志。
通過logstash采集日志到kafka。
kafka負責提供數(shù)據(jù)給下游消費。
storm計算匯聚指標結果并落到es。
storm抽取trace數(shù)據(jù)并落到es,這是為了提供比較復雜的查詢。比如通過時間維度查詢調(diào)用鏈,可以很快查詢出所有符合的traceID,根據(jù)這些traceID再去 Hbase 查數(shù)據(jù)就快了。
logstash將kafka原始數(shù)據(jù)拉取到hbase中。hbase的rowkey為traceID,根據(jù)traceID查詢是很快的。
在框架中引進kafaka:
- 可以削峰填谷,防止大數(shù)據(jù)量的沖擊
- 實現(xiàn)數(shù)據(jù)的多同步,擴展性也提高
PinPoint
利用HBase來存儲實時數(shù)據(jù)
鷹眼
16年開始完全放棄HDFS,引入流式計算 ,改有HBASE列存儲。

SkyWalking
在Apache“云原生”生態(tài)中的布局

部署框架

方案對比
| 方案 | skywalking | cat | pinpoint | zipkin |
|---|---|---|---|---|
| 依賴 | Java 8+ maven3.0+ nodejs zookeeper/k8s elasticsearch | Java 6 7 8、Maven 3+ MySQL 5.6 5.7、Linux 2.6+ hadoop可選 | Java 6,7,8 maven3+ Hbase0.94+ | Java 6,7,8 Maven3.2+ rabbitMQ |
| 實現(xiàn)方式 | java探針,字節(jié)碼增強 | 代碼埋點(攔截器,注解,過濾器等) | java探針,字節(jié)碼增強 | 攔截請求,發(fā)送(HTTP,mq)數(shù)據(jù)至zipkin服務 |
| 存儲 | elasticsearch , H2 | mysql , hdfs | HBase | in-memory , mysql , Cassandra , Elasticsearch |
| jvm監(jiān)控 | 支持 | 不支持 | 支持 | 不支持 |
| trace查詢 | 支持 | 支持 | 需要二次開發(fā) | 支持 |
| stars | 13k | 13.1k | 10.2k | 12.7k |
| 侵入 | 低, 也可以手動埋點 | 高,需要埋點 | 低 | 高,需要開發(fā) |
| 部署成本 | 較低,集群部署需要中間支持 | 中 | 較高 | 中 |
| 數(shù)據(jù)導出 | 需要開發(fā),ES 支持分索引定時導出 | 不容易,hdfs 太重 | HBase 實時同步較容易 | 較容易 |
| 定制化監(jiān)控 | 基于端口可以支持,再細粒度需要二次開發(fā) | 支持,手動埋點來實現(xiàn) |
SkyWalking
功能展示
SkyWalking是分布式系統(tǒng)的應用程序性能監(jiān)視工具,專為微服務、云原生架構和基于容器(Docker、K8S、Mesos)架構而設計
演示地址:
集成方式
-
agent 自動無侵入埋點
JVM參數(shù)中添加 -javaagent:/path/to/skywalking-package/agent/skywalking-agent.jar,并且確保這個參數(shù)在-jar參數(shù)之前。
-
注意 需要和agent包一起使用
java -javaagent:/Users/rongxin.srx/Downloads/apache-skywalking-apm-bin/agent/skywalking-agent.jar \ -DSW_AGENT_NAME=sw-test-demo-app \ -Dskywalking.collector.backend_service=<ip>:<port> \ -Dspring.profiles.active=local,nosso \ -jar is-kcloud-1.0-SNAPSHOT.jar
提供SDK 手動埋點
服務端功能
性能大盤
服務依賴拓撲
請求調(diào)用追蹤
性能采樣分析
業(yè)務告警
指標對比
需要解決的問題
-
大數(shù)據(jù)量下穩(wěn)定性
缺乏數(shù)據(jù)緩沖池,需要引入MQ
依賴ES的穩(wěn)定性 (ES可能出現(xiàn)性能抖動)
可擴展性,ES中的數(shù)據(jù)不易導出 ,進行多備份 (考慮使用多方監(jiān)聽MQ中的數(shù)據(jù),進行備份)
二次開發(fā):agent插件開發(fā)比較專業(yè),服務端邏輯復雜,需要時間消化