? ? ? ?介紹部署方式的文檔很多,這里就不多做介紹了,更多的本次部署的經驗教訓,框架的模式等的總結。
? ? ? ?公司需要發布一套云環境產品,因此需要選擇一套框架完成服務發現、服務監控、服務預警的全過程。
? ? ? 經過比對,決定選擇Prometheus和Consul作為核心組件,Grafana、AlertManager和其他組件,完成全部過程。其完成結構圖如下:
先說一下Prometheus監控體系的問題:
1、結構比較復雜
? ? ? 組件非常多,從圖中可以看到,整個結構組件幾十上百個。
? ? ? 結構上的復雜,也帶來了部署上的困難。這個后面講部署的時候再詳細說。
? ? ? 另外就是結構的復雜還帶來了維護的困難,因為組件分散在各處(集中存放的話,同服務端口配置會很麻煩),需要時刻維護一個結構圖,以保證整個結構的可維護性。
2、prometheus的集群穩定性
? ? ? 包括prometheus和alertmanager組件在內,都存在集群可用性的問題。
? ? ? prometheus官方給出的解決方案,要么是不集群,即各服務均單獨維護,或者使用統一的數據庫,以保證整體的集群數據一致性。前者顯然不能保證數據一致性,后者帶來的配置復雜性又會成倍提高(配置內置數據庫還是外置數據庫也同樣是個問題),給運維(架構)同學會帶來持續的壓力。
? ? ? ? alertmanger在官方文檔中,其提法是在某個版本后,只需要如下配置即可:
? ? ? 但是然并卵,經過多次測試,這種配置,同一個信息一定會被多個接收端同時接收到,并不是同一個告警信息所有alertmanager實例只發送一次。必須使用原有的參數配置,即:
? ? ? 才能完成alertmanager的同步,但是又然并卵,某些情況下仍然存在問題,后面再說。
另外就是prometheus的默認數據庫,官方的說法是:
? ? ? ? ? Note that a limitation of the local storage is that it is not clustered or replicated. Thus, it is not arbitrarily scalable or durable in the face of disk or node outages and should thus be treated as more of an ephemeral sliding window of recent data. However, if your durability requirements are not strict, you may still succeed in storing up to years of data in the local storage.
? ? ? ? ? 簡單說,就是官方自己也不推薦你強依賴這套數據庫,除非你的持久化需求不太強烈。也就是說如果你的環境壓力比較大,數據量很大,持久性和一致性要求比較高,那么抱歉,你換一個數據庫吧,比如influxDB。
3、exporter組件來源不統一
? ? ? 因為prometheus只是給出了數據聚集的解決方案以及存儲和查詢的解決方案,其本身并不負責從各終端拉取狀態服務信息,服務信息的拉取是依靠不同的exporter完成的。而其官方又沒有提供全部的exporter(嚴格說,基本就沒幾個exporter是官方提供的),這就帶來了幾個問題。
? ? ? 首先是exporter需要從不同的渠道進行收集,最大的來源是prometheus文檔和github,也存在其他的渠道,所以第一是需要你自己去找exporter,其次是你得選擇一個合適的來用(可能找到多個,當然也有可能找不到)。
? ? ? 其次是標準不同,因為這些都是社區貢獻,而始作俑者只是給出了答案的格式而沒有約定部署方式,所以各個exporter的部署方式都不一樣,需要逐個摸索熟悉和了解,甚至有些連文檔都沒有。所以工作的最后一步一定是把啟動命令用腳本記錄下來,并且歸檔保存以備后用。
? ? ? 最后是不同的使用方式導致集成的方式也不同,大部分exporter是獨立運行的,但也有部分exporter是跟其他服務嵌套在一起使用的,其使用復雜度就更高了,這就導致其維護難度更高,典型的例如jmx插件以及nginx的vts插件,都是典型的嵌套組件,一旦運行環境發生變化,又需要持續進行維護。
? ? ? 簡而言之,整個exporter組件就是難查詢、難部署、難維護,是維護是非常耗時耗力的過程。
4、監控信息需要定制
? ? ? 標準輸出的監控信息更多的普遍化的信息,如果需要更個性化的內容,就需要自己定制開發了,所以這部分工作是無法省去的。例如java后臺程序的監控是由插件完成的,但如果你希望收集更詳細的,例如500接口的時間和次數等信息,就必須自己開發監控內容以及圖標信息了。
5、集成的匹配度不高
? ? ? 這點主要表現在consul和prometheus之間的集成,本來是希望自動完美集成,但是實際用到才發現,很多地方是需要二次配置的,最典型的就是如何保證consul自己不進入到prometheus的集成監控列表中,如何調整對應的標簽信息等,這種幾乎做匹配就需要做處理的地方,官方卻沒有給出任何的最佳實踐的文檔,不得不說是一種缺陷。
? ? ? 上面基本聊完了這套架構的缺點,再說說優點吧。
1、全部開源
? ? ? 這點當然是最重要的,我們幾乎可以在社區找到我們一般需求的全部組件,不需要自己再次開發,對于成本壓力比較大的公司而言,這當然是非常好的選擇。
2、開箱即用
? ? ? 目前的組件除了極個別需要你下載自己編譯之外,所有的組件都是開箱即用的(不管這個過程是不是那么舒服)。
3、功能基本滿足基本需求
? ? ? 如果你對監控內容的要求不是特別高的話,那么一般的監控信息已經可以滿足你絕大部分的需求了,二次開發的工作量可以降到最低。
4、支持集群
? ? ? 無論官方給出的集群方案是否完美,但至少是存在開源的免費集群方案的,這比收費和自己建設簡單多了。
一句話總結一下,prometheus監控體系的優點就是入門簡單,缺點就是后續成本比較高。
? ? ? 再聊一下consul這套架構,照例還是先說說里面的坑。
? ? ? 1、配置沖突
因為后端都是使用springboot為主的微服務,因此consul的集成依賴了springcloud中關于consul服務發現的部分。這里提示大家一下,如果你使用的springcloud中的其他服務發現模式,例如你很不巧的用了zk作為配置中心,并使用了springcloud的相關組件來注入屬性,那么你很快會發現你的服務在引入了consul和zookeeper之后,無法啟動了。因為他們都注冊了org.springframework.boot.autoconfigure.EnableAutoConfiguration這個bean,同一個bean顯然是不能同時存在于spring的context中的,這里推薦一個github上貢獻的開源解決策略:
https://github.com/cloud-ready/spring-cloud-service-discovery
? ? ? 但里面的代碼可能并不是都用得上,大家可以自行調整,抓住關鍵即可。
? ? ? 2、管理復雜
? ? ? 為了簡化各項目配置,consul的服務地址均使用了默認的localhost:8500這個地址,這就意味著每臺宿主機都必須有一個consul的client端在工作。可以想見的是,隨著宿主機的增多,consul-client的數量也會持續增加,對它們的管理勢必會持續增大管理成本。
? ? ? 這個問題還容易出現端口沖突,因為consul占用的端口比較多(5個端口),且位于8000-9000號段(8500,8300,8301,8302,8600),是比較容易跟其他應用的端口發生沖突的,實際操作中,如果對該機制不熟悉,則很容易在配置時提前占用相關接口。
? ? ? 3、注銷機制
? ? ? consul的注銷機制是存在問題的,但是最近的測試發現似乎最新的server端已經增加了一段時間不在線即注銷對應的服務實例的操作,不過并沒有專門進行測試。但無論如何,某一個服務實例宕機,如果想通過consul-server端進行api調用注銷仍然是不可行的,你只能通過該實例注冊的consul-client進行注銷。
? ? ? 4、pull機制
? ? ? 這個問題在prometheus也存在,默認情況下,數據都是由server端從client端拉數據的,因此client端向server端注冊時,必須保證逆向可達,這一點在ip和網絡配置上是存在一定環境要求的,這種模式雖然解決server端可能會被client同時請求而壓垮的場景,但是也帶來了逆向必須可達的環境要求,給開發和調試會帶來一定困難。
? ? ? 再說說consul架構的優勢
? ? ? 1、與終端解耦
? ? ? consul不是spring開發,開發之處就是可以接入各種終端的,這方面能力不需要擔心。
? ? ? 2、接入便捷
? ? ? 默認環境下,java后端接入成本極低,開發人員無需感知。
? ? ? 3、服務穩定
? ? ? 在集群模式和拉數據模式下,server壓力可控,不用太過于擔心其穩定性問題。
? ? ? 4、和prometheus接入簡單
? ? ? prometheus官方支持consul接入,因此在初步接入層面比較容易,不需要額外開發和配置。(這也是選擇這兩套搭伴使用的很重要原因)
? ? ? 5、開源和開箱即用
? ? ? 與prometheus相同。
? ? ? 再說一下其他組件的優缺點:
? ? ? 1、Grafana
? ? ? ? Grafana的可用性很高,圖表插件非常多,完全可以根據自己的需求進行選用,并且社區上傳了大量的Dashboard可供使用,因此其優勢與其他組件類似,開源、開箱即用等。但其社區貢獻也帶來了如exporter一般的問題,首先是Dashboard和exporter的匹配度普遍不高,下載之后需要大量的二次調整(花費了相當的時間),其次就是接入的api不友好,例如接入prometheus,其接入api即為prometheus的時序數據庫的查詢語句,由于不熟悉,也導致需要大量時間進行熟悉的理解。最后就是缺少列表信息的內容,社區的Dashboard主要由各種圖表構成,做整體分析是ok的,但是問題定位的時候就顯得力不從心了。
? ? ? 2、alertmanager
? ? ? 剛才已經提到了alertmanager的集群問題,alertmanager集群即便使用了官方的cluster配置,仍然會在某些情況下出現重復發送消息的問題。實測是在某服務down后,啟動該服務。觀察日志發現,down的時候確實只收到了一條消息,但是很奇怪的是啟動的時候也會收到信息,并且此時是兩條信息。因為并沒有配置服務上線的告警信息,所以只可能是服務down的提示信息,暫時還沒有去深入了解相關文檔(也不確定有沒有相關文檔)。
? ? ? 其次就是alertmanager的匹配規則配置很復雜,是在prometheus的時序數據庫的基礎上做二次定制,也意味著如果你中間更換數據庫,那么之前的配置需要重新調整。這個對于后期配置開發是非常不利的,尤其其鍵值還依賴exporter的metrics信息,從編碼的角度而言,這里缺少接口的封裝,對于程序的可維護性是非常不利的。
? ? ? 大致就是這些了,下面再列一下目前使用到的組件以及相關信息。
? ? ? 以下是用到的exporter的組件列表。
組件名來源啟動命令備注
jmx_exporter
https://github.com/prometheus/jmx_exporter
需要內嵌至容器啟動命令中 JAVA_OPTS="$JAVA_OPTS -javaagent:/*/prometheus_exporter/jmx/jmx_prometheus_javaagent-0.11.0.jar=9151:/*/prometheus_exporter/jmx/tomcat.yaml"不同的jmx監控對象需要配置不同的yaml文件以約定其輸出內容,配置文檔見最后的附件
node_exporter
https://github.com/prometheus/node_exporter
nohup ./node_exporter --web.listen-address=":8909" >nohup.out 2>&1 &
nginx_vts_exporter
https://github.com/hnlq715/nginx-vts-exporter
這個插件需要依賴nginx支持相關功能,當nginx支持后,啟動該exporter即可
php-fpm-exporter
https://github.com/bakins/php-fpm-exporter
nohup ./php-fpm-exporter.linux.amd64 --addr x.x.x.x:xxxx --endpoint http://x.x.x.x:xxxx/php_fpm_status >nohup.out 2>&1 &
依賴php-fpm的功能,一般需要在nginx進行配置后方可使用
mysql_exporter
https://github.com/prometheus/mysqld_exporter
./mysqld_exporter --log.level=debug --web.listen-address=:8908 --config.my-cnf=mysql.cfg --collect.auto_increment.columns --collect.global_status
1、需要一個有權限的賬號
2、需要配置一個配置文件,輸入mysql的信息
我的配置信息如下:
[client]
host=
port=
user=
password=
redis_exporter
https://github.com/oliver006/redis_exporter
nohup ./redis_exporter -web.listen-address=":8912" -redis.file=redisconfig.cfg >nohup.out 2>&1 &?
配置文檔信息:redis://xx.xx.2.xx:xxxx,password
zookeeper_exporter
https://github.com/carlpett/zookeeper_exporter
./zookeeper_exporter -bind-addr=:8902 -zookeeper=localhost:8182
貌似不支持單機集群采集,待驗證
mongodb_exporter
https://github.com/dcu/mongodb_exporter
./mongodb_exporter --web.listen-address=:8919 --mongodb.uri=mongodb://user:password@uri:port
需要構建用戶到mongo數據庫中
下面是grafana的內容模板:
http://note.youdao.com/noteshare?id=996753825eac4fd3e7c6dafcf498bb64
A9QZ
沒有貼編號的原因是里面大多數都有過修改,如果直接使用前面的exporter,應該是可以直接對接的。