背景
項(xiàng)目中部署prometheus的時(shí)候,最開(kāi)始如果需要額外添加一臺(tái)機(jī)器,需要手動(dòng)更新prometheus的配置文件,再重新啟動(dòng),如果是正式生產(chǎn)環(huán)境存在大量的機(jī)器的情況,這種方式有很大的運(yùn)維成本。于是想如果能讓prometheus自動(dòng)發(fā)現(xiàn)要添加的應(yīng)用實(shí)例,則可以免去手動(dòng)添加的繁瑣操作。組內(nèi)項(xiàng)目有使用eureka做服務(wù)發(fā)現(xiàn),它也有對(duì)應(yīng)的API開(kāi)放,就想如果能夠集成eureka會(huì)方便很多。開(kāi)始想的是自己寫(xiě)個(gè)腳本(如python)從eureka獲取注冊(cè)的實(shí)例,然后寫(xiě)到配置里,使用prometheus的文件服務(wù)發(fā)現(xiàn),然后做reload實(shí)現(xiàn)。
好在后續(xù)調(diào)研發(fā)現(xiàn),在新版本的prometheus已經(jīng)支持了集成eureka,只需要添加配置就可以實(shí)現(xiàn)想要的功能。
說(shuō)明
使用的prometheus版本是2.22.0。項(xiàng)目中使用prometheus + micrometer進(jìn)行基礎(chǔ)的JVM、http、數(shù)據(jù)庫(kù)、線程池以及業(yè)務(wù)的可用度、耗時(shí)監(jiān)控,這塊后面單獨(dú)再寫(xiě)文章詳細(xì)介紹,下面會(huì)簡(jiǎn)單介紹。只要知道在完成后,會(huì)通過(guò)在actuator/prometheus暴露各項(xiàng)指標(biāo),然后由prometheus拉取,實(shí)現(xiàn)數(shù)據(jù)的采集。
springboot actuator集成prometheus
- 依賴
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_common</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
<version>1.5.1</version>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<version>1.5.1</version>
</dependency>
- 配置
添加application.yml
management:
endpoints:
enabled-by-default: true
web:
exposure:
include: ['pause','prometheus']
endpoint:
pause:
enabled: true
prometheus:
enabled: true
server:
port: 8293
servlet:
context-path: /api # 給actuator也設(shè)置context-path 這個(gè)配置在springboot 2.4 0 之后,改為base-path, 相應(yīng)eureka配置也要修改
這里基于安全考慮對(duì)actuator添加了額外的端口,和服務(wù)端口不一樣。因此,在本地eureka的配置中添加一個(gè)metadataMap.prometheus.port項(xiàng)。這個(gè)會(huì)保存到eureka的metadata,然后被prometheus eureka sd解析到。如下:
eureka:
instance:
prefer-ip-address: true
lease-renewal-interval-in-seconds: 10
metadataMap.prometheus.port: 8293
加幾個(gè)自定義標(biāo)簽,比如這里設(shè)置application為業(yè)務(wù)名,以及添加一個(gè)idc表示業(yè)務(wù)部署機(jī)房。
@Slf4j
@Configuration
public class PrometheusConfiguration {
private final Tags commonTags = Tags.of("application", "myapp", "idc", System.getProperty("idc"));
@Autowired
private MeterRegistry meterRegistry;
@Bean
public MeterRegistryCustomizer<MeterRegistry> configurer() {
//key value
//log4j 的用不到,排除掉
return (registry) -> registry.config().commonTags(commonTags).meterFilter(MeterFilter.denyNameStartsWith("log4j")).pauseDetector();
}
}
- 結(jié)果示例
項(xiàng)目集成完成后啟動(dòng),訪問(wèn)yourapp:port/actuator/prometheus得到prometheus的待采集數(shù)據(jù)
# HELP jvm_memory_used_bytes The amount of used memory
# TYPE jvm_memory_used_bytes gauge
jvm_memory_used_bytes{application="myapp",area="nonheap",id="Code Cache",idc="staging",} 1.20810432E8
jvm_memory_used_bytes{application="myapp",area="nonheap",id="Metaspace",idc="staging",} 1.5934492E8
jvm_memory_used_bytes{application="myapp",area="heap",id="G1 Old Gen",idc="staging",} 2.54245616E8
jvm_memory_used_bytes{application="myapp",area="heap",id="G1 Eden Space",idc="staging",} 2.0447232E8
jvm_memory_used_bytes{application="myapp",area="nonheap",id="Compressed Class Space",idc="staging",} 1.8597632E7
jvm_memory_used_bytes{application="myapp",area="heap",id="G1 Survivor Space",idc="staging",} 8388608.0
配置
然后我們添加prometheus的配置,讓其自動(dòng)發(fā)現(xiàn)我們注冊(cè)到eureka的服務(wù)實(shí)例。
scrape_configs:
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
- job_name: 'prometheus'
# metrics_path defaults to '/metrics'
# scheme defaults to 'http'.
static_configs:
- targets: ['localhost:9090']
#原先靜態(tài)配置的targets,需要重啟和改配置文件
# - job_name: 'myapp'
# metrics_path: '/actuator/prometheus'
# scrape_interval: 5s
# static_configs:
# - targets: ['myapp1:8157', 'myapp2:8157']
- job_name: 'eureka_sd'
eureka_sd_configs:
- server: 'http://my_eureka.server:port/eureka' #注意這里地址后面是eureka
basic_auth:
username: 'myuser'
password: 'mypass' # 應(yīng)用對(duì)/actuator添加了spring security http basic驗(yàn)證
relabel_configs:
- source_labels: [__address__, __meta_eureka_app_instance_metadata_prometheus_port]
action: replace
regex: ([^:]+)(?::\d+)?;(\d+)
replacement: $1:$2
target_label: __address__
metrics_path: '/actuator/prometheus' #采集地址
之后重啟prometheus服務(wù)或者reload配置,然后在prometheus的管理界面訪問(wèn)/service-discovery,就可以看到通過(guò)eureka服務(wù)發(fā)現(xiàn)添加的實(shí)例。配置中relablel_configs的部分,可以通過(guò)對(duì)原始標(biāo)簽對(duì)應(yīng)內(nèi)容的匹配過(guò)濾,生成新的標(biāo)簽內(nèi)容。比如根據(jù)eureka注冊(cè)的實(shí)例名稱和端口,生成新的目標(biāo)標(biāo)簽。
總結(jié)
以上就是本期的所有內(nèi)容。目前對(duì)于prometheus的應(yīng)用比較初級(jí),其實(shí)還有許多要解決的問(wèn)題,首先是數(shù)據(jù)的持久化,本來(lái)考慮支持openTSDB,公司也有內(nèi)部資源支持,但是openTSDB查詢對(duì)于模糊查詢支持不太好,且公司的資源維護(hù)也在起步階段,試用后發(fā)現(xiàn)有些問(wèn)題,再者沒(méi)有很好的兼容grafana。因此,還是使用在單機(jī)的prometheus本地tsdb存儲(chǔ);其次,對(duì)于報(bào)警方面目前還沒(méi)有深入調(diào)研,我們知道監(jiān)控和報(bào)警一般是相輔相成的;最后就是prometheus服務(wù)本身的HA這塊,也需要再做了解。