php 生产者-消费者实现

一、项目背景

        mes报工需求,原项目接口接收产线上位抛来的数据,处理无误后存储在本地,最后抛给工厂接口。

        但是有时候工厂数据响应太慢,也导致mes响应给上位变慢,拖慢了mes系统。

        现要求,将原接口中抛给工厂的功能分离出来。即,上位抛来数据处理无误并存储在本地后,直接返回给上位,而将数据抛给工厂的部分实现异步处理。

二、思路

        首先想到的是多线程,但是php是不支持多线程的,想要实现多线程需要下载各种插件,十分麻烦。最终我们采用了生产者-消费者的模式来实现。

三、生产者-消费者的简单介绍

        通俗讲,A是发糖的,B是吃糖的,但是B只能一个一个吃,如果A发糖的速度高于B吃糖的速度,那么就会出现A发了糖,B还没有吃的情况。那怎么办呢,A找来一个盒子,把要发给B的糖放在里面,B吃完了嘴里的糖就自行从盒子里取,双方各不耽误。

        这样就相当于一个简单的生产者-消费者模型。A是生产者,B是消费者,盒子是内存空间。A不需要理会B的状态,他会把数据放在特定的内存中;而B同样不和A有牵扯,在当前数据处理完后,只管从内存中拿数据。

四、实现

1)安装redis服务(也可以选择其他的,我用的是redis,所以只介绍redis)

        Releases · microsoftarchive/redis

         注意 :安装过程是全英文的,一定要选择将redis添加到环境变量!另外,记住自己的端口!默认是6379。

2)在php安装路径的ext文件夹中添加拓展

        下载链接:https://downloads.php.net/~windows/pecl/releases/redis/5.3.3/php_redis-5.3.3-7.3-ts-vc15-x64.zip

3)编辑php.ini

        加入extension=redis,如果前面有;删掉即可。

4)生产者实现

        lPush()从队列左边推入消息,rPush从队列右边推入消息。

	// 连接 Redis 服务器
	$redis = new Redis();
	$redis->connect('127.0.0.1', 6379);

	// 消息队列名
	$queue = 'message';

	// 生成消息
	$message = json_encode($jsonData);
	
	// 将消息推送到 Redis 队列中
	$redis->lPush($queue, $message);

5)消费者实现

        rPop()从队列右边取出消息,与lPush()结合使用弹出最早的消息,lPop()反之。

$redis = new Redis();

// 连接到 Redis 服务器
$redis->connect('127.0.0.1', 6379);

while (true) {
    // 从队列 'message' 弹出消息
    $message = $redis->rPop('message');

    // 如果有消息,处理消息
    if ($message) {
        print_r("上传中...");
        // 初始化 cURL 会话
        $ch = curl_init($url);

        // 设置 cURL 选项
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $message);

        // 执行 cURL 会话
        $response = curl_exec($ch);

        // 检查是否有错误发生
        if (curl_errno($ch)) {
            log_write('Error:' . curl_error($ch));
        }

        $message = json_decode($message);
        // 关闭 cURL 会话
        curl_close($ch);
        $LogIppsot = $_SERVER['REMOTE_ADDR'];
        $PostStrpost = json_encode($message, JSON_UNESCAPED_UNICODE);
        $LogContentpost = $response;
        $LogTimepost = date("Y-m-d H:i:s", time());
        $glmesconn_errpost = sql_mes_conn();
        $logsqlstrpost = "insert into Log_Plc_Api(LogFrom,LogIp,PostStr,LogContent,LogTime) values ('AddEquipInfo','$LogIppsot','$PostStrpost','$LogContentpost','$LogTimepost')";
        sqlsrv_query($glmesconn_errpost, $logsqlstrpost);
        sqlsrv_close($glmesconn_errpost);
    } else {
        // 如果队列为空,稍等再试
        print_r("waiting...\n");
        sleep(1);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值