Swoole 健康检查

参考文献

client同步阻塞客户端:https://wiki.swoole.com/#/client?id=%E5%AE%8C%E6%95%B4%E7%A4%BA%E4%BE%8B
heartbeat_check_interval:https://wiki.swoole.com/#/server/setting?id=heartbeat_check_interval

健康检查机制

对于长连接这种断开的问题;主要的点就在于服务端会保存客户端会话的有效性以及平台上监控所有客户端的网络状况;对于这种功能的实现我们可以通过两种方式实现
1、轮询机制
2、心跳机制
在这里插入图片描述
在这里插入图片描述

代码演示

tcpServer.php

<?php
// var_dump(swoole_get_local_ip());die;
echo swoole_get_local_ip()['eth0'].":9503\n";
$server = new Swoole\Server("0.0.0.0", 9503);

// 每个2s检测,在3s内没有给我发送信息的连接
$server->set([
    'heartbeat_check_interval' => 2, // 检测所有的连接
    'heartbeat_idle_time' => 3,
]);

$server->on('connect', function ($server, $fd){
   echo "connection open: {$fd}\n";
});

$server->on('receive', function ($server, $fd, $reactor_id, $data) {
   echo "接收到信息".$data." \n";
    $server->send($fd, "swoole: {$data}");
});

$server->on('close', function ($server, $fd) {
   echo "connection close: {$fd}\n";
});

$server->start();

tcpClient.php

<?php
$client = new Swoole\Client(SWOOLE_SOCK_TCP);

if (!$client->connect('127.0.0.1', 9503, -1)) {
    exit("connect failed. Error: {$client->errCode}\n");
}

//每隔2000ms触发一次
swoole_timer_tick(2000, function ($timer_id) use ($client) {
   echo "string\n";
   $client->send(1);
   $client->recv();
});

// $client->send("hello world1\n");
// echo $client->recv();

// $client->send("hello world2\n");
// echo $client->recv();

// $client->send("hello world3\n");
// echo $client->recv();

// $client->send("hello world4\n");
// echo $client->recv();

// $client->close();
<think>我们正在讨论Yii2-swoole中监控连接池健康状态的方法。根据之前提供的引用,我们知道tsingsun/yii2-swoole扩展是Yii2中管理MySQL连接池的解决方案。现在用户特别询问如何监控连接池的健康状态。 在Yii2-swoole中,连接池的健康监控主要通过以下几种方式实现: 1. 内置状态监控接口:扩展提供了HTTP端点来暴露连接池状态。 2. 日志监控:通过配置日志记录连接池的关键事件。 3. 自定义监控:通过事件监听器实现自定义监控逻辑。 4. 外部工具集成:如Prometheus等监控系统。 下面详细说明每种方法: ### 1. 内置状态监控接口 Yii2-swoole扩展内置了一个HTTP状态检查路由,可以直接获取连接池的实时状态。 **启用方法**(在配置文件中): ```php 'swooleServer' => [ 'enableStatisticRouter' => true, // 默认开启 'statisticRouter' => [ 'path' => '/status-pool', // 自定义路径 ], ], ``` **访问示例**: ```bash curl http://localhost:9501/status-pool ``` **返回JSON数据结构**: ```json { "db_master": { // 连接池名称(主库) "total": 20, // 总连接数 "idle": 15, // 空闲连接数 "busy": 5, // 繁忙连接数 "waiting": 0 // 等待获取连接的请求数 }, "redis_cache": { // 其他连接池(如Redis) "total": 10, "idle": 8, "busy": 2, "waiting": 0 } } ``` > 注意:该接口会显示所有已配置的连接池(包括数据库和Redis)的状态[^1]。 ### 2. 日志监控 通过配置Yii的日志组件,记录连接池的关键事件: ```php 'components' => [ 'log' => [ 'targets' => [ [ 'class' => 'yii\log\FileTarget', 'levels' => ['info', 'warning', 'error'], 'categories' => ['tsingsun\swoole\db\*'], // 监听数据库连接池事件 ], ], ], ], ``` **关键日志事件**: - `Connection pool created`:连接池创建 - `Get connection from pool`:从池中获取连接 - `Release connection to pool`:连接归还到池 - `Connection pool is full`:连接池已满(需告警) - `Create new connection failed`:创建新连接失败(严重错误) **日志示例**: ``` 2024-01-01 12:00:00 [INFO] [tsingsun\swoole\db\Connection] Connection pool created (min:10, max:100) 2024-01-01 12:00:05 [WARNING] [tsingsun\swoole\db\Connection] Connection pool is full! Waiting count: 15 ``` ### 3. 自定义监控(通过事件监听) 扩展提供了连接池事件,可自定义监控逻辑: ```php // 在配置文件中添加事件监听 'components' => [ 'db' => [ // ... 其他配置 ... 'on afterPoolCreate' => function($event) { // 连接池创建完成后触发 Yii::info("Pool initialized: ".json_encode($event->pool->getStats())); }, 'on afterGetConnection' => function($event) { // 每次获取连接时触发 Yii::info(sprintf( "Get connection: %s, waiting: %d", $event->isNew ? "new" : "reuse", $event->pool->getWaitingCount() )); } ], ], ``` **可用事件列表**: | 事件名称 | 触发时机 | |----------------------|----------------------------------| | `afterPoolCreate` | 连接池初始化完成后 | | `beforeGetConnection`| 尝试获取连接前 | | `afterGetConnection` | 成功获取连接后 | | `afterReleaseConnection`| 连接归还到池后 | ### 4. 集成Prometheus监控 对于生产环境,推荐使用Prometheus进行指标采集: **步骤**: 1. 安装Prometheus客户端库: ```bash composer require endclothing/prometheus_client_php ``` 2. 创建自定义指标收集器: ```php use Prometheus\CollectorRegistry; use Prometheus\Storage\APC; class PoolMetrics { public static function collect() { $registry = new CollectorRegistry(new APC()); $gauge = $registry->getOrRegisterGauge( 'yii2_swoole', 'db_pool_connections', 'Database connection pool status', ['pool', 'state'] ); foreach (Yii::$app->db->getPoolStats() as $poolName => $stats) { $gauge->set($stats['idle'], [$poolName, 'idle']); $gauge->set($stats['busy'], [$poolName, 'busy']); $gauge->set($stats['waiting'], [$poolName, 'waiting']); } } } ``` 3. 在Swoole Worker中定时收集(每5秒): ```php $http = new Swoole\Http\Server("0.0.0.0", 9501); $http->on('workerStart', function() { Swoole\Timer::tick(5000, function() { PoolMetrics::collect(); }); }); ``` 4. 配置Prometheus抓取: ```yaml scrape_configs: - job_name: 'yii2_swoole' static_configs: - targets: ['yii-app:9501'] # 暴露metrics端口 ``` ### 健康状态判断标准 根据监控数据,可定义以下健康指标: 1. **连接泄漏检测**: `busy_connections / total_connections > 90% 持续5分钟` → 可能连接未归还 2. **池容量不足**: `waiting_count > 0 持续10秒` → 需要扩大poolMaxSize 3. **连接创建失败率**: `create_fail_count / total_get > 1%` → 检查数据库可用性或网络 4. **心跳失败率**: `heartbeat_fail_count > 0` → 数据库连接异常断开 > 💡 **生产建议**:设置告警规则,当空闲连接数低于`poolMinSize`的20%时触发扩容[^1]。 §§相关问题§§ 1. 如何在Yii2-swoole中实现连接池的自动扩容? 2. 连接池监控数据如何集成到Grafana仪表盘? 3. 如何诊断Yii2-swoole中的数据库连接泄漏问题? </think> ### Yii2-swoole 连接池健康监控方法 在 Yii2-swoole 中监控连接池健康状态,主要有以下 4 种核心方法: #### 1. 内置状态监控接口 通过扩展自带的路由获取实时连接池状态: ```php // config/web.php 'swooleServer' => [ 'enableStatisticRouter' => true, // 启用状态路由 'statisticRouter' => [ 'path' => '/pool-status', // 自定义监控路径 ] ] ``` 访问监控端点: ```bash curl http://localhost:9501/pool-status ``` 返回数据结构: ```json { "db_master": { "total": 50, // 总连接数 "idle": 32, // 空闲连接数 "busy": 18, // 使用中连接数 "waiting": 3, // 等待连接的请求数 "heartbeat": "OK" // 心跳检测状态 } } ``` > 此接口可实时反映连接池负载和健康状态[^1]。 #### 2. 日志监控 配置专用日志通道记录关键事件: ```php 'components' => [ 'log' => [ 'targets' => [ [ 'class' => 'yii\log\FileTarget', 'categories' => ['tsingsun\swoole\db\*'], 'logFile' => '@runtime/logs/db-pool.log', 'levels' => ['info', 'warning', 'error'] ] ] ] ] ``` 关键监控日志: ``` [2023-08-15 10:23:45] [INFO] Connection pool created (min:10, max:100) [2023-08-15 10:25:31] [WARNING] Pool wait timeout (0.6s > 0.5s) [2023-08-15 10:30:22] [ERROR] Heartbeat failed on connection #47 ``` #### 3. Prometheus 指标集成 通过 Prometheus 实现生产级监控: ```php // 注册自定义指标 Yii::$container->set('prometheus', function() { $registry = new CollectorRegistry(new APC()); $gauge = $registry->registerGauge( 'db_pool', 'Database connection pool metrics', ['state'] ); return $registry; }); // 定时更新指标 Swoole\Timer::tick(5000, function() { $stats = Yii::$app->db->getPool()->getStats(); Yii::$app->prometheus->getGauge('db_pool') ->set($stats['idle'], ['idle']) ->set($stats['busy'], ['busy']); }); ``` 导出指标端点: ```bash curl http://localhost:9501/metrics ``` ``` # HELP db_pool Database connection pool metrics # TYPE db_pool gauge db_pool{state="idle"} 27 db_pool{state="busy"} 23 ``` #### 4. 健康告警规则 基于监控数据设置告警阈值: | 监控指标 | 警告阈值 | 严重阈值 | 处理建议 | |----------------------|------------------|------------------|---------------------------| | 空闲连接比例 | < 20% | < 10% | 扩大 `poolMaxSize` | | 等待请求数 | > 5 | > 15 | 优化查询或扩容 | | 心跳失败率 | > 1% | > 5% | 检查数据库网络/配置 | | 获取连接平均耗时 | > 100ms | > 500ms | 优化连接池参数 | #### 健康检测配置示例 ```php 'db' => [ 'class' => 'tsingsun\swoole\db\Connection', 'enablePool' => true, 'poolHeartbeat' => 30, // 每30秒心跳检测 'poolCheckStatement' => 'SELECT 1', // 健康检查SQL 'poolMaxWaitTime' => 0.3, // 获取连接超时(秒) 'on afterPoolCreate' => function($event) { // 连接池创建时触发 Yii::info("Pool initialized: ".json_encode($event->pool->getStats())); } ] ``` > 💡 **最佳实践**:生产环境建议组合使用 Prometheus + Grafana 实现可视化监控仪表盘,配合 Alertmanager 设置阈值告警[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

汀风说后端

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值