系列文章
- .Net微服務實戰之技術選型篇
- .Net微服務實戰之技術架構分層篇
- .Net微服務實戰之DevOps篇
- .Net微服務實戰之負載均衡(上)
- .Net微服務實戰之CI/CD
- .Net微服務實戰之Kubernetes的搭建與使用
- .Net微服務實戰之負載均衡(下)
- .Net微服務實戰之必須得面對的分散式問題
前言
很多次去面試,有經驗的面試官都會問一個問題,你是怎麼去定位日常遇到的問題?平常跟同行分享自己遇到的問題,事後他會問我,這種看起來毫無頭緒的問題,你是怎麼去定位解決的?
其實我們平常不知道怎麼問題出在哪,主要是所瞭解的資訊量不足,那麼怎麼才能提高給我們們定位問題的資訊量呢?其實上面兩個問題的答案都是同一個:日誌、指標、跟蹤。
有日誌記錄才能清楚知道當前系統的執行狀況和具體問題;指標是給與後續做優化和定位偶發性問題的一些參考,沒指標參考就沒標準;我們平常做得多的除錯、檢視呼叫棧也是跟蹤的一種,但是在分散式時代,更多考量的是跨程式通訊的呼叫鏈路。
日誌、指標、跟蹤三者結合起來有一種統稱——可觀測性
運維是架構的地基,我第一次看到這句是在張輝清寫的《小團隊構建大網站:中小研發團隊架構實踐》,說實話,我非常的認同。不少小團隊的運維都是由開發兼職的,而團隊的運維能力決定了日後架構選型與日常維護。有良好的運維監控體系,就有足夠的資訊量提供給開發人員進行定位排錯。
可觀測性
可觀測性的意思是可以由系統的外部輸出推斷其內部狀態的程度,在軟體系統中,可觀察性是指能夠收集有關程式執行、模組內部狀態以及元件之間通訊的資料。分別由三個方向組成:日誌(logging)、跟蹤( tracing)、指標(Metrics)《Metrics, tracing, and logging》
日誌(logging)
日誌的定義特徵是它記錄離散事件,目的是通過這些記錄後分析出程式的行為。
例如:應用程式除錯或錯誤訊息通過轉換檔案描述,通過 syslog 傳送到 Elasticsearch;審計跟蹤事件通過 Kafka 推送到 BigTable 等資料儲存;或從服務呼叫中提取併傳送到錯誤跟蹤服務(如 NewRelic)的特定於請求的後設資料。
跟蹤( tracing)
跟蹤的定義特徵是它處理請求範圍內的資訊,目的是排查故障。
在系統中執行的單個事務物件生命週期裡,所繫結的資料或後設資料。例如:RPC遠端服務呼叫的持續時間;請求到資料庫的實際 SQL 查詢語句;HTTP 請求入站的關聯 ID。
指標(Metrics)
指標的定義特徵是它們是可聚合的,目的是監控和預警。
這些指標在一段時間內,能組成單個邏輯儀表、計數器或直方圖。例如:佇列的當前長度可以被建模為一個量規;HTTP 請求的數量可以建模為一個計數器,更新後通過簡單的加法聚合計算;並且可以將觀察到的請求持續時間建模為直方圖,更新彙總到某個時間段中並建立統計摘要。
代表性產品
日誌(logging)基本上是ELK (ElasticSearch, Logstash, Kibana) 技術棧一家獨大了,但是Logstash比較重量級的,而輕量級的Filebeat可能更加受大家的青睞。下文裡的實戰部分,我是以EFK(ElasticSearch, Filebeat, Kibana)演示。
跟蹤( tracing)相比於日誌就是百花齊放了,Skywalking、zipkin、鷹眼、jeager、Datadog等等……但是在.Net的技術棧裡,能提供出SDK的相對會少,所以選擇也會少一些,我在之前的實戰和下文的演示都是用Skywalking,主要優勢無侵入。
指標(Metrics)在雲生時代Prometheus比Zabbix更加受大家歡迎,同時Prometheus社群活躍度也佔非常大的優勢。下文實戰部分我以Prometheus 作為演示。
ElasticSearch部署與安裝
後面的Skywaking和日誌都需要用到ElasticSearch,所以我把部署流程優先提了出來。
匯入 GPG key
rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch
新增源
vim /etc/yum.repos.d/elasticsearch.repo
[elasticsearch] name=Elasticsearch repository for 7.x packages baseurl=https://artifacts.elastic.co/packages/7.x/yum gpgcheck=1 gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch enabled=0 autorefresh=1 type=rpm-md
重新載入
yum makecache
安裝
sudo yum install -y --enablerepo=elasticsearch elasticsearch
修改配置
vim /etc/elasticsearch/elasticsearch.yml
network.host: 0.0.0.0 discovery.type: single-node
啟動
/sbin/chkconfig --add elasticsearch sudo -i service elasticsearch start systemctl enable elasticsearch.service
用瀏覽器訪問,能出現下圖就是可以了
Prometheus與Grafana實現指標
架構簡析
核心元件
Prometheus server
Prometheus的主程式,本身也是一個時序資料庫,它來負責整個監控叢集的資料拉取、處理、計算和儲存,是使用pull方式由服務端主動拉取監控資料。
Alertmanager
Prometheus的告警元件,負責整個叢集的告警傳送、分組、排程、警告抑制等功能。 需要知道的是alertmanager本身是不做告警規則計算的,簡單來說就是,alertmanager不去計算當前的監控取值是否達到我設定的閾值,上面已經提過該部分規則計算是prometheus server來計算的,alertmanager監聽prometheus server發來的訊息,然後在結合自己的配置,比如等待週期,重複傳送告警時間,路由匹配等配置項,然後把接收到的訊息傳送到指定的接收者。同時他還支援多種告警接收方式,常見的如郵件、企業微信、釘釘等。1.3
Pushgateway
Pushgateway 它是prometheus的一箇中間網管元件,類似於zabbix的zabbix-proxy。它主要解決的問題是一些不支援pull方式獲取資料的場景,比如:自定義shell指令碼來監控服務的健康狀態,這個就沒辦法直接讓prometheus來拉資料,這時就可以藉助pushgateway,它是支援推送資料的,我們可以把對應的資料按照prometheus的格式推送到pushgateway,然後配置prometheus server拉取pushgateway即可。
UI
Grafana、prometheus-ui是用來圖形化展示資料的元件,其中prometheus-ui是prometheus專案原生的ui介面,但是在資料展示方面不太好用,因此推薦grafana來展示你的資料,grafana支援prometheus的PromQL語法,能夠和prometheus資料庫互動,加上grafana強大的ui功能,我們可以很輕鬆的獲取到很多好看的介面,同時也有很多做好的模版可以使用。
Prometheus Target
採集指標的API,有不同的Exporter,如果redis、mysql、server nodel提供給Prometheus server定時pull資料到資料庫。
安裝Prometheus
mkdir /var/prometheus docker run -d --name=prometheus -p 9090:9090 prom/prometheus docker cp prometheus:/etc/prometheus/prometheus.yml /var/prometheus/
刪除之前的容器
docker run -d --name=prometheus -p 9090:9090 -v /var/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus
到瀏覽器輸入地址訪問,出現以下頁面則成功
安裝Grafana
docker run -d --name=grafana -p 3000:3000 grafana/grafana
安裝完成後,使用admin/admin登入
安裝Node Exporter
docker run -d -p 9100:9100 \ -v "/proc:/host/proc:ro" \ -v "/sys:/host/sys:ro" \ -v "/:/rootfs:ro" \ --net="host" \ --restart always \ prom/node-exporter
到瀏覽器輸入地址訪問(http://192.168.184.129:9100/metrics),出現以下頁面則成功
配置Prometheus
vim /var/prometheus/prometheus.yml
新增以下配置 (注意格式)
配置Grafana
新增資料來源
匯入模板,其他模板可以到 https://grafana.com/grafana/dashboards 檢視
確認後則生成(注意修改主機名)
到這裡完整的一次監控就完成,我們可以根據上訴的步驟新增容器和docker的監控。
使用Docker Exporter監控容器
用docker進行安裝
docker run --name docker_exporter --detach --restart always --volume "/var/run/docker.sock":"/var/run/docker.sock" --publish 9417:9417 prometheusnet/docker_exporter
在Prometheus進行配置,新增下面配置項
vim /var/prometheus/prometheus.yml
- job_name: "container" static_configs: - targets: ["192.168.88.138:9417"]
在grafana根據上面node-exporter的步驟進行匯入對應的模板 https://grafana.com/grafana/dashboards/11467
使用docker metrics 監控docker
開啟metrics
vim /etc/docker/daemon.json
{ "metrics-addr" : "192.168.88.146:9323", "experimental" : true }
重啟docker
systemctl daemon-reload
service docker restart
配置Prometheus
- job_name: "docker" static_configs: - targets: ["192.168.88.138:9323", "192.168.88.146:9323", "192.168.88.146:9323"]
匯入模板https://grafana.com/grafana/dashboards/1229
SkyWalking實現跟蹤
架構簡析
核心元件
Skywalking OAP Server
Skywalking收集器,接受寫入請求與UI資料查詢。
Skywalking UI
有呼叫鏈路記錄、網路拓撲圖、效能指標展示等。
Skywalking客戶端代理
提供了多種語言的SDK(Java, .NET Core, NodeJS, PHP, Python等),在應用程式進行網路請求的時候進行埋點攔截,整理成需要的指標傳送到Skywalking OAP Server,
安裝SkyWalking的收集器
docker run --name skywalking-oap-server -p 12800:12800 -p 11800:11800 -p 1234:1234 --restart always -d -e SW_STORAGE=elasticsearch7 -e SW_STORAGE_ES_CLUSTER_NODES=192.168.184.129:9200 apache/skywalking-oap-server:8.4.0-es7
啟動成功後去ES檢視,多了很多的Index
安裝SkyWalking UI
docker run --name skywalking-ui -p 8888:8080 --restart always -d -e SW_OAP_ADDRESS=192.168.184.129:12800 apache/skywalking-ui:8.4.0
使用時注意調整右下角的時區
我們到Github下載原始碼 https://github.com/SkyAPM/SkyAPM-dotnet,根據how-to-build文件進行編譯
- Prepare git and .NET Core SDK. - `git clone https://github.com/SkyAPM/SkyAPM-dotnet.git` - `cd SkyAPM-dotnet/` - Switch to the tag by using `git checkout [tagname]` (Optional, switch if want to build a release from source codes) - `git submodule init` - `git submodule update` - Run `dotnet restore` - Run `dotnet build src/SkyApm.Transport.Grpc.Protocol` - Run `dotnet build skyapm-dotnet.sln`
啟動SkyApm.Sample.Frontend與SkyApm.Sample.Backend兩個專案,瀏覽器訪問http://localhost:5001/api/values/postin ,就可以見到下面的呼叫鏈了。
我在19年的時候使用0.9版本,http.request_body和http.response_body都是沒記錄需要自己擴充套件,而現在最新版已經有記錄,省了不少的事。
EFK(ElasticSearch+Filebeat+Kibana)實現日誌
安裝Nginx
主要用來測試的
rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
安裝
yum install -y nginx
vim /etc/nginx/nginx.conf
把圈起來的配置改動一下
log_format json '{"@timestamp":"$time_iso8601",' '"host": "$server_addr",' '"clientip": "$remote_addr",' '"request_body": "$request_body",' '"responsetime": $request_time,' '"upstreamtime": "$upstream_response_time",' '"upstreamhost": "$upstream_addr",' '"http_host": "$host",' '"url": "$uri",' '"referer": "$http_referer",' '"agent": "$http_user_agent",' '"status": "$status"}';
access_log /var/log/nginx/access.log json;
systemctl start nginx.service
systemctl enable nginx.service
用瀏覽器訪問,重新整理幾次,執行cat /var/log/nginx/access.log 就可以看到json格式的日誌了
安裝Filebeat
匯入安裝源
sudo rpm --import https://packages.elastic.co/GPG-KEY-elasticsearch
vim /etc/yum.repos.d/elastic.repo
儲存下面文案
[elastic-7.x] name=Elastic repository for 7.x packages baseurl=https://artifacts.elastic.co/packages/7.x/yum gpgcheck=1 gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch enabled=1 autorefresh=1 type=rpm-md
執行安裝指令
yum install -y filebeat
新增配置
vim /etc/filebeat/filebeat.yml
filebeat.inputs: - type: log enabled: true paths: - /var/log/nginx/access.log json.key_under_root: true json.overwrite_keys: true json.message_key: log tags: ["nginx-access"] - type: log enabled: true paths: - /var/log/nginx/error.log json.key_under_root: true json.overwrite_keys: true json.message_key: log tags: ["nginx-error"] filebeat.config.modules: path: ${path.config}/modules.d/*.yml reload.enabled: false setup.ilm.enabled: false setup.template: name: "nginx" pattern: "nginx-*" setup.template.overwrite: true setup.template.enabled: false output.elasticsearch: hosts: ["192.168.184.129:9200"] indices: - index: "nginx-access-%{+yyyy.MM.dd}" when.contains: tags: "nginx-access" - index: "nginx-error-%{+yyyy.MM.dd}" when.contains: tags: "nginx-error"
啟動
systemctl start filebeat
systemctl enable filebeat
安裝kibana
docker run --name kibana -d -p 5601:5601 kibana:7.7.0
mkdir /var/kibana
docker cp kibana:/usr/share/kibana/config /var/kibana/config
刪除之前的容器再安裝一次
docker run --name kibana -d -v /var/kibana/config:/usr/share/kibana/config -p 5601:5601 kibana:7.7.0
修改配置後,重啟容器
vim /var/kibana/config/kibana.yml
開啟瀏覽器訪問
建立索引,填寫nginx-access-*
最後的展示UI
.Net的日誌同樣可以使用Json儲存,然後通過Filebeat進行採集。
結束
本篇文章是我之前實現微服務的時的運維的技術棧,如果有什麼問題與建議,可以給在評論區反饋給我。