监控url_熬夜之作:一文带你了解Cat分布式监控
Cat 是什么?
CAT(Central Application Tracking)是基于 Java 開(kāi)發(fā)的實(shí)時(shí)應(yīng)用監(jiān)控平臺(tái),包括實(shí)時(shí)應(yīng)用監(jiān)控,業(yè)務(wù)監(jiān)控。
CAT 作為服務(wù)端項(xiàng)目基礎(chǔ)組件,提供了 Java, C/C++, Node.js, Python, Go 等多語(yǔ)言客戶端,已經(jīng)在美團(tuán)點(diǎn)評(píng)的基礎(chǔ)架構(gòu)中間件框架(MVC 框架,RPC 框架,數(shù)據(jù)庫(kù)框架,緩存框架等,消息隊(duì)列,配置系統(tǒng)等)深度集成,為美團(tuán)點(diǎn)評(píng)各業(yè)務(wù)線提供系統(tǒng)豐富的性能指標(biāo)、健康狀況、實(shí)時(shí)告警等。
CAT 很大的優(yōu)勢(shì)是它是一個(gè)實(shí)時(shí)系統(tǒng),CAT 大部分系統(tǒng)是分鐘級(jí)統(tǒng)計(jì),但是從數(shù)據(jù)生成到服務(wù)端處理結(jié)束是秒級(jí)別,秒級(jí)定義是 48 分鐘 40 秒,基本上看到 48 分鐘 38 秒數(shù)據(jù),整體報(bào)表的統(tǒng)計(jì)粒度是分鐘級(jí);第二個(gè)優(yōu)勢(shì),監(jiān)控?cái)?shù)據(jù)是全量統(tǒng)計(jì),客戶端預(yù)計(jì)算;鏈路數(shù)據(jù)是采樣計(jì)算。
Github: https://github.com/dianping/cat
Cat 功能亮點(diǎn)
- 實(shí)時(shí)處理:信息的價(jià)值會(huì)隨時(shí)間銳減,尤其是事故處理過(guò)程中
- 全量數(shù)據(jù):全量采集指標(biāo)數(shù)據(jù),便于深度分析故障案例
- 高可用:故障的還原與問(wèn)題定位,需要高可用監(jiān)控來(lái)支撐
- 故障容忍:故障不影響業(yè)務(wù)正常運(yùn)轉(zhuǎn)、對(duì)業(yè)務(wù)透明
- 高吞吐:海量監(jiān)控?cái)?shù)據(jù)的收集,需要高吞吐能力做保證
- 可擴(kuò)展:支持分布式、跨 IDC 部署,橫向擴(kuò)展的監(jiān)控系統(tǒng)
為什么要用 Cat?
場(chǎng)景一:用戶反饋 App 無(wú)法下單,用戶反饋無(wú)法支付,用戶反饋商品無(wú)法搜索等問(wèn)題
場(chǎng)景一的問(wèn)題在于當(dāng)系統(tǒng)出現(xiàn)問(wèn)題后,第一反饋的總是用戶。我們需要做的是什么,是在出問(wèn)題后研發(fā)第一時(shí)間知曉,而不是讓用戶來(lái)告訴我們出問(wèn)題了。
Cat 可以出故障后提供秒級(jí)別的異常告警機(jī)制,不用再等用戶來(lái)反饋問(wèn)題了。
場(chǎng)景二:出故障后如何快速定位問(wèn)題
一般傳統(tǒng)的方式當(dāng)出現(xiàn)問(wèn)題后,我們就會(huì)去服務(wù)器上看看服務(wù)是否還存活。如果存活就會(huì)看看日志是否有異常信息。
在 Cat 后臺(tái)的首頁(yè),會(huì)展示各個(gè)系統(tǒng)的運(yùn)行情況,如果有異常,則會(huì)大片飄紅,非常明顯。最直接的方式還是直接查看 Problem 報(bào)表,這里會(huì)為我們展示直接的異常信息,快速定位問(wèn)題。
場(chǎng)景三:用戶反饋訂單列表要 10 幾秒才展示,用戶反饋下單一直在轉(zhuǎn)圈圈
場(chǎng)景三屬于優(yōu)化相關(guān),對(duì)于研發(fā)來(lái)說(shuō),優(yōu)化是一個(gè)長(zhǎng)期的過(guò)程,沒(méi)有最好只有更好。優(yōu)化除了需要有對(duì)應(yīng)的方案,最重要的是要對(duì)癥下藥。
所謂的對(duì)癥下藥也就是在優(yōu)化之前,你得先知道哪里比較慢。RPC 調(diào)用慢?數(shù)據(jù)庫(kù)查詢慢?緩存更新慢?
Cat 可以提供詳細(xì)的性能數(shù)據(jù),95 線,99 線等。更細(xì)粒度的就是可以看到某個(gè)請(qǐng)求或者某個(gè)業(yè)務(wù)方法的所有耗時(shí)邏輯,前提是你做了埋點(diǎn)操作。
Cat 報(bào)表
Cat 目前有五種報(bào)表,每種都有特定的應(yīng)用場(chǎng)景,下面我們來(lái)具體聊聊這些報(bào)表的作用。
Transaction 報(bào)表
適用于監(jiān)控一段代碼運(yùn)行情況,比如:運(yùn)行次數(shù)、QPS、錯(cuò)誤次數(shù)、失敗率、響應(yīng)時(shí)間統(tǒng)計(jì)(平均影響時(shí)間、Tp 分位值)等等場(chǎng)景。
埋點(diǎn)方式:
public void shopService() { Transaction transaction = Cat.newTransaction("ShopService", "Service"); try { service(); transaction.setStatus(Transaction.SUCCESS); } catch (Exception e) { transaction.setStatus(e); // catch 到異常,設(shè)置狀態(tài),代表此請(qǐng)求失敗 Cat.logError(e); // 將異常上報(bào)到cat上 // 也可以選擇向上拋出: throw e; } finally { transaction.complete(); }}可以在基礎(chǔ)框架中對(duì) Rpc, 數(shù)據(jù)庫(kù)等框架進(jìn)行埋點(diǎn),這樣就可以通過(guò) Cat 來(lái)監(jiān)控這些組件了。
業(yè)務(wù)中需要埋點(diǎn)也可以使用 Cat 的 Transaction,比如下單,支付等核心功能,通常我們對(duì) URL 進(jìn)行埋點(diǎn)就可以了,也就包含了具體的業(yè)務(wù)流程。
Event 報(bào)表
適用于監(jiān)控一段代碼運(yùn)行次數(shù),比如記錄程序中一個(gè)事件記錄了多少次,錯(cuò)誤了多少次。Event 報(bào)表的整體結(jié)構(gòu)與 Transaction 報(bào)表幾乎一樣,只缺少響應(yīng)時(shí)間的統(tǒng)計(jì)。
埋點(diǎn)方式:
Cat.logEvent("Func", "Func1");Problem 報(bào)表
Problem 記錄整個(gè)項(xiàng)目在運(yùn)行過(guò)程中出現(xiàn)的問(wèn)題,包括一些異常、錯(cuò)誤、訪問(wèn)較長(zhǎng)的行為。
如果有人反饋你的接口報(bào) 500 錯(cuò)誤了,你進(jìn) Cat 后就直接可以去 Problem 報(bào)表了,錯(cuò)誤信息就在 Problem 中。
Problem 報(bào)表不需要手動(dòng)埋點(diǎn),我們只需要在項(xiàng)目中集成日志的 LogAppender 就可以將所有 error 異常記錄,下面的段落中會(huì)講解如何整合 LogAppender。
Heartbeat 報(bào)表
Heartbeat 報(bào)表是 CAT 客戶端,以一分鐘為周期,定期向服務(wù)端匯報(bào)當(dāng)前運(yùn)行時(shí)候的一些狀態(tài)。
系統(tǒng)指標(biāo)有系統(tǒng)的負(fù)載信息,內(nèi)存使用情況,磁盤(pán)使用情況等。
JVM 指標(biāo)有 GC 相關(guān)信息,線程相關(guān)信息。
Business 報(bào)表
Business 報(bào)表對(duì)應(yīng)著業(yè)務(wù)指標(biāo),比如訂單指標(biāo)。與 Transaction、Event、Problem 不同,Business 更偏向于宏觀上的指標(biāo),另外三者偏向于微觀代碼的執(zhí)行情況。
這個(gè)報(bào)表我也沒(méi)怎么用過(guò),用的多的還是前面幾個(gè)。
Cat 在 Kitty Cloud 中的應(yīng)用
Kitty Cloud 的基礎(chǔ)組件是 Kitty,Kitty 里面對(duì)需要的一些框架都進(jìn)行了一層包裝,比如擴(kuò)展,增加 Cat 埋點(diǎn)之類的功能。
Cat 的集成
Kitty 中對(duì) Cat 封裝了一層,在使用的時(shí)候直接依賴 kitty-spring-cloud-starter-cat 即可整合 Cat 到項(xiàng)目中。
com.cxytiandi kitty-spring-cloud-starter-cat Kitty Version然后在 application 配置文件中配置 Cat 的服務(wù)端地址信息,多個(gè)英文逗號(hào)分隔:
cat.servers=47.105.66.210在項(xiàng)目的 resources 目錄下創(chuàng)建 META-INF 目錄,然后在 META-INF 中創(chuàng)建 app.properties 文件配置 app.name。此名稱是在 Cat 后臺(tái)顯示的應(yīng)用名
app.name=kitty-cloud-comment-provider最后需要配置一下 Cat 的 LogAppender,這樣應(yīng)用在記錄 error 級(jí)別的日志時(shí),Cat 可以及時(shí)進(jìn)行異常告警操作。
在 logback.xml 增加下面的配置:
更詳細(xì)的內(nèi)容請(qǐng)移步 Cat 的 Github 主頁(yè)進(jìn)行查看。
MVC 框架埋點(diǎn)
基于 Spring Boot 做 Web 應(yīng)用開(kāi)發(fā),我們最常用到的一個(gè) Starter 包就是 spring-boot-starter-web。
如果你使用了 Kitty 來(lái)構(gòu)建微服務(wù)的框架,那么就不再需要直接依賴 spring-boot-starter-web。而是需要依賴 Kitty 中的 kitty-spring-cloud-starter-web。
kitty-spring-cloud-starter-web 在 spring-boot-starter-web 的基礎(chǔ)上進(jìn)行了封裝,會(huì)對(duì)請(qǐng)求的 Url 進(jìn)行 Cat 埋點(diǎn),會(huì)對(duì)一些通用信息進(jìn)行接收透?jìng)?#xff0c;會(huì)對(duì) RestTemplate 的調(diào)用進(jìn)行 Cat 埋點(diǎn)。
在項(xiàng)目中依賴 kitty-spring-cloud-starter-web:
com.cxytiandi kitty-spring-cloud-starter-web Kitty Version啟動(dòng)項(xiàng)目,然后訪問(wèn)你的 REST API??梢栽?Cat 的控制臺(tái)看到 URL 的監(jiān)控信息。
點(diǎn)擊 URL 進(jìn)去可以看到具體的 URL 信息。
再進(jìn)一步可以看到整個(gè) URL 的信息,比如數(shù)據(jù)庫(kù)的查詢,緩存的操作,Http 的調(diào)用等。后端同學(xué)在優(yōu)化性能的時(shí)候就直接從 URL 下手可以將整個(gè)請(qǐng)求的鏈路耗時(shí)的情況都分析清楚。
Mybatis 埋點(diǎn)
Kitty 中 Mybatis 是用的 Mybatis Plus, 主要是對(duì)數(shù)據(jù)庫(kù)相關(guān)操作的 SQL 進(jìn)行了 Cat 埋點(diǎn),可以很方便的查看 SQL 的耗時(shí)情況。
依賴 kitty-spring-cloud-starter-mybatis:
com.cxytiandi kitty-spring-cloud-starter-mybatis Kitty Version其他的使用方式還是跟 Mybatis Plus 一樣,具體參考 Mybatis Plus 文檔:https://mp.baomidou.com
只要涉及到數(shù)據(jù)庫(kù)的操作,都會(huì)在 Cat 中進(jìn)行數(shù)據(jù)的展示。
點(diǎn)擊 SQL 進(jìn)去還可以看到是哪個(gè) Mapper 的操作。
再進(jìn)一步就可以看到具體的 SQL 語(yǔ)句和消耗的時(shí)間。
有了這些數(shù)據(jù),后端研發(fā)同學(xué)就可以對(duì)相關(guān)的 SQL 進(jìn)行優(yōu)化了。
Redis 埋點(diǎn)
如果需要使用 Spring Data Redis 的話,直接集成 kitty-spring-cloud-starter-redis 就可以,kitty-spring-cloud-starter-redis 中對(duì) Redis 的命令進(jìn)行了埋點(diǎn),可以在 Cat 上直觀的查看對(duì)應(yīng)的命令和消耗的時(shí)間。
添加對(duì)應(yīng)的 Maven 依賴:
com.cxytiandi kitty-spring-cloud-starter-redis Kitty Version直接使用 StringRedisTemplate:
@Autowiredprivate StringRedisTemplate stringRedisTemplate; stringRedisTemplate.opsForValue().set("name", "yinjihuan");Cat 中可以看到 Redis 信息。
點(diǎn)擊 Redis 進(jìn)去可以看到有哪些命令。
再進(jìn)去可以看到命令的詳細(xì)信息,比如操作的 key 和消耗的時(shí)間。
MongoDB 埋點(diǎn)
Kitty 中對(duì) Spring Data Mongodb 做了封裝,只對(duì) MongoTemplate 做了埋點(diǎn)。使用時(shí)需要依賴 kitty-spring-cloud-starter-mongodb。
com.cxytiandi kitty-spring-cloud-starter-mongodb Kitty Version在發(fā)生 Mongo 的操作后,Cat 上就可以看到相關(guān)的數(shù)據(jù)了。
點(diǎn)進(jìn)去就可以看到是 MongoTemplate 的哪個(gè)方法發(fā)生了調(diào)用。
再進(jìn)一步就可以看到具體的 Mongo 參數(shù)和消耗的時(shí)間。
還有 Dubbo, Feign,Jetcache,ElasticSearch 等框架的埋點(diǎn)就不細(xì)講了,感興趣的可以移步 Github 查看代碼。
Cat 使用小技巧
埋點(diǎn)工具類
如果要對(duì)業(yè)務(wù)方法進(jìn)行監(jiān)控,我們一般會(huì)用 Transaction 功能,將業(yè)務(wù)邏輯包含在 Transaction 里面,就能監(jiān)控這個(gè)業(yè)務(wù)的耗時(shí)信息。
埋點(diǎn)的方式也是通過(guò) Cat.newTransaction 來(lái)進(jìn)行,具體可以參考上面 Transaction 介紹時(shí)給出的埋點(diǎn)示列。
像這種埋點(diǎn)的方式最好是有一個(gè)統(tǒng)一的工具類去做,將埋點(diǎn)的細(xì)節(jié)封裝起來(lái)。
public class CatTransactionManager { public static T newTransaction(Supplier function, String type, String name, Map data) { Transaction transaction = Cat.newTransaction(type, name); if (data != null && !data.isEmpty()) { data.forEach(transaction::addData); } try { T result = function.get(); transaction.setStatus(Message.SUCCESS); return result; } catch (Exception e) { Cat.logError(e); if (e.getMessage() != null) { Cat.logEvent(type + "_" + name + "_Error", e.getMessage()); } transaction.setStatus(e); throw e; } finally { transaction.complete(); } }}工具類使用:
public SearchResponse search(SearchRequest searchRequest, RequestOptions options) { Map catData = new HashMap<>(1); catData.put(ElasticSearchConstant.SEARCH_REQUEST, searchRequest.toString()); return CatTransactionManager.newTransaction(() -> { try { return restHighLevelClient.search(searchRequest, options); } catch (IOException e) { throw new RuntimeException(e); } }, ElasticSearchConstant.ES_CAT_TYPE, ElasticSearchConstant.SEARCH, catData);}通過(guò)使用工具類,不再需要每個(gè)監(jiān)控的地方都是設(shè)置 Transaction 是否 complete,是否成功這些信息了。
注解埋點(diǎn)
為了讓 Transaction 使用更方便,我們可以自定義注解來(lái)做這個(gè)事情。比如需要監(jiān)控下單,支付等核心業(yè)務(wù)方法,那么就可以使用自定義的 Transaction 注解加在方法上,然后通過(guò) AOP 去統(tǒng)一做監(jiān)控。
定義注解:
@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.METHOD, ElementType.TYPE})public @interface CatTransaction { /** * 類型, 默認(rèn)為Method * @return */ String type() default ""; /** * 名稱, 默認(rèn)為類名.方法名 * @return */ String name() default ""; /** * 是否保存參數(shù)信息到Cat * @return */ boolean isSaveParamToCat() default true;}定義切面:
@Aspectpublic class CatTransactionAspect { @Around("@annotation(catTransaction)") public Object aroundAdvice(ProceedingJoinPoint joinpoint, CatTransaction catTransaction) throws Throwable { String type = catTransaction.type(); if (StringUtils.isEmpty(type)){ type = CatConstantsExt.METHOD; } String name = catTransaction.name(); if (StringUtils.isEmpty(name)){ name = joinpoint.getSignature().getDeclaringType().getSimpleName() + "." + joinpoint.getSignature().getName(); } Map data = new HashMap<>(1); if (catTransaction.isSaveParamToCat()) { Object[] args = joinpoint.getArgs(); if (args != null) { data.put("params", JsonUtils.toJson(args)); } } return CatTransactionManager.newTransaction(() -> { try { return joinpoint.proceed(); } catch (Throwable throwable) { throw new RuntimeException(throwable); } }, type, name, data); }}注解使用:
@CatTransaction@Overridepublic Page searchArticleIndex(ArticleIndexSearchParam param) {}你可能關(guān)心的幾個(gè)問(wèn)題
Cat 能做鏈路跟蹤嗎?
Cat 主要是一個(gè)實(shí)時(shí)監(jiān)控系統(tǒng),并不是一個(gè)標(biāo)準(zhǔn)的全鏈路系統(tǒng),主要是 Cat 的 logview 在異步線程等等一些場(chǎng)景下,不太合適,Cat 本身模型并不適合這個(gè)。Cat 的 Github 上有說(shuō)明:在美團(tuán)點(diǎn)評(píng)內(nèi)部,有 mtrace 專門(mén)做全鏈路分析。
但是如果在 Mvc,遠(yuǎn)程調(diào)用等這些框架中做好了數(shù)據(jù)的無(wú)縫傳輸,Cat 也可以充當(dāng)一個(gè)鏈路跟蹤的系統(tǒng),基本的場(chǎng)景足夠了。
Cat 也可以構(gòu)建遠(yuǎn)程消息樹(shù),可以看到請(qǐng)求經(jīng)過(guò)了哪些服務(wù),每個(gè)服務(wù)的耗時(shí)等信息。只不過(guò)服務(wù)之間的依賴關(guān)系圖在 Cat 中沒(méi)有。
下圖請(qǐng)求從網(wǎng)關(guān)進(jìn)行請(qǐng)求轉(zhuǎn)發(fā)到 articles 上面,然后 articles 里面調(diào)用了 users 的接口。
Cat 跟 Skywalking 哪個(gè)好用?
Skywalking 也是一款非常優(yōu)秀的 APM 框架,我還沒(méi)用過(guò),不過(guò)看過(guò)一些文檔,功能點(diǎn)挺全的 ,界面也挺好看。最大的優(yōu)勢(shì)是不用像 Cat 一樣需要埋點(diǎn),使用字節(jié)碼增強(qiáng)的方式來(lái)對(duì)應(yīng)用進(jìn)行監(jiān)控。
之所以列出這個(gè)小標(biāo)題是因?yàn)槿绻蠹疫€沒(méi)有用的話肯定會(huì)糾結(jié)要選擇落地哪個(gè)去做監(jiān)控。我個(gè)人認(rèn)為這兩個(gè)都可以,可以自己先弄個(gè)簡(jiǎn)單的版本體驗(yàn)體驗(yàn),結(jié)合你想要的功能點(diǎn)來(lái)評(píng)估落地哪個(gè)。
用 Cat 的話最好有一套基礎(chǔ)框架,在基礎(chǔ)框架中埋好點(diǎn),這樣才能在 Cat 中詳細(xì)的顯示各種信息來(lái)幫助我們快速定位問(wèn)題和優(yōu)化性能。
感興趣的 Star 下唄:https://github.com/yinjihuan/kitty-cloud
關(guān)于作者:尹吉?dú)g,簡(jiǎn)單的技術(shù)愛(ài)好者,《Spring Cloud 微服務(wù)-全棧技術(shù)與案例解析》, 《Spring Cloud 微服務(wù) 入門(mén) 實(shí)戰(zhàn)與進(jìn)階》作者, 公眾號(hào) 猿天地 發(fā)起人。個(gè)人微信 jihuan900,歡迎勾搭。
總結(jié)
以上是生活随笔為你收集整理的监控url_熬夜之作:一文带你了解Cat分布式监控的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 2019-3-1
- 下一篇: 中小企业网络安全提升