服务监控

微服务治理的一个核心需求便是服务可观察性。作为微服务的牧羊人,要做到时刻掌握各项服务的健康状态,并非易事。云原生时代这一领域内涌现出了诸多解决方案。本组件对可观察性当中的重要支柱遥测与监控进行了抽象,方便使用者与既有基础设施快速结合,同时避免供应商锁定。

php-fpm

Dockerfile

#php exporter监控
COPY ./exporter/php-fpm-exporter /usr/bin/php-fpm-exporter   
COPY ./exporter/nginx-status.conf /etc/nginx/conf.d/nginx-status.conf
COPY --chmod=0600 ./confd/default-supervisor.conf /etc/supervisor/conf.d/default.conf
#开启php监控
RUN set-ex \
&& sed -i '$apm.status_path = /status'  /etc/php/fpm/php-fpm.conf \
&& sed -i '$aping.path = /ping'  /etc/php/fpm/php-fpm.conf

nginx

server {
    listen 9999;
    server_name  localhost;
    location /stub_status {
       stub_status on;
       access_log off;
       allow 127.0.0.1;
       deny all;
    }
    location ~ ^/(status|ping)$ {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
        allow 127.0.0.1;
        deny all;
}
}

启动exporter (supervisor)

[program:php-fpm-exporter]
command = /usr/bin/php-fpm-exporter --addr="0.0.0.0:9114" --endpoint="http://127.0.0.1:9999/status"
autostart=true
autorestart=true
priority=992
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stdout
stderr_logfile_maxbytes=0

k8s配置

prometheus.io/path: /metrics
        prometheus.io/port: '9114'
        prometheus.io/scrape: 'true'

Prometheus

job_name: kubernetes-php-fpm
honor_timestamps: true
honor_labels: false
scrape_interval: 30s
scheme: http
metrics_path: /metrics
relabel_configs:
- regex: Running
  action: keep
  source_labels: [__meta_kubernetes_pod_phase]
  replacement: $1
  separator: ;
- regex: 'true'
  action: keep
  source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
  replacement: $1
  separator: ;
- regex: (.+)
  action: replace
  source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
  replacement: $1
  separator: ;
  target_label: __metrics_path__
- regex: (.+)
  action: replace
  source_labels: [__meta_kubernetes_pod_label_targetId]
  replacement: $1
  separator: ;
  target_label: arms_instance_id
- regex: (.+)
  action: replace
  source_labels: [__meta_kubernetes_pod_label_uid]
  replacement: $1
  separator: ;
  target_label: arms_instance_name
- regex: ([^:]+)(?::\d+)?;(\d+)
  action: replace
  source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
  replacement: $1:$2
  separator: ;
  target_label: __address__
- {regex: __meta_kubernetes_pod_label_(.+), action: labelmap, replacement: $1, separator: ;}
- regex: (.*)
  action: replace
  source_labels: [__meta_kubernetes_namespace]
  replacement: $1
  separator: ;
  target_label: kubernetes_namespace
- regex: (.*)
  action: replace
  source_labels: [__meta_kubernetes_pod_name]
  replacement: $1
  separator: ;
  target_label: kubernetes_pod_name
metric_relabel_configs:
- regex: up
  action: drop
  source_labels: [__name__]
  separator: ;
kubernetes_sd_configs:
- role: pod
  namespaces: {}
  follow_redirects: true
scrape_timeout: 5s

grafana大盘

https://grafana.com/grafana/dashboards/4912-kubernetes-php-fpm/

hyperf

通过 Composer 安装组件

composer require hyperf/metric

使用 Prometheus 时,在配置文件中的 metric 项增加 Prometheus 的具体配置。

use Hyperf\Metric\Adapter\Prometheus\Constants;

return [
    'default' => env('TELEMETRY_DRIVER', 'prometheus'),
    'use_standalone_process' => env('TELEMETRY_USE_STANDALONE_PROCESS', true),
    'enable_default_metric' => env('TELEMETRY_ENABLE_DEFAULT_TELEMETRY', true),
    'default_metric_interval' => env('DEFAULT_METRIC_INTERVAL', 5),
    'metric' => [
        'prometheus' => [
            'driver' => Hyperf\Metric\Adapter\Prometheus\MetricFactory::class,
            'mode' => Constants::SCRAPE_MODE,
            'namespace' => env('APP_NAME', 'skeleton'),
            'scrape_host' => env('PROMETHEUS_SCRAPE_HOST', '0.0.0.0'),
            'scrape_port' => env('PROMETHEUS_SCRAPE_PORT', '9502'),
            'scrape_path' => env('PROMETHEUS_SCRAPE_PATH', '/metrics'),
            'push_host' => env('PROMETHEUS_PUSH_HOST', '0.0.0.0'),
            'push_port' => env('PROMETHEUS_PUSH_PORT', '9091'),
            'push_interval' => env('PROMETHEUS_PUSH_INTERVAL', 5),
        ],
    ],
];

k8s配置

prometheus.io/path: /metrics
        prometheus.io/port: '9502'
        prometheus.io/scrape: 'true'

Prometheus

job_name: kubernetes-hyerpf
honor_timestamps: true
honor_labels: false
scrape_interval: 60s
scheme: http
metrics_path: /metrics
relabel_configs:
- regex: Running
  action: keep
  source_labels: [__meta_kubernetes_pod_phase]
  replacement: $1
  separator: ;
- regex: 'true'
  action: keep
  source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
  replacement: $1
  separator: ;
- regex: (.+)
  action: replace
  source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
  replacement: $1
  separator: ;
  target_label: __metrics_path__
- regex: (.+)
  action: replace
  source_labels: [__meta_kubernetes_pod_label_targetId]
  replacement: $1
  separator: ;
  target_label: arms_instance_id
- regex: (.+)
  action: replace
  source_labels: [__meta_kubernetes_pod_label_uid]
  replacement: $1
  separator: ;
  target_label: arms_instance_name
- regex: ([^:]+)(?::\d+)?;(\d+)
  action: replace
  source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
  replacement: $1:$2
  separator: ;
  target_label: __address__
- {regex: __meta_kubernetes_pod_label_(.+), action: labelmap, replacement: $1, separator: ;}
- regex: (.*)
  action: replace
  source_labels: [__meta_kubernetes_namespace]
  replacement: $1
  separator: ;
  target_label: kubernetes_namespace
- regex: (.*)
  action: replace
  source_labels: [__meta_kubernetes_pod_name]
  replacement: $1
  separator: ;
  target_label: kubernetes_pod_name
kubernetes_sd_configs:
- role: pod
  namespaces: {}
  follow_redirects: true
scrape_timeout: 5s

grafana

https://github.com/hyperf/metric/blob/master/grafana.json