Prometheus(七) 監控spring boot docker 容器

主要步驟

  • 經過Prometheus提供的Java client包,在spring boot工程中生成咱們關心的業務指標,
  • 將spring boot工程打成docker 鏡像
  • 將docker容器部署到docker swarm集羣中
  • 修改Prometheus對應的file_sd_configs文件,將部署的服務追加進去
  • 經過Grafana觀察業務指標

本文主要闡述的是對容器中業務指標的監控,對容器的監控以及環境的搭建參照[Prometheus 監控Docker Swarm](Prometheus 監控Docker Swarm.md)java

Prometheus概念

  1. 數據模型web

    Prometheus中的數據都是時間序列值。指標名稱相同,label相同的記錄稱爲一個樣本值,Prometheus中存的就是各個樣本值在不一樣時間點的數據,稱爲一個時間序列,每一個時間點對應的值稱爲一個Sample,包含一個float64數值和一個精確到毫秒的時間值。spring

    每一個序列經過指標名稱以及相關的label來惟一肯定,指標名稱要代表觀察的目的(不是強制的)如(http_requests_total表示系統受到請求總數的時間序列),同一指標中的每一個key/value(稱爲label)都稱做一個維度,如(http_requests_total{code=200})表明請求成功的時間序列.docker

    外部應用經過PromQL來對時間序列進行相應的查找,在查詢時還能夠利用Prometheus提供的功能豐富的函數對時間序列中的值進行計算。springboot

  2. 指標類型restful

    Prometheus提供的客戶端jar包中把指標類型分爲以下四種app

    • Counter
    • Gauge
    • Histogram
    • Summary

    這個分類只針對客戶端使用者有效,在Prometheus server端是不進行區分的。對於Prometheus server端而言,客戶端返回的都是時間序列對應的一個Sample,如http_requests_total{code=200} 290,表示Prometheus server拉取指標的這個時間點,請求成功的總數是290次,是一個純文本數據,即使咱們不用Prometheus提供的客戶端,只要返回的數據知足這種格式,Prometheus server就能正常存儲,也能夠經過PromQL供外部查詢。maven

    1. Counter函數

      Counter對應的指標值只能是一個單獨的數值,而且除了能在服務啓動時重置外,只能對指標值作累加操做,不能作減法操做,能夠用來統計請求次數、任務執行次數、關鍵業務對象操做次數等。spring-boot

    2. Gauge

      Gauge對應的指標值只能是一個單獨的數值,與Counter不一樣的是,能夠對Gauge表明的指標值作仁義的加減操做,通常用來表示溫度、正在執行的job等指標

    3. Histogram

      Histogram 柱狀圖,再也不是簡單對指標的sample值進行加減等操做,對於每個sample值執行下面的三個操做:

      • 根據Histogram定義時指定的bucket區間,將sample分到各個bucket中,每一個bucket中存放的是落入這個區間的個數
      • 對每一個採樣點值累計和(sum)
      • 對採樣點的次數累計和(count)

      例如咱們經過Prometheus提供的客戶端經過Histogram.build().name("job_execute_time").help("job執行時間時間分佈(分)").buckets(1,5,10) .register();定義了一個histogram,用來統計job執行時間的分佈。對應的buckets是(1,5,10),表明四個區間

      • <=1分鐘
      • <=5分鐘
      • <=10分鐘
      • <無窮大

      Histogram會生成以下6個維度的指標值

      job_execute_time_bucket{le="1.0",} 
      job_execute_time_bucket{le="5.0",} 
      job_execute_time_bucket{le="10.0",} 
      job_execute_time_bucket{le="+Inf",}
      job_execute_time_count 
      job_execute_time_sum

      當咱們有一個job執行時間爲5.6分鐘,則對應的各個維度的值變成

      job_execute_time_bucket{le="1.0",} 0.0
      job_execute_time_bucket{le="5.0",} 0.0
      job_execute_time_bucket{le="10.0",} 1.0
      job_execute_time_bucket{le="+Inf",} 1.0
      job_execute_time_count 1.0
      job_execute_time_sum  5.6

      無窮大的確定是和job_execute_time_count一致的

      能夠看到Histogram類型的指標不會保留各個sample的具體數值,每一個bucket中也只是記錄樣本數的counter。

    4. Summary 採樣點分位圖統計,相似於histgram,可是採用分位數來將sample分到不一樣的bucket中,具體的區別查看HISTOGRAMS AND SUMMARIES,我的數學很差,理解的太痛苦了。

構建spring boot工程(2.x)

  1. pom.xml中追加Prometheus相關依賴

    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
    	<groupId>io.micrometer</groupId>
    	<artifactId>micrometer-core</artifactId>
    </dependency>
    <dependency>
    	<groupId>io.micrometer</groupId>
    	<artifactId>micrometer-registry-prometheus</artifactId>
    </dependency>
    
    <dependency>
    	<groupId>io.prometheus</groupId>
    	<artifactId>simpleclient</artifactId>
    	<version>0.8.1</version>
    </dependency>
  2. application.yml 文件中追加啓用Prometheus相關metric,

    spring:
      application:
        name: sbprometheus
    server:
      port: 8080
    
    management:
      metrics:
        export:
          prometheus:
            enabled: true
      endpoint:
        metrics:
          enabled: true
        prometheus:
          enabled: true
      endpoints:
        web:
          exposure:
            include: ["prometheus","health"]
    • 默認狀況 prometheus對應的endpoint是 /actuator/prometheus
  3. 定義業務須要的指標

    /**
     * 
     */
    package chengf.falcon.sb.prometheus;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import io.micrometer.prometheus.PrometheusMeterRegistry;
    import io.prometheus.client.Counter;
    import io.prometheus.client.Gauge;
    import io.prometheus.client.Histogram;
    import io.prometheus.client.Summary;
    
    /**
     * @author: 做者: chengaofeng
     * @date: 建立時間:2020-03-20 12:04:20
     * @Description: TODO
     * @version V1.0
     */
    @Configuration
    public class MetricConfig {
    
    	@Autowired
    	PrometheusMeterRegistry registry;
    
    	@Value("${spring.application.name}")
    	String appName;
    
    	@Bean
    	public Counter operatorCount() {
    		return Counter.build().name(appName + "_class_operator_count").help("操做總次數").labelNames("className")
    				.register(registry.getPrometheusRegistry());
    	}
    
    	@Bean
    	public Gauge runningJob() {
    		return Gauge.build().name(appName + "_running_job_count").help("正在運行的job數")
    				.register(registry.getPrometheusRegistry());
    	}
    
    	@Bean
    	public Histogram executeTime() {
    		return Histogram.build().name(appName + "_job_execute_time").help("job執行時間時間分佈(分)").buckets(1,5,10)
    				.register(registry.getPrometheusRegistry());
    	}
    	
    	@Bean
    	public Summary timeQuantile() {
    		return Summary.build().name(appName + "_job_execute_time_quantile").help("job執行時間時間分佈(分)").quantile(0.5, 0.05).quantile(0.9, 0.01)
    				.register(registry.getPrometheusRegistry());
    	}
    
    }
  4. 業務代碼中更新指標(經過resturl模擬實際的操做)

    /**
     * 
     */
    package chengf.falcon.sb.prometheus;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import io.prometheus.client.Counter;
    import io.prometheus.client.Gauge;
    import io.prometheus.client.Histogram;
    import io.prometheus.client.Summary;
    
    /**
     * @author: 做者: chengaofeng
     * @date: 建立時間:2020-03-03 19:02:43
     * @Description: TODO
     * @version V1.0
     */
    @RestController
    public class MetricController {
    
    
    	
    	@Autowired
    	Counter operatorCount;
    	
    	@Autowired
    	Gauge runningJob;
    	
    	@Autowired
    	Histogram executeTime;
    	
    	@Autowired
    	Summary timeQuantile;
    
    	@RequestMapping("/counter/{className}")
    	public String counter(@PathVariable String className) {
    		operatorCount.labels(className).inc();
    		return "COUNTER";
    	}
    	
    	@RequestMapping("/guage/{number}")
    	public String guage(@PathVariable int number) {
    		runningJob.set(number);
    		return "guage";
    	}
    	
    	@RequestMapping("/histogram/{time}")
    	public String histogram(@PathVariable double time) {
    		executeTime.observe(time);
    		return "histogram";
    	}
    	
    	@RequestMapping("/summary/{time}")
    	public String summary(@PathVariable double time) {
    		timeQuantile.observe(time);
    		return "summary";
    	}
    	
    	
    }
  5. 啓動sprong-boot工程,訪問上面的restful接口幾回,而後訪問/actuator/prometheus查看指標狀況,下面貼出一個樣例(去除掉spring 自動給咱們生成的各類指標)

    # HELP sbprometheus_job_execute_time_quantile job執行時間時間分佈(分)
    # TYPE sbprometheus_job_execute_time_quantile summary
    sbprometheus_job_execute_time_quantile{quantile="0.5",} 5.0
    sbprometheus_job_execute_time_quantile{quantile="0.9",} 13.0
    sbprometheus_job_execute_time_quantile_count 11.0
    sbprometheus_job_execute_time_quantile_sum 120.0
    
    # HELP sbprometheus_job_execute_time job執行時間時間分佈(分)
    # TYPE sbprometheus_job_execute_time histogram
    sbprometheus_job_execute_time_bucket{le="1.0",} 2.0
    sbprometheus_job_execute_time_bucket{le="5.0",} 3.0
    sbprometheus_job_execute_time_bucket{le="10.0",} 3.0
    sbprometheus_job_execute_time_bucket{le="+Inf",} 3.0
    sbprometheus_job_execute_time_count 3.0
    sbprometheus_job_execute_time_sum 6.5
    
    # HELP sbprometheus_class_operator_count 操做總次數
    # TYPE sbprometheus_class_operator_count counter
    sbprometheus_class_operator_count{className="transform",} 2.0
    sbprometheus_class_operator_count{className="sub",} 1.0
    
    # HELP sbprometheus_running_job_count 正在運行的job數
    # TYPE sbprometheus_running_job_count gauge
    sbprometheus_running_job_count 10.0

docker鏡像

由於在spring-boot工程的pom中,咱們追加了spring-boot-maven-plugin這個插件,因此執行mvn package後會生成一個獨立的可執行jar,因此製做鏡像時,只用基於openjdk的鏡像,再把這個jar copy進去,以後啓動就能夠了.

  1. 構建(在工程目錄下)

    $ mvn clean package
    $ cd target 
    $ cat > Dockerfile<<EOF
    #基礎鏡像基於openjdk,利用alpine
    FROM openjdk:8u212-jdk-alpine
    #所屬團隊
    MAINTAINER chengf
    
    #將編譯好的工程jar包copy到鏡像容器中
    ENV TARGET_JAR="sb-prometheus-0.0.1-SNAPSHOT.jar"
    COPY ${TARGET_JAR} /usr/src/${TARGET_JAR}
    
    
    # 工做目錄
    WORKDIR /usr/src
    #程序入口
    RUN echo "java -jar \${TARGET_JAR}  > start.sh \
                 && chmod 777 start.sh
    CMD ./start.sh
    
    EOF
    
    $ docker build -t sb-prometheus:0.0.1 .
  2. 啓動鏡像,測試鏡像是否正確

    docker run --rm --name sb-prometheus -p 8080:8080 sb-prometheus:0.0.1
    • 訪問一些咱們定義的restful接口以及/actuator/prometheus,看是否正常工做

部署到docker swarm集羣

  1. 編輯stack文件

    $ cd /opt/k8s/prometheus
    $ cat> sb-prom-stack.yml<<EOF
    version: "3"
    services:
      sbprometheus:
        image: sb-prometheus:0.0.1
        networks:
      		- mcsas-network
        deploy:
          restart_policy:
            condition: on-failure
      
    networks:
      mcsas-network: 
        external: true
    EOF
  2. 啓動服務

    $ docker stack deploy -c sb-prom-stack.yml sbprom

修改Prometheus的file_sd_configs中配置的文件

在[Prometheus 監控Docker Swarm](Prometheus 監控Docker Swarm.md)中,咱們在prometheus的配置文件中指定了以下配置段:

- job_name: 'springboot'
  metrics_path: /actuator/prometheus
  file_sd_configs:
  - files:
	 - /etc/prometheus/service.yaml

因此只用在掛載目錄下建立service.yaml,並追加咱們要監控的服務便可

$ cd /opt/k8s/prometheus/conf
$ cat>service.yaml<<EOF
- targets: ['sbprometheus:8080']
EOF

修改完成後,經過Prometheus服務暴露的端口查看指標分類,能夠發現咱們自定義的業務指標已經被Prometheus獲取到

由於咱們業務容器沒有暴露出來端口,因此爲了演示,進入容器內部,經過wget訪問咱們的restful接口,產生一些指標數據

$ docker ps |grep sbprometheus
8dbafd80573b        sb-prometheus:0.0.1                               "/bin/sh -c ./start.…"   44 minutes ago      Up 44 minutes                               sbprom_sbprometheus.1.kuzpe4he7j2iz9i43cwrrxh3x
$ docker exec -it 8dbafd80573b sh
/usr/src # wget -q -O - http://localhost:8080/summary/66
/usr/src # wget -q -O - http://localhost:8080/counter/tranform
/usr/src # wget -q -O - http://localhost:8080/counter/sub
/usr/src # wget -q -O - http://localhost:8080/histogram/1
/usr/src # wget -q -O - http://localhost:8080/histogram/3.4

進入grafana配置dashboard

在grafana中能夠對咱們的業務指標進行觀察如:

也能夠經過cAdvisor對我部署的這個服務對應的容器進行觀察

相關文章
相關標籤/搜索