首页 > 作文

通过 Swoole\Table 实现 Swoole 多进程数据共享

更新时间:2023-04-08 13:09:46 阅读: 评论:0

第三方存储媒介

前面我们介绍了基于 swoole 的processprocess\pool模块在 php 中实现多进程管理,但是多进程模式下进程间是相互隔离的,无法共享数据和变量,即便是通过global定义的全局或超全局变量,也只是在所属进程中有效,如果要在 swoole 实现的多进程间共享数据,需要借助第三方存储媒介实现:

数据库:mysql、mongodb缓存:redis、memcached磁盘文件

但是这也会引入新的问题,多进程同时操作一条记录或一个文件存在并发访问问题,以数据库操作为例,两个进程可能会同时读取一条数据,或者一个进程对某条记录进行更新处理时,另一个进程也来读取这条记录并进行操作,会导致最终结果数据与预期不一致的情况,这个时候,我们就需要引入锁的概念,当一个进程(比如进程a)对某个记录进行写操作时,对该记录加锁,这样其它进程就无法操作该条记录, 直到进程 a 事务提交再释放这个锁,让其他进程可以进行操作。

内存共享

php 相关扩展

对于单机操作来说,除了这些第三方存储媒介之外,还可以通过共享内存的方式实现进程间数据读写操作,有多个 php 扩展可以支持共享内存数据操作:

maphore 扩展:可通过该扩展包提供的shm_get_varshm_put_var函数实现内存共享数据的读写操作;shmop 扩展:可通过该扩展包提供的shmop_readshmop_write函数实现内存共享数据的读写操作;apcu(apc ur cache)扩展:可通过该扩展包提供的apc_fetchapc_store实现内存共享数据的读写操作。

swoole table

但是上述扩展要么不支持锁,要么高并发时性能比较差,所以 swoole 自己实现了一个共享内存读写工具 ——swool成人高考复习资料e\table,该工具是一个基于共享内存和锁实现的高性能并发数据结构,可用于解决多进程/多线程数据共享和同步加锁问题:

性能强悍,单线程每秒可读写200万次;应用代码无需加锁,内置行锁自旋锁,所有操作均是多线程/多进程安全,用户层完全不需要考虑数据同步问题;支持多进程,可用于多进程之间共享数据;使用行锁,而不是全局锁,仅当 2 个进程在同一 cpu 时间,并发读取同一条数据才会进行发生抢锁。

swoole\table支持以 key-value 方式读写,使用起来非常简单:

<?php// 初始化一个容量为 1024 的 swoole table$table = new \swoole\table(1024);// 在 table 中新增 id 列$table->column('id', \swoole\table::type_int);// 在 table 中新增 name 列,长度为 50$table->column('name', \swoole\table::type_st2020年清明ring, 10);// 在 table 中新泽 score 列$table->column('score', \swoole\table::type_float);// 创建这个 swoole table$table->create();// 设置 key-value 值$table->t('student-1', ['id' => 1, 'name' => '学小君', 'score' =>女儿不认真学习被妈妈拖进大海; 80]);$table->t('student-2', ['id' => 2, 'name' => '学院君', 'score' => 90]);// 如果指定 key 值存在则打印对应 value 值if ($table->exist('student-1')) {    echo "student-" . $table->get('student-1', 'id') . ':' . $table->get('student-1', 'name').":".        $table->get('student-1', 'score') . "\n";}// 自增操作$table->incr('student-2', 'score', 5);// 自减操作$table->decr('student-2', 'score', 5);// 表中总记录数$count = $table->count();// 删除指定表记录$table->del('student-1');

  

此外swoole\table类还实现了迭代器接口,支持通过foreach进行遍历。

在 laravel 中使用 swoole\table

如果要在 laravel 中集成 swoole 使用swoole\t5iable,以laravels 扩展包为例,首先要在配置文件config/laravels.php中定义swoole_tables配置项:

'swoole_tables'            => [    'ws' => [ // 表名,会加上 table 后缀,比如这里是 wstable        'size'   => 102400, //  表容量        'column' => [ // 表字段,字段名为 value            ['name' => 'value', 'type' => \swoole\table::type_int, 'size' => 8],        ],    ],    ... // 还可以定义其它表],

  

然后我们可以在代码中通过swoole实例上的wstable属性访问 swooletable:地域分布

class websocketrvice implements websockethandlerinterface{    ...    // 连接建立时触发    public function onopen(rver $rver, request $request)    {        // 在触发 websocket 连接建立事件之前,laravel 应用初始化的生命周期已经结束,你可以在这里获取 laravel 请求和会话数据        // 调用 push 方法向客户端推送数据,fd 是客户端连接标识字段        log::info('websocket 连接建立:' . $request->fd);        app('swoole')->wstable->t('fd:' . $request->fd, ['value' => $request->fd]);        $rver->push($request->fd, 'welcome to websocket rver built on laravels');    }    // 收到消息时触发    public function onmessage(rver $rver, frame $frame)    {        foreach (app('swoole')->wstable as $key => $row) {            if (strpos($key, 'fd:') === 0 && $rver->exist($row['value'])) {                log::info('receive message from client: ' . $row['value']);                // 调用 push 方法向客户端推送数据                $rver->push($frame->fd, 'this is a message nt from websocket rver at ' . date('y-m-d h:i:s'));            }        }    }        ...}

  

然后我们参考在 laravel 中集成 swoole 实现 websocket 服务器这篇教程从客户端向 websocket 服务器发起请求,即可在最新日志文件中看到相应的日志信息:

[2020-04-24 19:39:03] local.info: websocket 连接建立:1  [2020-04-24 19:39:07] local.info: receive message from client: 1

  



本文发布于:2023-04-08 13:09:44,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/00f1547867c5e9a64d7994069e3e7223.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:通过 Swoole\Table 实现 Swoole 多进程数据共享.doc

本文 PDF 下载地址:通过 Swoole\Table 实现 Swoole 多进程数据共享.pdf

标签:进程   操作   数据   内存
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图