定时器
我们工作中,定时器经常使用的是contab,但是这个只支持秒级别的,所以我们可以通过swoole的毫秒级别的定时器。
下例中:
- 我们可以通过tick来设置定时器,并且还可以传入参数
- 使用clear来清除定时器,被清除的定时器就不会执行了
- 可以使用after来设置多少秒后执行
- 可以用info方法,获取定时器的信息
- 可以用clearAll方法来清除所有定时器
use Swoole\Coroutine;
use Swoole\Timer;
Coroutine\run(function () {
// 创建2秒定时器
Timer::tick(2000, function (int $timerId, $param1, $param2) {
echo "定时器,定时器ID是:{$timerId},在2000ms后执行;参数1是:{$param1},参数2是:{$param2}", PHP_EOL;
Timer::clear($timerId);
// 2秒定时器里又创建一个4秒的定时器
Timer::tick(4000, function ($timerId) {
echo "定时器里的定时器,定时器ID是:{$timerId},在4000ms后执行", PHP_EOL;
Timer::clear($timerId);
});
}, "A", 'B'); // A,B是参数,传递给$param1、$param2
// 如果只想执行一次,可以用after
Timer::after(3000, function () {
echo "通过after触发的定时器,在3000ms后执行", PHP_EOL;
});
foreach (Timer::list() as $timerId) {
echo "这里是循环", PHP_EOL;
print_r(Timer::info($timerId));
}
// 如果清除所有的定时器,那么所有定时器都不会执行,因为都被清除了
// Timer::clearAll();
});
高性能内存表
内存表,可以理解成mysql的数据表
use Swoole\Table;
// 实现一个类似redis key
$table = new Table(3072);
// 内存表增加列
$table->column('id', Table::TYPE_INT);
$table->column('name', Table::TYPE_STRING, 60);
$table->column('price', Table::TYPE_FLOAT);
// 创建内存表。定义好表的结构后,执行 create 向操作系统申请内存,创建表
$table->create();
$server = new Swoole\Server('127.0.0.1', 9502);
$server->set([
// 多个进程的负载均衡策略,例如轮询、ip hash、worker进程空闲状态来
'dispatch_mode' => 1,
]);
$server->table = $table;
$server->on('receive', function ($server, $fd, $reactorId, $data) {
$cmd = explode(' ', trim($data));
if ($cmd[0] == 'get') {
if (count($cmd) < 2) {
$cmd[1] = $fd;
}
$get_fd = intval($cmd[1]);
// 获取一行数据
$info = $server->table->get($get_fd);
$server->send($fd, var_export($info, true) . PHP_EOL);
} elseif ($cmd[0] == 'set') {
// 设置行的数据。Table 使用 key-value 的方式来访问数据
// 返回成功或者失败
$ret = $server->table->set($fd, [
'price' => rand(1, 100),
'id' => $fd,
'name' => $cmd[1],
]);
if ($ret) {
$server->send($fd, "OK" . PHP_EOL);
} else {
$server->send($fd, "ERROR" . PHP_EOL);
}
} else {
$server->send($fd, "COMMAND ERROR" . PHP_EOL);
}
});
$server->start();
// 然后在telnet里输入:set 1和get 1试下
优点是:
- 读写速度很快,比如redis都还快;