我是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
賬號:[email protected]
密碼: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