【升職加薪祕籍】我在服務監控方面的實踐(2)-監控元件設定

2023-07-25 18:00:24

大家好,我是藍胖子,關於效能分析的視訊和文章我也大大小小出了有一二十篇了,算是已經有了一個系列,之前的程式碼已經上傳到 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 設定

完整的 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。

在萬千人海中,相遇就是緣分,為了這份緣分,給作者點個贊