我是3y,一年CRUD
經驗用十年的markdown
程式設計師???常年被譽為職業八股文選手
今天austin專案來給大家整點不一樣的:花點時間跟著文章做完,螢幕桌布就可以有了,我來上個圖,大家就懂了。
每當同事一瞄你的電腦,發現都是圖形化的、黑色的看起來就比較高階的介面:“嗯,這逼又在找Bug了吧”
沒錯,要聊的話題就是監控
01、為什麼監控
過去在面試的時候,我記得曾經被問過:“線上出了問題,你們是怎麼排查的?排查的思路是怎麼樣的?”
我以前的部門老大很看重穩定性,經常讓我們梳理系統的上下鏈路和介面資訊。我想:想要提高系統的穩定性就需要有完備的監控和及時告警。
有了監控,出了問題可以快速定位(而不是出了問題還在那裡列印日誌查詢,很多問題都可以通過監控的資料就直接看出來了)。有了監控,我們可以把指標都配置在監控內,無論是技術上的還是業務上的(只不過業務的資料叫做看板,而系統的資料叫做監控)。有了監控我們看待系統的角度都會不一樣(全方位理解系統的效能指標和業務指標)
如果你線上的系統還沒有監控,那著實是不太行的了
02、監控開源元件
監控告警這種想都不用想,直接依賴開源元件就完事了,應該只有大公司才有人力去自研監控告警的元件了。
我選擇的是Prometheus(普羅米修斯),這個在業內還是很出名的,有很多公司都是用它來做監控和告警。
從prometheus的官網我們可以從文件中找到一張架構圖:
我把上面圖以我的理解“不適當地”簡化下
簡化完了之後,發現:還是他孃的人家的圖畫得好看
總體而言,prometheus的核心是在於Server,我們要接入prometheus的話,實際上就是開放介面給prometheus拉取資料,然後在web-ui下配置圖形化介面進而實現監控的功能。
03、prometheus環境搭建
對於prometheus的環境搭建,我這次也是直接用docker來弄了,畢竟Redis和Kafka都上了docker了。新建一個prometheus的資料夾,存放docker-compose.yml
的資訊:
version: '2'
networks:
monitor:
driver: bridge
services:
prometheus:
image: prom/prometheus
container_name: prometheus
hostname: prometheus
restart: always
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
# - ./node_down.yml:/usr/local/etc/node_down.yml:rw
ports:
- "9090:9090"
networks:
- monitor
alertmanager:
image: prom/alertmanager
container_name: alertmanager
hostname: alertmanager
restart: always
# volumes:
# - ./alertmanager.yml:/usr/local/etc/alertmanager.yml
ports:
- "9093:9093"
networks:
- monitor
grafana:
image: grafana/grafana
container_name: grafana
hostname: grafana
restart: always
ports:
- "3000:3000"
networks:
- monitor
node-exporter:
image: quay.io/prometheus/node-exporter
container_name: node-exporter
hostname: node-exporter
restart: always
ports:
- "9100:9100"
networks:
- monitor
cadvisor:
image: google/cadvisor:latest
container_name: cadvisor
hostname: cadvisor
restart: always
volumes:
- /:/rootfs:ro
- /var/run:/var/run:rw
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
ports:
- "8899:8080"
networks:
- monitor
這裡拉取的映象分別有:
cadvisor
用於獲取docker容器的指標node-exporter
使用者獲取伺服器的指標grafana
監控的web-ui
好用的視覺化元件alertmanager
告警元件(目前暫未用到)prometheus
核心監控元件
新建prometheus的配置檔案prometheus.yml
(這份配置其實就是告訴prometheus要去哪個埠中拉取對應的監控資料)
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['ip:9090'] // TODO ip自己寫
- job_name: 'cadvisor'
static_configs:
- targets: ['ip:8899'] // TODO ip自己寫
- job_name: 'node'
static_configs:
- targets: ['ip:9100'] // TODO ip自己寫
(這裡要注意埠,按自己配置的來)
把這份prometheus.yml
的配置往/etc/prometheus/prometheus.yml
路徑下複製一份(有很多配置的資訊我都忽略沒寫了,prometheus的功能還是蠻強大的,對監控想深入瞭解的可以官網看看文件)
隨後在目錄下docker-compose up -d
啟動,於是我們就可以分別訪問:
http://ip:9100/metrics
( 檢視伺服器的指標)http://ip:8899/metrics
(檢視docker容器的指標)http://ip:9090/
(prometheus的原生web-ui)http://ip:3000/
(Grafana開源的監控視覺化元件頁面)
一個docker-compose起了5個伺服器,真好使!
04、Grafana配置監控
既然我們已經起了Grafana了,就直接用Grafana作為監控的視覺化工具啦(prometheus有自帶的視覺化介面,但我們就不用啦)。進到Grafana首頁,我們首先要配置prometheus作為我們的資料來源
進到配置頁面,寫下對應的URL,然後儲存就好了。
配置好資料來源之後,我們就可以配置對應的監控資訊了,常見的配置監控已經有對應的模板了,就不需要我們一個一個地去配置了。(如果不滿足的話,那還是得自己去配)
在這裡,我就演示如何使用現有的模板吧,直接import對應的模板,相關的模板可以在 https://grafana.com/grafana/dashboards/ 這裡查到。
我們直接伺服器的監控直接選用8913的就好了
import後就能直接看到高大上的監控頁面了:
因為我們用docker啟動的服務還是蠻多的,也可以看看Docker的監控(上面啟動的cadvisor
服務就採集了Docker的資訊),我們使用模板893來配置監控docker的資訊:
05、Java系統指標
沒想到,通過上面短短的內容已經配置好了伺服器和Docker服務的監控,但還是缺了什麼對吧?我們寫Java程式的,JVM相關的監控都沒搞起來?這怎麼能行啊。
所以,得支稜起來
配置Java的監控也特別簡單,只要我們在專案中多引入兩個pom依賴(SpringBoot自帶的監控元件actuator)
<!--監控-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--適配prometheus-->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
然後在配置檔案上加上對應的配置(開啟監控並可以讓prometheus拉取配置)
# 監控配置 TODO
management:
endpoint:
health:
show-details: always
metrics:
enabled: true
prometheus:
enabled: true
endpoints:
web:
exposure:
include: '*'
metrics:
export:
prometheus:
enabled: true
當我們啟動服務後,訪問/actuator
路徑就能看到一大堆輸出的指標了,包括prometheus的
能看到這些指標被列印了,說明我們程式接入已經完成了,剩下的就是通過prometheus來採集應用的指標了。
要讓prometheus採集到Java應用的資料,其實就是改下對應的配置檔案就完事了。在前面寫好的的prometheus.yml
檔案下新增相關的配置資訊:
- job_name: 'austin'
metrics_path: '/actuator/prometheus' # 採集的路徑
static_configs:
- targets: ['ip:port'] # todo 這裡的ip和埠寫自己的應用下的
我們訪問:ip:9090/targets
這個路徑下,能看到現在prometheus能採集到的端點有哪些,看到都是自己所配置的狀態為up
,那就說明正常了。
那我們繼續在Grafana配置對應的監控就好啦。這裡我選用了4701
模板的JVM監控和12900
SpringBoot監控,可以簡單看下他們的效果:
06、壓測
到目前為止,我們想要發訊息,都是通過HTTP介面進行呼叫的,而恰好的是,Spring actuator是能監控到HTTP的資料的。那我們就壓測一把看看監控平臺的指標會不會變?
這裡我使用wrk
這個壓測工具來(它足夠簡單易用)所以,首先安裝他(環境Centos 7.6
):
sudo yum groupinstall 'Development Tools'
sudo yum install -y openssl-devel git
git clone https://github.com/wg/wrk.git wrk
cd wrk
make
# 將可執行檔案移動到 /usr/local/bin 位置
sudo cp wrk /usr/local/bin
# 驗證安裝是否成功
wrk -v
壓測下百度來玩玩:wrk -t2 -c100 -d10s --latency http://www.baidu.com
(開兩個執行緒 併發100 持續10s 請求百度)
壓測下我們的介面,完了之後看資料:wrk -t4 -c100 -d10s --latency 'http://localhost:8888/sendSmsTest?phone=13888888888&templateId=1'
顯然資料是有明顯的波動的,而資料貌似跟我們壓測的對不太上?
在我個人的理解下:prometheus是每隔N秒(可配置)去拉取暴露的資料,而在介面上配置的視覺化也是按N秒(可配置)去執行一次Query。基於這種架構下,我們是很難得出某一時刻(秒)對應的數值。
所以在prometheus體系下,它只能看到一個時間段內的值,這對於QPS和RT這些指標並不太友好。
07、部署專案到Linux
從上面的命令來看,我是將austin專案放在Linux下跑了,雖然這是比較基礎的事了。但為了新人,我還是貼下具體的流程吧,點個贊不過分吧?
首先,我們需要下載JDK
下載JDK:https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
賬號:liwei@xiaostudy.com
密碼:OracleTest1234
完了之後,我們需要把下載的包上傳到Linux上,我用的是Mac(用Windows的同學可以百度下,估計都挺簡單的),IP自己切換成對應的地址
scp -P22 /Users/3y/Downloads/下載的dmg/jdk-8u311-linux-i586.tar.gz root@ip:/root/austin
解壓java包
tar -zxvf jdk-8u231-linux-x64.tar.gz
配置對應的環境變數:
vim /etc/profile
# 在配置檔案後新增下面的內容
export JAVA_HOME="/root/java/jdk1.8.0_311"
export PATH="$JAVA_HOME/bin:$PATH"
#重新整理配置檔案
source /etc/profile
# 檢查版本看是否安裝成功
java -version
# 如果出現以下錯誤,則安裝下面的環境 -- 未出現則忽略
-bash: /root/java/jdk1.8.0_311/bin/java: /lib/ld-linux.so.2: bad ELF interpreter: 沒有那個檔案或目錄
# 安裝環境
yum install glibc.i686
在本地打好對應的jar包:
mvn package -Dmaven.test.skip=true
上傳到Linux伺服器(跟上面的操作一致),然後使用後臺的方式啟動:
nohup java -jar austin-web-0.0.1-SNAPSHOT.jar --server.port=8888 &
08、業務指標
從上面我配置了docker的監控、伺服器的監控、SpringBoot應用程式的監控。但可以發現的是,這大多數都是系統的指標監控。有的小夥伴可能就會問了:”呀?你不是說有業務監控嗎?咋不見你弄?“
我們也是可以實現自定義指標監控給到prometheus進行採集的,但如果系統本身如果接入了類ELK的系統,那我們更偏向於把業務指標資料在ELK上做掉。畢竟ELK面向的是日誌資料,只要我們記錄下了日誌就可以把日誌資料清洗出來做業務指標皮膚監控。
對於austin專案而言,後期是會接ELK相關的元件的。所以,這裡就不用prometheus來採集業務指標的資訊了,我更偏向於把prometheus作為採集系統指標的元件。
09、總結
這篇文章主要講的是監控的基本入門(一般這塊是由運維團隊去做的,但作為開發最好懂點吧)。如果你公司內的系統還沒監控,那可以規劃規劃下,用開源的元件入門下還是比較容易搭建出來的。
一個系統真不能少了監控,有監控排查的問題會快很多。
最後還是來回答下之前面試被問到的問題吧:“線上出了問題,你們是怎麼排查的?排查的思路是怎麼樣的?”
我是這樣理解的:首先,如果線上出了問題。那要想想最近有沒有曾經發布過系統,很多時候線上出現的問題都是由系統的釋出更改所導致的。如果最近釋出過系統,並且對線上的問題是造成比較大的影響,那首先先回滾,而不是先排查問題。
如果最近沒有釋出系統,那看下系統的監控是否正常(流量監控、業務監控等等),一般情況下我們能從監控上就發現問題了(畢竟系統我們是最瞭解的,有異常很快就能定位出問題了)
如果系統監控也沒問題,那得看下線上有沒有比較特殊的錯誤日誌了,通過錯誤日誌去排查問題。一般對系統比較瞭解的話,那還是容易能看出來的,再不行就拿著請求引數去dev環境上debug看執行過程吧。
所以:我們這有回滾的機制、有監控機制、一般的錯誤我們會及時告警到簡訊、郵件以及IM工具上,如果這些都沒有,那可能就得翻錯誤日誌復現問題,這是我的一般排查思路。
這篇文章到這裡就結束了,預告下:分散式配置中心我在程式碼裡已經接入了
不知不覺已經寫了這麼長了,點個贊一點都不過分吧?我是3y,下期見。
歡迎關注我的微信公眾號【Java3y】來聊聊Java面試和專案,對線面試官系列持續更新中!
【對線面試官+從零編寫Java專案】 持續高強度更新中!求star!!原創不易!!求三連!!
Gitee連結:https://gitee.com/austin
GitHub連結:https://github.com/austin