php網(wǎng)站開發(fā)工程師待遇百度快照是啥
【作者】JasonXu
前言
當前全球企業(yè)云化、數(shù)字化進程持續(xù)加速,容器、微服務等云原生技術在軟件架構中快速滲透,IT 架構云化、復雜化持續(xù)驅(qū)動性能監(jiān)控市場。企業(yè)云化、數(shù)字化持續(xù)轉(zhuǎn)型,以及為了考慮系統(tǒng)的彈性、效率,企業(yè)軟件開發(fā)中大量云原生技術的應用推動全球 IT 監(jiān)控市場快速變化,如何全面、有效的對容器、K8s、微服務進行監(jiān)控是當下云原生技術面臨的重要課題。
背景和挑戰(zhàn)
云化產(chǎn)品通常采用服務化框架,由一系列微服務組成,且微服務是可以獨立運行的進程,不同服務可使用不同開發(fā)語言,可能分布部署在幾千臺服務器上,甚至可能橫跨多個不同的數(shù)據(jù)中心,服務間使用輕量的通信機制;服務之間存在復雜的調(diào)用關系,對運維人員理解系統(tǒng)的行為或分析系統(tǒng)性能帶來巨大挑戰(zhàn) 如:
(1)容器是否正常運行
(2)K8S是否正常運行。
(3)微服務是正常
(5)業(yè)務調(diào)用出現(xiàn)問題,如何快速找出哪個服務發(fā)生失敗?
(6)某個業(yè)務調(diào)用耗時較長,如何快速找到性能瓶頸點?
(7)如何快速獲取某次調(diào)用的業(yè)務日志進行分析定位?
解決方案
概述
云原生監(jiān)控體系包括:Healthchecks、Metrics、Logging、Tracing。Healthchecks:健康檢查可以定期檢查某個應用的存活狀態(tài);Metrics:度量指標監(jiān)控,在離散的時間點上產(chǎn)生數(shù)值點;Logging:日志監(jiān)控;Tracing:調(diào)用鏈監(jiān)控。
各種監(jiān)控工具適用場景如下圖所示:
健康檢查
微服務架構,為了保證所有服務可用,當服務發(fā)生問題時能及時摘除有問題的服務需要定期檢測服務可用性,即健康檢查。通常健康健康檢查包括TCP與HTTP兩種。即定時發(fā)送TCP或HTTP請求,根據(jù)響應來確定服務是否可用。一般通過TCP定期請求來判定網(wǎng)絡層是否正常,而通過Http請求判斷應用層是否正常。服務要配置好請求接口,檢測服務定期向指定的接口發(fā)送http請求,并根據(jù)接口響應碼和響應時間判斷。Spring boot的end port /health可以檢查應用的健康狀態(tài),舉例說,當我們訪問 http://localhost:8088/health 時,可以看到 HealthEndPoint 給我們提供默認的監(jiān)控結果,包含磁盤檢測和數(shù)據(jù)庫檢測。
{
"status": "UP",
"diskSpace": {
"status": "UP",
"total": 398458875904,
"free": 315106918400,
"threshold": 10485760
},
"db": {
"status": "UP",
"database": "MySQL",
"hello": 1
}
}
容器監(jiān)控
容器監(jiān)控使用Prometheus-cAdvisor,cAdvisor是谷歌專為監(jiān)控容器性能狀態(tài)設計的一個開源工具,cAdvisor提供有Push和Pull兩種獲取性能數(shù)據(jù)的接口。Push接口指的是由cAdvisor主動將數(shù)據(jù)周期性的推送到遠端的存儲服務中,Influxdb與cAdvisor的對接就是通過這個接口完成的。而Pull接口則允許外部訪問服務隨時主動從cAdvisor獲取到當時時刻的性能數(shù)據(jù),然后自行處理,Prometheus與cAdvisor的對接用的是這種方法。
基于容器的微服務監(jiān)控和原始的監(jiān)控是有很大區(qū)別的,因為服務的實例生存周期很短,分分鐘可能就會有容器的生滅。微服務的容器與宿主機的監(jiān)控離不開CPU、內(nèi)存、磁盤、網(wǎng)卡這些基礎的性能指標,對于宿主機的監(jiān)控來說,我們可以依然使用原始的監(jiān)控方式,每個宿主機安裝一個代理來采集服務器的性能指標,代理在采集性能指標的時候可以打上時間戳和相應的標簽來區(qū)分不同性能指標的數(shù)據(jù)維度(metric),然后將監(jiān)控數(shù)據(jù)匯總到時間序列數(shù)據(jù)庫,里面的數(shù)據(jù)可以對接目前一些開源的組件來進行可視化的展示,也可以對接報警服務(結合報警服務的報警策略)進行報警。
容器的監(jiān)控自然就和宿主機不太一樣了,我們不能說給每個容器鏡像內(nèi)部都集成一個監(jiān)控代理(agent),這樣的話侵入性太強,不易于維護。Prometheus有很多的Exporter可以用來采集監(jiān)控數(shù)據(jù),例如我們想采集Kubernetes上所有容器(pod)的性能指標的話,Promethus可以通過直接配置多個Kubernetes ApiServer的Endpoints來監(jiān)控整個Kubernetes集群。
K8S監(jiān)控
K8S集群層面選擇使用Prometheus。集群層面的監(jiān)控又分為Node、K8S基礎組件、K8S資源對象三大類。
1、對于Node的監(jiān)控,Prometheus提供了node-exporter,可采集到CPU、內(nèi)存、磁盤IO、磁盤使用率、網(wǎng)絡包量、帶寬等數(shù)據(jù);
2、K8S基礎組件類的kubelet、kube-apiserver、kube-controller-manager 和 kube-scheduler等,都提供了 metrics接口暴露自身的運行時的監(jiān)控數(shù)據(jù),這些數(shù)據(jù)都可被部署在K8S集群中的Prometheus 直接拉取到;
3、結合cadvisor 和kube-state-metrics ,可直接采集到K8S中Pod的 CPU、內(nèi)存、磁盤 IO、網(wǎng)絡 IO 等數(shù)據(jù)。由CoreOS開源的Kube-Prometheus項目,極大簡化了Prometheus的安裝部署運維工作。
基于Kubernetes實現(xiàn)的微服務應用級的監(jiān)控插件,如下圖:
在Kubernetes的master節(jié)點,也就是安裝apiserver的那臺服務器上運行一個監(jiān)控插件,該插件可以通過一個kubernetes提供的官方客戶端來訪問apiserver,首先我們要告知插件要監(jiān)控哪個namespace下的哪個service,然后,插件通過和apiserver進行交互獲取某個service下所有Pods的實例,插件會并發(fā)訪問所有pod提供的/metrics接口(Path可配),并給每個pod的返回數(shù)據(jù)(json格式,遵守一定的數(shù)據(jù)格式契約)打上pod_name的標簽來標識每個pod返回的metrics,打上pod_name標簽的同時也會打上service_name的標簽用來區(qū)分具體是哪個service的監(jiān)控數(shù)據(jù)。
Kubernetes主要提供了如下5種服務發(fā)現(xiàn)模式和Prometheus進行集成:Node、Pod、Endpoints、Service、Ingress。監(jiān)控K8S將使用Prometheus federation的形式,k8s集群外部的Prometheus從k8s集群中Prometheus拉取監(jiān)控數(shù)據(jù),外部的Prometheus才是監(jiān)控數(shù)據(jù)的存儲。k8s集群中部署Prometheus的數(shù)據(jù)存儲層可以簡單的使用emptyDir,數(shù)據(jù)只保留24小時(或更短時間)即可,部署在k8s集群上的這個Prometheus實例即使發(fā)生故障也可以放心的讓它在集群節(jié)點中漂移。
1)創(chuàng)建namespace取名ns-monitor
2)在k8s中部署node-exporter
Node-exporter用于采集kubernetes集群中各個節(jié)點的物理指標,比如:Memory、CPU等??梢灾苯釉诿總€物理節(jié)點直接安裝,這里我們使用DaemonSet部署到每個節(jié)點上,使用 hostNetwork: true 和 hostPID: true 使其獲得Node的物理指標信息,配置tolerations使其在master節(jié)點也啟動一個pod。
#創(chuàng)建node-exporter.yml文件
3-1)創(chuàng)建編輯rabc.yml
rbac.yml定義了Prometheus容器訪問k8s apiserver所需的ServiceAccount和ClusterRole及ClusterRoleBinding????
3-2)創(chuàng)建編輯configmap.yml 進行configmap中的prometheus的配置文件
3-3)prometheus-deploy.yml定義Prometheus的部署????
3-4)prometheus-svc.yml定義Prometheus的Service
需要將Prometheus以NodePort, LoadBalancer或使用Ingress暴露到集群外部,這樣外部的Prometheus才能訪問它?。
3-5)使用yml文件創(chuàng)建對象
????? kubectl create -f rbac.yml
????? kubectl create -f configmap.yml
????? kubectl create -f prometheus-deploy.yml
????? kubectl create -f prometheus-svc.yml
4)配置配置Prometheus Federation
完成Kubernetes集群上的Prometheus的部署之后,下面將配置集群外部的Prometheus使其從集群內(nèi)部的Prometheus拉取數(shù)據(jù)。實際上只需以靜態(tài)配置的形式添加一個job就可以。
5)配置pushgateway
日志監(jiān)控
Fluentd是一個通用的信息收集、整理、轉(zhuǎn)發(fā)的流式數(shù)據(jù)處理工具。默認情況下Docker會將所有容器輸出到系統(tǒng)控制臺的內(nèi)容重定向到以容器ID命名的一個本地目錄中,只需要定期采集所有這些目錄的內(nèi)容就能一字不漏的將容器的輸出捕獲出來,這種方式的侵入性很小,但由于是周期性的收集,日志在匯聚端(例如Kibana)的展示會有一定的延時,延時長度與日志收集的周期相關。相反的,如果使用Docker的日志驅(qū)動(啟動docker后臺服務時指定參數(shù)–log-driver=fluentd)將獲得實時性很好的匯聚端日志展示,但由于日志直接發(fā)送到了遠端的Fluentd服務,會使得在本地主機上的docker logs命令失效。
兩種方式的共性在于:不論通過哪一種方式,收集到的日志都能夠以容器名稱、鏡像、標簽等對容器使用十分友好的維度進行檢索。Kubernetes 集群本身不提供日志收集的解決方案,我們采用fluentd-->kafka-->logstash-->elasticsearch-->kibana的方式,直接在應用程序中將日志信息推送到采集后端。
調(diào)用鏈監(jiān)控
調(diào)用鏈定義:在系統(tǒng)完成一次業(yè)務調(diào)用的過程中,把服務之間的調(diào)用信息(時間、接口、層次、結果)打點到日志中,然后將所有的打點數(shù)據(jù)連接為一個樹狀鏈條就產(chǎn)生了一個調(diào)用鏈。跟蹤系統(tǒng)把過程中產(chǎn)生的日志信息進行分析處理,將業(yè)務端到端的執(zhí)行完整的調(diào)用過程進行還原,根據(jù)不同維度進行統(tǒng)計分析;從而標識出有異常的服務調(diào)用,能夠快速分析定界到出異常的服務;同時可根據(jù)數(shù)據(jù)統(tǒng)計分析系統(tǒng)性能瓶頸。
Dapper, a Large-Scale Distributed Systems Tracing Infrastructure?描述了其中的原理和一般性的機制。模型中包含的術語也很多,理解最主要的兩個即可:
-
Trace:一次完整的分布式調(diào)用跟蹤鏈路。
-
Span:跨服務的一次調(diào)用;多個 Span 組合成一次 Trace 追蹤記錄。
下面通過一次用戶服務請求來完成調(diào)用鏈過程模擬:
左圖為一個和5臺服務器相關的一個服務,包括:前端(A),兩個中間層(B和C),以及兩個后端(D和E)。當一個用戶(這個用例的發(fā)起人)發(fā)起一個請求時,首先到達前端,然后發(fā)送兩個RPC到服務器B和C。B會馬上做出反應,但是C需要和后端的D和E交互之后再返還給A,由A來響應最初的請求。右表示對應 Span 的管理關系。每個節(jié)點是一個 Span,表示一個調(diào)用。至少包含 Span 的名、父 SpanId 和 SpanId。節(jié)點間的連線下表示 Span 和父 Span 的關系。所有的 Span 屬于一個跟蹤,共用一個 TraceId。從圖上可以看到對前端 A 的調(diào)用 Span 的兩個子 Span 分別是對 B 和 C 調(diào)用的 Span,D 和 E 兩個后端服務調(diào)用的 Span 則都是 C 的子 Span。跟蹤系統(tǒng)根據(jù)用戶請求每次生成的全局唯一的ID(TraceId),TraceId 在span間傳遞,將不同服務的“孤立的”日志串在一起,重組還原出更多有價值的信息。如今調(diào)用鏈系統(tǒng)有很多實現(xiàn),用的比較多的如 zipkin ,還有已經(jīng)加入 CNCF 基金會并且用的越來越多的 Jaeger。
調(diào)用鏈模型格式
為了能將一系列埋點串接成一個完整的調(diào)用鏈,并區(qū)分不同請求的調(diào)用鏈日志信息,同時信息中需要包含請求狀態(tài)與時長,對于不同業(yè)務應用可能需要有特殊的信息記錄到日志中;所以調(diào)用鏈日志信息(Span)應包含如下內(nèi)容:
一次業(yè)務請求調(diào)用鏈模型:
對于Trace而言,最基礎的能力是能夠記錄請求在多個服務之間調(diào)用的傳播、依賴關系并進行可視化。而從Trace本身的數(shù)據(jù)特點而言,它是規(guī)則化、標準化且?guī)в幸蕾囮P系的訪問日志,因此可以基于Trace去計算并挖掘更多的價值。下面是SLS OpenTelemetry Trace的實現(xiàn)架構,核心是通過數(shù)據(jù)編排計算Trace原始數(shù)據(jù)并得到聚合數(shù)據(jù),并基于SLS提供的接口實現(xiàn)各類Trace的附加功能。例如:
1.依賴關系:這是絕大部分的Trace系統(tǒng)都會附帶的功能,基于Trace中的父子關系進行聚合計算,得到Trace Dependency
2.服務/接口黃金指標:Trace中記錄了服務/接口的調(diào)用延遲、狀態(tài)碼等信息,基于這些數(shù)據(jù)可以計算出QPS、延遲、錯誤率等黃金指標。
3.上下游分析:基于計算的Dependency信息,按照某個Service進行聚合,統(tǒng)一Service依賴的上下游的指標
4.中間件分析:Trace中對于中間件(數(shù)據(jù)庫/MQ等)的調(diào)用一般都會記錄成一個個Span,基于這些Span的統(tǒng)計可以得到中間件的QPS、延遲、錯誤率。
告警相關:通?;诜?接口的黃金指標設置監(jiān)控和告警,也可以只關心整體服務入口的告警(一般對父Span為空的Span認為是服務入口調(diào)用)。
Metrics:
-
通常都是range查詢,每次查詢某一個單一的指標/時間線,或者一組時間線進行聚合,例如統(tǒng)一某個應用所有機器的平均CPU
-
時序類的查詢一般QPS都較高(主要有很多告警規(guī)則),為了適應高QPS查詢,需要把數(shù)據(jù)的聚合性做好
-
對于這類數(shù)據(jù)都會有專門的時序引擎來支撐,目前主流的時序引擎基本上都是用類似于LSM Tree的思想來實現(xiàn),以適應高吞吐的寫入和查詢(Update、Delete操作很少)
-
同時可觀測性數(shù)據(jù)還有一些共性的特點,例如高吞吐寫入(高流量、QPS,而且會有Burst)、超大規(guī)模查詢特點、時間訪問特性(冷熱特性、訪問局部性等)。
業(yè)務調(diào)用鏈路監(jiān)控
Skywalking是一款比較優(yōu)秀的開源的應用性能監(jiān)控工具,支持對分布式系統(tǒng)的監(jiān)控、跟蹤和診斷。它提供了如下的主要功能特性:
Service Topology監(jiān)控
調(diào)用鏈路監(jiān)控可以從兩個角度去看待。通過給服務添加探針并產(chǎn)生實際的調(diào)用之后,我們可以通過Skywalking的前端UI查看服務之間的調(diào)用關系。我們簡單模擬一次服務之間的調(diào)用。新建兩個服務,service-provider以及service-consumer,服務之間簡單的通過Feign Client 來模擬遠程調(diào)用。
從圖中可以看到:
-
有兩個服務節(jié)點:provider & consumer
-
有一個數(shù)據(jù)庫節(jié)點:localhost【mysql】
-
一個注冊中心節(jié)點
consumer消費了provider提供出來的接口。
一個系統(tǒng)的拓撲圖讓我們清晰的認識到系統(tǒng)之間的應用的依賴關系以及當前狀態(tài)下的業(yè)務流轉(zhuǎn)流程。細心的可能發(fā)現(xiàn)圖示節(jié)點consumer上有一部分是紅色的,紅色是什么意思呢?
紅色代表當前流經(jīng)consumer節(jié)點的請求有一段時間內(nèi)是響應異常的。當節(jié)點全部變紅的時候證明服務現(xiàn)階段內(nèi)就徹底不可用了。運維人員可以通過Topology迅速發(fā)現(xiàn)某一個服務潛在的問題,并進行下一步的排查并做到預防。
Skywalking Trace監(jiān)控
Skywalking通過業(yè)務調(diào)用監(jiān)控進行依賴分析,提供給我們服務之間的服務調(diào)用拓撲關系、以及針對每個endpoint的trace記錄。
我們在之前看到consumer節(jié)點服務中發(fā)生了錯誤,讓我們一起來定位下錯誤是發(fā)生在了什么地方又是什么原因呢?
在每一條trace的信息中都可以看到當前請求的時間、GloableId、以及請求被調(diào)用的時間。我們分別看一看正確的調(diào)用和異常的調(diào)用。
Trace調(diào)用鏈路監(jiān)控
圖示展示的是一次正常的響應,這條響應總耗時19ms,它有4個span:
-
span1 /getStore = 19ms ?響應的總流轉(zhuǎn)時間
-
span2 /demo2/stores = 14ms? feign client 開始調(diào)用遠程服務后的響應的總時間
-
span3 /stores = 14ms 接口服務響應總時間
-
span4 Mysql = 1ms? 服務提供端查詢數(shù)據(jù)庫的時間
這里span2和span3的時間表現(xiàn)相同,其實是不同的,因為這里時間取了整。
在每個Span中可以查看當前Span的相關屬性。
-
組件類型: SpringMVC、Feign? ? ? ? ? ? ? ? ??
-
Span狀態(tài): false
-
HttpMethod: GET
-
Url:?
http://192.168.16.125:10002/demo2/stores
這是一次正常的請求調(diào)用Trace日志,可能我們并不關心正常的時候,畢竟一切正常不就是我們期待的么!我們再來看下,異常狀態(tài)下我們的Trace以及Span又是什么樣的呢。
發(fā)生錯誤的調(diào)用鏈中Span中的is error標識變?yōu)閠rue,并且在名為Logs的TAB中可以看到錯誤發(fā)生的具體原因。根據(jù)異常情況我們就可以輕松定位到影響業(yè)務的具體原因,從而快速定位問題,解決問題。通過Log我們看到連接被拒,那么可能是我們的網(wǎng)絡出現(xiàn)了問題(可能性小,因為實際情況如果網(wǎng)絡出現(xiàn)問題我們連這個trace都看不到了),也有可能是服務端配置問題無法正確建立連接。通過異常日志,我們迅速就找到了問題的關鍵。
服務性能監(jiān)控
服務性能可以實現(xiàn)以下關鍵指標:
1、關鍵業(yè)務指標:響應時間、Apex、吞吐率、錯誤率
2、事務:耗時百分比、響應時間、吞吐量、Apdex、錯誤率、調(diào)用次數(shù)
3、數(shù)據(jù)庫:SQL耗時、平均響應時間、吞吐率、SQL語句執(zhí)行計劃、代碼堆棧
4、NoSQL:Memcached/Redis/MogooDB的操作總耗時、平均響應時間、吞吐率
5、外部應用:HTTP/Thrif/Dubbo/Web Service的響應時間占比、平均響應時間、響應總時間、吞吐率、錯誤率
6、MQ:RabbitMQ/JMS/ActiveMQ生產(chǎn)者、消費者的消息總數(shù)、每分鐘消息數(shù)、平均消息發(fā)送時間、總流量
7、JVM:內(nèi)存使用量、線程、HTTP會話