hyperf/doc/zh/metric.md

299 lines
9.2 KiB
Markdown
Raw Normal View History

# 遥测与监控
微服务治理的一个核心需求便是服务可观察性。作为微服务的牧羊人,要做到时刻掌握各项服务的健康状态,并非易事。云原生时代这一领域内涌现出了诸多解决方案。本组件对可观察性当中的重要支柱遥测与监控进行了抽象,方便使用者与既有基础设施快速结合,同时避免供应商锁定。
## 安装
### 通过 Composer 安装组件
```bash
composer require hyperf/metric
```
[hyperf/metric](https://github.com/hyperf/metric) 组件默认安装了[Prometheus](https://prometheus.io/) 相关依赖。如果要使用[StatsD](https://github.com/statsd/statsd)或[InfluxDB](http://influxdb.com),还需要执行下面的命令安装对应的依赖:
```bash
#StatsD 所需依赖
composer require domnikl/statsd
#InfluxDB 所需依赖
composer require influxdb/influxdb-php
```
### 增加组件配置
如文件不存在,可执行下面的命令增加 `config/autoload/metric.php` 配置文件:
```bash
php bin/hyperf.php vendor:publish hyperf/metric
```
## 使用
### 配置
#### 选项
* `default`:配置文件内的 `default` 对应的值则为使用的驱动名称。驱动的具体配置在 `metric` 项下定义,使用与 `key` 相同的驱动。
```php
'default' => env('TELEMETRY_DRIVER', 'prometheus'),
```
* `use_standalone_process`: 是否使用独立监控进程。推荐开启。关闭后将在Worker进程中处理指标收集与上报。
```php
'use_standalone_process' => env('TELEMETRY_USE_STANDALONE_PROCESS', true),
```
* `enable_default_metric`: 是否统计默认指标。默认指标包括内存占用、系统CPU负载以及Swoole Server指标和Swoole Coroutine指标。
```php
'enable_default_metric' => env('TELEMETRY_ENABLE_DEFAULT_TELEMETRY', true),
```
#### 配置 Prometheus
使用 Prometheus 时,在配置文件中的 `metric` 项增加 Prometheus 的具体配置。
```php
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),
'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_inteval' => env('PROMETHEUS_PUSH_INTEVAL', 5),
],
],
];
```
Prometheus 有两种工作模式,推模式与拉模式,本组件均可支持。
使用爬模式Prometheus官方推荐时需设置
```php
'mode' => Constants::SCRAPE_MODE
```
并配置爬取地址`scrape_host`、爬取端口`scrape_port`、爬取路径`scrape_path`。Prometheus可以在对应配置下以HTTP访问形式拉取全部指标。
使用推模式时需设置:
```php
'mode' => Constants::PUSH_MODE
```
并配置推送地址`push_host`、推送端口`push_port`、推送间隔`push_inteval`。
注意爬模式下必须启用独立进程即use_standalone_process = true。
#### 配置 StatsD
使用 StatsD 时,在配置文件中的 `metric` 项增加 StatsD 的具体配置。
```php
return [
'default' => env('TELEMETRY_DRIVER', 'statd'),
'use_standalone_process' => env('TELEMETRY_USE_STANDALONE_PROCESS', true),
'enable_default_metric' => env('TELEMETRY_ENABLE_DEFAULT_TELEMETRY', true),
'metric' => [
'statsd' => [
'driver' => Hyperf\Metric\Adapter\StatsD\MetricFactory::class,
'namespace' => env('APP_NAME', 'skeleton'),
'udp_host' => env('STATSD_UDP_HOST', '127.0.0.1'),
'udp_port' => env('STATSD_UDP_PORT', '8125'),
'enable_batch' => env('STATSD_ENABLE_BATCH', true),
'push_inteval' => env('STATSD_PUSH_INTEVAL', 5),
'sample_rate' => env('STATSD_SAMPLE_RATE', 1.0),
],
],
];
```
StatsD 目前只支持UDP模式需要配置UDP地址`udp_host`UDP端口`udp_port`、是否批量推送`enable_batch`(减少请求次数)、批量推送间隔`push_inteval`以及采样率`sample_rate`。
#### 配置 InfluxDB
使用 InfluxDB 时,在配置文件中的 `metric` 项增加 InfluxDB 的具体配置。
```php
return [
'default' => env('TELEMETRY_DRIVER', 'influxdb'),
'use_standalone_process' => env('TELEMETRY_USE_STANDALONE_PROCESS', true),
'enable_default_metric' => env('TELEMETRY_ENABLE_DEFAULT_TELEMETRY', true),
'metric' => [
'influxdb' => [
'driver' => Hyperf\Metric\Adapter\InfluxDB\MetricFactory::class,
'namespace' => env('APP_NAME', 'skeleton'),
'host' => env('INFLUXDB_HOST', '127.0.0.1'),
'port' => env('INFLUXDB_PORT', '8086'),
'username' => env('INFLUXDB_USERNAME', ''),
'password' => env('INFLUXDB_PASSWORD', ''),
'dbname' => env('INFLUXDB_DBNAME', true),
'push_inteval' => env('INFLUXDB_PUSH_INTEVAL', 5),
],
],
];
```
InfluxDB 使用默认的HTTP模式需要配置地址`host`UDP端口`port`、用户名`username`、密码`password`、`dbname`数据表以及批量推送间隔`push_inteval`。
### 基本抽象
遥测组件对常用的三种数据类型进行了抽象,以确保解耦具体实现。
三种类型分别为:
* 计数器(Counter): 用于描述单向递增的某种指标。如HTTP请求计数。
```php
interface CounterInterface
{
public function with(string ...$labelValues): self;
public function add(int $delta);
}
```
* 測量器(Gauge):用于描述某种随时间发生增减变化的指标。如连接池内的可用连接数。
```php
interface GaugeInterface
{
public function with(string ...$labelValues): self;
public function set(float $value);
public function add(float $delta);
}
```
* 直方图(Histogram)用于描述对某一事件的持续观测后产生的统计学分布通常表示为百分位数或分桶。如HTTP请求延迟。
```php
interface HistogramInterface
{
public function with(string ...$labelValues): self;
public function observe(float $delta);
}
```
### 配置中间件
配置完驱动之后只需配置一下中间件就能启用请求Histogram统计功能。
打开 `config/autoload/middlewares.php` 文件,在 `http` 节点启用中间件。
```php
<?php
declare(strict_types=1);
return [
'http' => [
\Hyperf\Metric\Middleware\MetricMiddeware::class,
],
];
```
### 自定义使用
通过HTTP中间件遥测仅仅是本组件用途的冰山一角您可以注入`Hyperf\Metric\Contract\MetricFactoryInterface`类来自行遥测业务数据。比如:创建的订单数量、广告的点击数量等。
```php
<?php
declare(strict_types=1);
namespace App\Controller;
use App\Model\Order;
use Hyperf\Metric\Contract\MetricFactoryInterface;
class IndexController extends AbstractController
{
/**
* @Inject
* @var MetricFactoryInterface
*/
private $metricFactory;
public function create(Order $order)
{
$counter = $this->metricFactory->makeCounter('order_created', ['order_type']);
$counter->with($order->type)->add(1);
// 订单逻辑...
}
}
```
`MetricFactoryInterface`中包含如下工厂方法来生成对应的三种基本统计类型。
```php
public function makeCounter($name, $labelNames): CounterInterface;
public function makeGauge($name, $labelNames): GaugeInterface;
public function makeHistogram($name, $labelNames): HistogramInterface;
```
上述例子是统计请求范围内的产生的指标。有时候我们需要统计的指标是面向完整生命周期的,比如统计异步队列长度或库存商品数量。此种场景下可以监听`MetricFactoryReady`事件。
```php
<?php
declare(strict_types=1);
namespace App\Listener;
use Hyperf\Event\Contract\ListenerInterface;
use Hyperf\Metric\Listener\OnMetricFactoryReady;
use Psr\Container\ContainerInterface;
use Redis;
class OnMetricFactoryReady implements ListenerInterface
{
/**
* @var ContainerInterface
*/
protected $container;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
public function listen(): array
{
return [
MetricFactoryReady::class,
];
}
public function process(object $event)
{
$redis = $this->container->get(Redis::class);
while (true) {
$length = $redis->llen('queue');
$event
->factory
->makeGauge('queue_length', ['driver'])
->with('redis')
->set($length);
sleep(1);
}
}
}
```
### 注解
您可以使用`@Counter(name="stat_name_here")`和`@Histogram(name="stat_name_here")`来统计切面的调用次数和运行时间。
关于注解的使用请参阅[注解章节](https://doc.hyperf.io/#/zh/annotation)。