大家好,我是藍胖子,關於效能分析的視訊和文章我也大大小小出了有一二十篇了,算是已經有了一個系列,之前的程式碼已經上傳到 github.com/HobbyBear/performance-analyze ,接下來這段時間我將在之前內容的基礎上,結合自己在公司生產上構建監控系統的經驗,詳細的展示如何對線上服務進行監控,內容涉及到的指標設計,軟體設定,監控方案等等你都可以拿來直接復刻到你的專案裡,這是一套非常適合中小企業的監控體系。
在上一節我們其實是建立起了對監控的概念,對監控什麼,如何監控有了大致的印象。這一節我們就要正式開始動手實踐了,這一節我會介紹下專案程式碼的結構以及著重介紹下其中docker-compose的組態檔。
完整程式碼我已經上傳到了github
github.com/HobbyBear/easymonitor
為了後面章節的介紹更加清晰,我在這一節還是介紹下整個專案各個目錄以及含義
(base) ➜ easymonitor git:(main) ✗ tree -L 1
.
├── ReadMe.md
├── build.sh // 對webhookserver 以及 webapp 專案進行編譯 ,然後放到program資料夾裡
├── docker-compose.yaml // 啟動各個監控系統元件
├── filebeat.yml // filebeat紀錄檔採集的組態檔
├── go.mod
├── go.sum
├── grafanadashbord // 放置grafana的監控面板匯出的json檔案,可直接啟動專案,然後匯入json檔案,即可構建監控面板
├── infra // 專案基礎元件的程式碼,因為服務的監控有時會涉及到埋點和prometheus client暴露指標,將這部分邏輯都寫在這個包下,後續新應用只要引入這個包就能擁有這些監控指標
├── logconf // 放置主機上的紀錄檔採集組態檔,filebeat.yml 中會引入這個資料夾下的設定規則做不同的採集策略
├── logs // 放置應用服務紀錄檔的目錄,由於是docker-compose啟動,需要將主機這個目錄同時對映到filebeat和應用服務容器,filebeat會對這個目錄下的紀錄檔進行採集
├── logstash.conf // logstash 組態檔
├── program // 放置webhookserver 以及 webapp 專案編譯好的二進位制檔案
├── prometheus.yml // prometheus 組態檔
├── webapp // 應用服務程式碼
└── alerterserver // 模擬自研報警系統程式碼
由於機器有限,我準備用docker-compose來構建我們需要用到的監控元件以及應用服務。回顧下監控架構圖。
我們需要的元件或者服務有,應用服務(在專案程式碼裡是webapp),filebeat,prometheus,logstash,elasticsearch,kibana, grafana,node exporter , 自研的報警服務(在專案程式碼裡是alerterserver)
可以看到,在實際的生產環境中,應用服務和filebeat,node exporter是在同一臺主機上,共用了linux名稱空間,直接用docker-compose 啟動各個元件不好模擬這種情況,所以為了更加真實的模擬,我對node exporter 啟動容器的設定做了簡單修改,讓專案程式碼裡的logs目錄同時對映到filebeat容器和node exporter容器內部,並且讓應用程式程式碼在node exporter容器裡啟動,這樣filebeat從logs目錄採集到的紀錄檔就是應用程式webapp打的紀錄檔了。
為了讓node exporter 容器映象啟動時也會執行webapp程式,我修改了其啟動容器時的entrypoint設定,因為node exporter本來的entrypoint是要去執行node exporter程序的,現在修改為要執行一個指令碼。
version: "3.7"
services:
mynode:
image: prom/node-exporter:latest
container_name: "node0"
hostname: "mynode"
ports:
- "9100:9100"
- "8080:8080"
- "8090:8090"
volumes:
- "./program:/program"
- "./logs:/logs"
restart: always
entrypoint: "sh /program/start_node_exporter.sh"
指令碼內則是將webapp和node exporter同時啟動起來,指令碼是放置在專案program 目錄裡,對映到了 容器內部。 webapp通過8090埠暴露prometheus 指標資訊,通過8080埠監聽http請求。9100埠是node exporter服務監聽的埠。指令碼內容如下:
#!/bin/bash
nohup /program/webapp &
node_exporter --collector.vmstat --collector.tcpstat --collector.processes
完整的 docker-compose 組態檔如下:
version: "3.7"
services:
mynode:
image: prom/node-exporter:latest
container_name: "node0"
hostname: "mynode"
ports:
- "9100:9100"
- "8080:8080"
- "8090:8090"
volumes:
- "./program:/program"
- "./logs:/logs"
restart: always
entrypoint: "sh /program/start_node_exporter.sh"
prometheus:
image: prom/prometheus:latest
container_name: "prometheus0"
restart: always
ports:
- "9090:9090"
volumes:
- "./prometheus.yml:/etc/prometheus/prometheus.yml"
grafana:
image: grafana/grafana
container_name: "grafana0"
ports:
- "3000:3000"
restart: always
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.14.2
container_name: elasticsearch
environment:
- discovery.type=single-node
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ports:
- "9200:9200"
kibana:
image: docker.elastic.co/kibana/kibana:7.14.2
container_name: kibana
ports:
- "5601:5601"
environment:
ELASTICSEARCH_URL: http://elasticsearch:9200
filebeat:
image: docker.elastic.co/beats/filebeat:7.14.2
container_name: filebeat
user: root
volumes:
- ./logs:/logs
- ./logconf:/logconf
- ./filebeat.yml:/usr/share/filebeat/filebeat.yml
command: filebeat -e -d "*"
depends_on:
- elasticsearch
- logstash
logstash:
image: docker.elastic.co/logstash/logstash:7.14.2
volumes:
- ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf
ports:
- "5044:5044"
depends_on:
- elasticsearch
mem_reservation: 1000M
cpu_count: 1
ubuntu:
image: ubuntu
command: ./alerterserver
ports:
- "16060:16060"
volumes:
- "./program:/program"
working_dir: /program
mydb:
restart: always
image: amd64/mysql:latest
container_name: mydb
environment:
- "MYSQL_ROOT_PASSWORD=1234567"
- "MYSQL_DATABASE=test"
ports:
- "3306:3306"
需要注意的是其中卷對映的設定,我們挨個來看下對映了哪些組態檔。
首先是prometheus 將專案程式碼裡的prometheus.yml 對映到prometheus容器內部,prometheus.yml 裡面設定要採集的物件,如下所示,我們需要對主機以及應用服務進行指標採集。
## prometheus.yml
global:
scrape_interval: 15s # 預設抓取週期
scrape_configs:
- job_name: 'normal' ## 對node exporter 進行採集
scrape_interval: 5s
metrics_path: /metrics
static_configs:
- targets: ['mynode:9100']
- job_name: 'webapp' ## 對應用服務指標進行採集
scrape_interval: 5s
metrics_path: /metrics
static_configs:
- targets: [ 'mynode:8090' ]
relabel_configs:
- source_labels: [ __address__ ]
target_label: instance
regex: (.*):\d+
replacement: $1
然後是filebeat,對映了3個卷,分別是專案程式碼裡的logs目錄,這個目錄是filebeat的採集紀錄檔目錄,filebeat設定的採集規則將從這個目錄採集紀錄檔。設定的規則放到了logconf目錄下,以下是設定規則檔案範例:
## logconf/api.yml
- type: log
tail_files: true // 該設定為true,為了讓filebeat啟動的時候對新增的紀錄檔才進行採集,對歷史紀錄檔不進行採集
paths:
- /logs/**.log
fields:
log_type: project1
除此以外,filebeat還將專案程式碼裡的filebeat.yml 組態檔對映到了filebeat容器內。
接著是logstash 容器設定,它對映了專案程式碼裡的logstash 組態檔,這個檔案主要是定義了一些紀錄檔清洗規則,已經定義紀錄檔的輸入來源和輸出來源,在這個系統裡,輸入來源就是filebeat,輸出來源就是elasticsearch。
然後是ubuntu這個容器,對映了專案程式碼裡的program 目錄,program這個目錄下放置了alerterserver報警服務的二進位制程式,ubuntu容器就是前臺啟動這個程式,16060埠就是報警服務監聽的埠。
通過下面兩個命令,我們就可以啟動整個監控系統
(base) ➜ easymonitor git:(main) ✗ sh build.sh
(base) ➜ easymonitor git:(main) ✗ docker-compose up
接著,服務啟動之後,在瀏覽器輸入 localhost:3000就可以 存取grafana的介面了,預設賬號和密碼都是admin,點選左邊選單欄選擇Data sources 。
注意prometheus的的ip地址要換成你本地機器局域的ip,因為docker-compose啟動的每個容器擁有各自的網路名稱空間,要存取其他容器的程序,就得用容器的ip+埠,不過我們本地機器對映了相同埠且容器和本地機器是互通的,所以ip地址填成本地機器區域網ip即可。
你也可以用prometheus關鍵字替換ip地址,變成http://prometheus:9090 ,因為docker-compose啟動的程序預設可以用組態檔中的容器名代替ip地址進行存取。
設定好資料來源以後,就可以正式對系統進行監控了,正如前一節【升職加薪祕籍】我在服務監控方面的實踐(1)-監控藍圖 所說,監控是分級的,所以我們建立監控系統指標時,也是這樣,在下一節,我會首先介紹如何在作業系統,伺服器層面建立起系統的監控,並客製化一個自己的dash board。
在萬千人海中,相遇就是緣分,為了這份緣分,給作者點個贊