如题,我在UDP服务的onWorkerStart回调中启动了一个定时器,log显示onWorkerStart也只调用了一次,但是status里面发现ntp_worker的内存占用与timer数量在不断增加。
百思不得其解,只好来提问,请大神帮忙看看。
以下是debug启动,可以看见Timer added只发生了一次。
[root@crazy crazy-ntp]# php w.php start
Workerman[w.php] start in DEBUG mode
-------------------------------------------- WORKERMAN ---------------------------------------------
Workerman version:4.1.8 PHP version:8.1.16 Event-Loop:\Workerman\Events\Select
--------------------------------------------- WORKERS ----------------------------------------------
proto user worker listen processes status
tcp root globalDataServer frame://127.0.0.1:2207 1 [OK]
udp root NTP Service udp://127.0.0.1:123 1 [OK]
----------------------------------------------------------------------------------------------------
Press Ctrl+C to stop. Start success.
Worker started!
Timer added!
query:, is_limit:0
Timer act, clear list.
query:0, is_limit:0
Timer act, clear list.
query:0, is_limit:0
Timer act, clear list.
^CWorkerman[w.php] stopping ...
Workerman[w.php] has been stopped
然后start -d
,观察内存与timer数量:
[root@crazy crazy-ntp]# php w.php start -d
Workerman[w.php] start in DAEMON mode
-------------------------------------------- WORKERMAN ---------------------------------------------
Workerman version:4.1.8 PHP version:8.1.16 Event-Loop:\Workerman\Events\Select
--------------------------------------------- WORKERS ----------------------------------------------
proto user worker listen processes status
tcp root globalDataServer frame://127.0.0.1:2207 1 [OK]
udp root NTP Service udp://127.0.0.1:123 1 [OK]
----------------------------------------------------------------------------------------------------
Input "php w.php stop" to stop. Start success.
[root@crazy crazy-ntp]# php w.php status
Workerman[w.php] status
----------------------------------------------GLOBAL STATUS----------------------------------------------------
Workerman version:4.1.8 PHP version:8.1.16
start time:2023-02-26 11:35:07 run 0 days 0 hours
load average: 0.65, 1.02, 1.02 event-loop:\Workerman\Events\Select
2 workers 2 processes
worker_name exit_status exit_count
globalDataServer 0 0
NTP Service 0 0
----------------------------------------------PROCESS STATUS---------------------------------------------------
pid memory listening worker_name connections send_fail timers total_request qps status
92247 1.06M frame://127.0.0.1:2207 globalDataServer 4 0 0 16 0 [idle]
92248 1.05M udp://127.0.0.1:123 NTP Service 0 0 5 0 0 [idle]
----------------------------------------------PROCESS STATUS---------------------------------------------------
Summary 2M - - 4 0 0 21 0 [Summary]
[root@crazy crazy-ntp]# php w.php status
Workerman[w.php] status
----------------------------------------------GLOBAL STATUS----------------------------------------------------
Workerman version:4.1.8 PHP version:8.1.16
start time:2023-02-26 11:35:07 run 0 days 0 hours
load average: 0.59, 1, 1.01 event-loop:\Workerman\Events\Select
2 workers 2 processes
worker_name exit_status exit_count
globalDataServer 0 0
NTP Service 0 0
----------------------------------------------PROCESS STATUS---------------------------------------------------
pid memory listening worker_name connections send_fail timers total_request qps status
92247 1.09M frame://127.0.0.1:2207 globalDataServer 13 0 0 52 0 [idle]
92248 1.14M udp://127.0.0.1:123 NTP Service 0 0 14 0 0 [idle]
----------------------------------------------PROCESS STATUS---------------------------------------------------
Summary 2M - - 13 0 0 66 0 [Summary]
可以发现内存占用与timers都在不停增加。
<?php
require_once __DIR__ . '/vendor/autoload.php';
require_once __DIR__ . '/NTPLite.php';
use Workerman\Worker;
use Workerman\Timer;
use Workerman\Connection\UdpConnection;
$GlobalData = new GlobalData\Server('127.0.0.1', 2207);
$ntp_worker = new Worker('udp://127.0.0.1:123');
$ntp_worker->name = 'NTP Service';
$ntp_worker->onWorkerStart = function () {
echo "Worker started!\n";
$time_interval = 1;
Timer::add(
$time_interval,
function () {
$global = new GlobalData\Client('127.0.0.1:2207');
echo "query:$global->query_now, is_limit:";
echo $global->is_limited ? 1 : 0;
echo "\nTimer act, clear list.\n";
$global->query_now = 0;
$global->is_limited = false;
}
);
echo "Timer added!\n";
};
$ntp_worker->onMessage = function (UdpConnection $connection, $data) {
$global = new GlobalData\Client('127.0.0.1:2207');
$global->query_now++;
if ($global->query_now > 2)
{
$global->is_limited = true;
$connection->close(0x00);
}
if (!$global->is_limited and $connection->getRemoteIp()) {
$NTP = new NTPLite();
if (!$NTP->readMessage($data)) {
$hex = '';
for ($i = 0; $i < strlen($data); $i++) {
$hex .= sprintf('%02x', ord($data[$i]));
}
echo "Bad request, aborted\n$hex\n";
} else {
//$NTP->dump();
//echo "\n", $NTP;
$NTP->leapIndicator = 0;
$NTP->mode = 4;
$NTP->stratum = 6;
$NTP->precision = -20;
$NTP->rootDelay = 0;
$NTP->rootDispersion = 0.0120;
$NTP->referenceIdentifier = ip2long('202.38.64.7');
$now = new DateTime(NULL);
$NTP->referenceTimestamp = NTPLite::convertDateTimeToSntp($now);
$NTP->originateTimestamp = $NTP->transmitTimestamp;
$NTP->receiveTimestamp = NTPLite::convertDateTimeToSntp($now);
$NTP->transmitTimestamp = NTPLite::convertDateTimeToSntp($now);
$message = $NTP->writeMessage();
unset($NTP);
$connection->close($message);
}
}
};
Worker::runAll();
同时想问一下GlobalData变量共享的连接怎么关闭?一段时间以后连接数超过了1000,看代码没有找到方法。
直接启动
Fedora 37, PHP 8.1.16, Workerman 4.1.8
GlobalData Client不支持关闭连接,GlobalData Client应该在全局初始化,例如onWorkerStart里初始化,其它地方复用它。
GlobalData Client内部会使用定时器,每创建一个GlobalData Client实例,就可能会创建一个定时器。
所以你复用GlobalData Client就好了。
明白了,谢谢老大及时回复。我马上去改
修改以后正常了。