首页
下载
文档
社区
视频
捐赠
源代码
赞助商
AOT 编译器
AI 助理
商业产品
PHP AOT 原生编译器
Swoole-Compiler 代码加密器
CRMEB 新零售社交电商系统
登录
注册
全部
提问
分享
讨论
建议
公告
开发框架
CodeGalaxy
发表新帖
跨worker 检查客户端fd 是否存在
我在TCP server 中,onWorkerStart 位置有一个定时器,统一管理所有的FD状态,但在做在线状态检查时返回false ,不知道什么原因。 ```php function my_onWorkerStart(\swoole_server $serv, $worker_id) { global $argv; $jobType = ($worker_id >= $serv->setting['worker_num']) ? 'task' : 'event'; PHP_OS === "Linux" && cli_set_process_title("php {$argv[0]} {$jobType} worker{$worker_id}"); if ($worker_id === 0) { \Swoole\Timer::tick(1000, function () use ($serv) { foreach (PRedis::instance('trans_process')->smembers("trans_running") as $trans_key) { $info = PRedis::instance('trans_process')->hgetall("trans_{$trans_key}"); if ($info) { // 超时了(5s) if (microtime(true) - $info['begin_at_ms'] > 10) { // 检查是否有链接活跃 $fds = PRedis::instance('trans_process')->smembers("trans_{$trans_key}_fd"); $inActiveFds = array_filter($fds, function ($fd) use ($serv) { return $serv->exist((int)$fd);// 这里期望对应的未断开的链接返回True }); if (!$inActiveFds) { // 回退异常事务 $request_data = [ 'cmd' => 65535, 'request_key' => $trans_key, 'param' => [] ]; $serv->taskwait($request_data, 2, (int)$info['task_worker_id']); // 删除记录 PRedis::instance('trans_process')->srem("trans_running", $trans_key); PRedis::instance('trans_process')->delete("trans_{$trans_key}"); PRedis::instance('trans_process')->delete("trans_{$trans_key}_fd"); } } } } }); } } ``` PHP 7.4.1 swoole 4.4.16 Darwin bogon 19.4.0
发布于6年前 · 8 次浏览 · 来自
提问
zxyfaxcn
我在TCP server 中,onWorkerStart 位置有一个定时器,统一管理所有的FD状态,但在做在线状态检查时返回false ,不知道什么原因。 ```php function my_onWorkerStart(\swoole_server $serv, $worker_id) { global $argv; $jobType = ($worker_id >= $serv->setting['worker_num']) ? 'task' : 'event'; PHP_OS === "Linux" && cli_set_process_title("php {$argv[0]} {$jobType} worker{$worker_id}"); if ($worker_id === 0) { \Swoole\Timer::tick(1000, function () use ($serv) { foreach (PRedis::instance('trans_process')->smembers("trans_running") as $trans_key) { $info = PRedis::instance('trans_process')->hgetall("trans_{$trans_key}"); if ($info) { // 超时了(5s) if (microtime(true) - $info['begin_at_ms'] > 10) { // 检查是否有链接活跃 $fds = PRedis::instance('trans_process')->smembers("trans_{$trans_key}_fd"); $inActiveFds = array_filter($fds, function ($fd) use ($serv) { return $serv->exist((int)$fd);// 这里期望对应的未断开的链接返回True }); if (!$inActiveFds) { // 回退异常事务 $request_data = [ 'cmd' => 65535, 'request_key' => $trans_key, 'param' => [] ]; $serv->taskwait($request_data, 2, (int)$info['task_worker_id']); // 删除记录 PRedis::instance('trans_process')->srem("trans_running", $trans_key); PRedis::instance('trans_process')->delete("trans_{$trans_key}"); PRedis::instance('trans_process')->delete("trans_{$trans_key}_fd"); } } } } }); } } ``` PHP 7.4.1 swoole 4.4.16 Darwin bogon 19.4.0
赞
0
收藏
提问
分享
讨论
建议
公告
开发框架
CodeGalaxy
登录
后参与评论
评论
2020-04-09
郭新华
BASE模式还是Process模式,确定exists的时候 fd没有断开吗?
赞
0
回复
2020-04-09
zxyfaxcn
回复
郭新华
SWOOLE_PROCESS 模式,确定没有断开,因为我写了一个阻塞在那里来专门测试这个情况的。
赞
0
回复
2020-04-09
zxyfaxcn
回复
郭新华
``` $serv = new \swoole_server('0.0.0.0', 9504, SWOOLE_PROCESS, SWOOLE_SOCK_TCP); $serv->set([ 'debug_mode' => $_SERVER['ENV'] === 'dev', 'daemonize' => $_SERVER['ENV'] !== 'dev', 'worker_num' => swoole_cpu_num() * 2, 'max_request' => 50000, 'max_conn' => 10240, 'pid_file' => __DIR__ . '/data_server.pid', 'log_file' => __DIR__ . '/data_server.log', 'backlog' => 1024, 'dispatch_mode' => 3, 'task_worker_num' => 4, 'reload_async' => true, 'max_wait_time' => 10, // 默认30s Worker 进程收到停止服务通知后最大等待时间 'heartbeat_idle_time' => 30, 'heartbeat_check_interval' => 5, //检查包设置 'open_length_check' => true, 'package_body_offset' => 4, 'package_length_offset' => 0, 'package_max_length' => 65535, 'package_length_type' => 'N', 'tcp_defer_accept' => 10, 'enable_reuse_port' => true, 'tcp_fastopen' => true, ]); ``` 确定没有断开,因为我写了一个阻塞在那里专门测试这个情况的。
赞
0
回复
2020-04-09
zxyfaxcn
回复
郭新华
自己的代码问题,我在阻塞的请求中没有先把fd 放到池子里,然后去判断了一个还不存在的fd,所以。。。。谢谢啦。
赞
1
回复