實(shí)操 OpenTelemetry:通過 Demo 掌握微服務(wù)監(jiān)控的藝術(shù)
項(xiàng)目介紹
我們參考官方文檔構(gòu)建幾個 spring boot 、Golang 項(xiàng)目再配合 Agent 其實(shí)也可以很方便的集成 OpenTelemetry。
但是要完整的體驗(yàn) OpenTelemetry 的所有功能,包含 trace、logs、metrics,還有社區(qū)這么多語言的支持其實(shí)還是比較麻煩的。
我們還需要單獨(dú)部署 collector、存儲的 backend service 等組件、包括 trace UI 展示所需要的 Jaeger,metric 所需要的 grafana 等。
這些所有東西都自己從頭弄的話還是比較費(fèi)時,不過好在社區(qū)已經(jīng)將這些步驟都考慮到了。
特地為大家寫了一個 opentelemetry-demo。
這個項(xiàng)目模擬了一個微服務(wù)版本的電子商城,主要包含了以下一些項(xiàng)目:
Service | Language | Description |
accountingservice | Go | 處理和計(jì)算訂單數(shù)據(jù) |
adservice | Java | 廣告服務(wù) |
cartservice | .NET | 購物車服務(wù),主要會依賴 Redis |
checkoutservice | Go | checkout |
currencyservice | C++ | 貨幣轉(zhuǎn)換服務(wù),提供了較高的 QPS 能力。 |
emailservice | Ruby | 郵件服務(wù) |
frauddetectionservice | Kotlin | 風(fēng)控服務(wù) |
frontend | JavaScript | 前端應(yīng)用 |
loadgenerator | Python/Locust | 模擬壓測服務(wù) |
paymentservice | JavaScript | 支付服務(wù) |
productcatalogservice | Go | 商品服務(wù) |
quoteservice | PHP | 成本服務(wù) |
recommendationservice | Python | 推薦服務(wù) |
shippingservice | Rust | shipping service |
可以發(fā)現(xiàn)在這個 demo 中提供了許多的服務(wù),而且包含了幾乎所有主流的語言,可以很好的模擬我們實(shí)際的使用場景了。 |
圖片
通過這張圖可以更直觀的查看各個服務(wù)之間的關(guān)系。
整體來說前端所有的請求都會通過 front-end-proxy 這個組件代理,最終再由 front 這個服務(wù)進(jìn)行轉(zhuǎn)發(fā)到不同的后端服務(wù)中。
圖片
除了一個項(xiàng)目的架構(gòu)圖之外,還有一個關(guān)于 OpenTelemetry 的數(shù)據(jù)流轉(zhuǎn)圖。
在 OpenTelemetry 中數(shù)據(jù)流轉(zhuǎn)是它的特點(diǎn)也是非常重要的核心,這點(diǎn)在上一篇文章中講過,用戶可以自由定制數(shù)據(jù)的流轉(zhuǎn)以及任意的處理數(shù)據(jù),在這個圖中就將數(shù)據(jù)流轉(zhuǎn)可視化了。
- 客戶端可以通過 OTLP 協(xié)議或者是 HTTP 將數(shù)據(jù)上傳到 OTel Collector 中。
- 在 collector 中會根據(jù)我們配置的 Process pipeline 處理數(shù)據(jù)。
- Metric 數(shù)據(jù)通過 OTLP HTTP exporter 將數(shù)據(jù)導(dǎo)入到 Prometheus 中。
Prometheus 已經(jīng)于 23 年七月份支持 OTLP 格式的 metric 數(shù)據(jù)導(dǎo)入了。
- Trace 數(shù)據(jù)則是通過 OTLP Exporter 寫入到 Jaeger 中進(jìn)行存儲,最后通過 Jaeger 的 UI 進(jìn)行查詢展示。
- 而存入 Prometheus 中的 metric 數(shù)據(jù)則是有 grafana 進(jìn)行查詢。
關(guān)于 collector 的配置會在后文講解。
部署
接下來便是安裝 Demo 了,我更推薦使用 helm 安裝。
這里的版本要求是:
- Kubernetes 1.24+
- Helm 3.9+
helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts
helm repo update
helm install my-otel-demo open-telemetry/opentelemetry-demo
這樣就可以很簡單的將 demo 所涉及到的所有組件和服務(wù)都安裝到 default 命名空間中。
helm show values open-telemetry/opentelemetry-demo > demo.yaml
不過在安裝前還是建議先導(dǎo)出一份 value.yaml,之后可以使用這個 yaml 定制需要安裝的組件。
在這個 yaml 中我們可以看到有哪些組件和服務(wù)可以定制:
圖片
可以看到這里包含了我們剛才提到的所有服務(wù),以及這些服務(wù)所依賴的 Kafka、redis、Prometheus 等中間件,都可以自己進(jìn)行定制修改。
圖片
當(dāng)所有的 Pod 都成功運(yùn)行之后表示安裝成功。
正常情況下安裝不會有什么問題,最大可能的問題就是鏡像拉取失敗,此時我們可以先在本地手動 docker pull 下來鏡像后再上傳到私服,然后修改 deployment 中的鏡像地址即可。
暴露服務(wù)
為了方便使用我們可以用這個 demo 進(jìn)行測試,還需要將 front-proxy 的服務(wù)暴露出來可以在本地訪問:
kubectl port-forward svc/my-otel-demo-frontendproxy 8080:8080
Component | Path |
Shop 首頁 | |
Grafana | |
壓測頁面 | |
Jaeger UI | |
正常情況下就可以打開這些頁面進(jìn)行訪問了。 |
不過使用 port-forward 轉(zhuǎn)發(fā)的方式只是臨時方案,使用 ctrl+c 就會停止暴露服務(wù),所以如果想要一個穩(wěn)定的訪問鏈接時便可以配置一個 ingress。
components:
frontendProxy:
ingress:
enabled: true
annotations: {}
hosts:
- host: otel-demo.my-domain.com
paths:
- path: /
pathType: Prefix
port: 8080
在之前的 helm 的 value.yaml 中配置即可,本地測試的話需要將這個 host 和 ingress 暴露出來的 IP 進(jìn)行綁定才可以使用這個域名機(jī)進(jìn)行訪問。
更多關(guān)于 ingress 的使用可以參考我之前的文章:
- k8s入門到實(shí)戰(zhàn)-使用Ingress
當(dāng)然簡單起見也可以直接將 front-proxy 的 service 類型改為 LoadBalancer。(默認(rèn)是 ClusterIP 只可以在集群內(nèi)訪問)
這樣就可以直接通過這個 service 的 IP 進(jìn)行訪問了。
components:
frontendProxy:
service:
type: LoadBalancer
不過需要注意的是如果 demo 安裝完成之后是不可以再次修改 service 的類型的,需要手動這個 service 刪掉之后再次新建才可以。
臨時測試使用的話還是推薦直接使用 port-forward 進(jìn)行轉(zhuǎn)發(fā)。
查看 Trace
通過之前的項(xiàng)目架構(gòu)圖可以得知,我們在項(xiàng)目首頁刷新會直接請求 AdService 來獲取廣告。
為了簡單起見我們只查詢這一鏈路的調(diào)用情況:
圖片
打開 http://localhost:8080/jaeger/ui/search Jeager 的 UI 頁面便可以篩選服務(wù),之后點(diǎn)擊查找 Traces 就可以列出一段時間內(nèi)的訪問 trace。
圖片
可以看到這個請求鏈路是從前端訪問到 adService 中的 getAds()接口,然后在這個接口中再訪問了 getAdsByCategory 函數(shù)。
圖片
最終在源碼中也可以看到符合鏈路的調(diào)用代碼。
在剛才的鏈路圖的右下角有一個 spanID,整個 trace 是由這些小的 span 組成,每一個 span 也會有唯一 spanID;trace 也會有一個 traceID 將這些 span 串聯(lián)起來;更多關(guān)于 trace 的內(nèi)容會在后面的文章進(jìn)行分析。
查看 Metrics
我們再打開 grafana 便可以看到剛才訪問的 adService 的延遲和接口的 QPS 情況:
圖片
在opentelemetry-collector-data-flow 面板中還可以看到 OpenTelemetry 的數(shù)據(jù)流轉(zhuǎn)。
圖片
更多監(jiān)控信息可以查看其它的面板。
而剛才面板中的數(shù)據(jù)流轉(zhuǎn)規(guī)則則是在我們的 collector 中進(jìn)行配置的:
receivers:
otlp:
protocols:
grpc:
http:
cors:
allowed_origins:
- "http://*"
- "https://*"
httpcheck/frontendproxy:
targets:
- endpoint: http://frontendproxy:${env:ENVOY_PORT}
exporters:
debug:
otlp:
endpoint: "jaeger:4317"
tls:
insecure: true
otlphttp/prometheus:
endpoint: "http://prometheus:9090/api/v1/otlp"
tls:
insecure: true
opensearch:
logs_index: otel
http:
endpoint: "http://opensearch:9200"
tls:
insecure: true
processors:
batch:
connectors:
spanmetrics:
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlp, debug, spanmetrics]
metrics:
receivers: [httpcheck/frontendproxy, otlp, spanmetrics]
processors: [batch]
exporters: [otlphttp/prometheus, debug]
logs:
receivers: [otlp]
processors: [batch]
exporters: [opensearch, debug]
重點(diǎn)的就是這里的 service.piplines,可以進(jìn)行任意的組裝。
更多關(guān)于 collector 的配置也會在后續(xù)文章中繼續(xù)講解。
我們也可以繼續(xù)訪問這個 demo 網(wǎng)站,模擬加入購物車、下單等行為,再結(jié)合 trace 和 metric 觀察系統(tǒng)的變化。
這樣一個完整的 OpenTelemetry-Demo 就搭建完畢了,我們實(shí)際在生產(chǎn)環(huán)境使時完全可以參考這個 demo 進(jìn)行配置,可以少踩很多坑。
參考鏈接:
- https://github.com/open-telemetry/opentelemetry-demo/blob/main/src/adservice/Dockerfile
- https://github.com/open-telemetry/opentelemetry-demo
- https://github.com/prometheus/prometheus/pull/12571
- https://github.com/open-telemetry/opentelemetry-demo/blob/main/src/otelcollector/otelcol-config.yml