PHP使用MySQL实现消息队列

消息队列常用在流量削峰(秒杀场景),异步通信等地方。

大体的结构如下:

  类似于消费者和生产者的关系,首先生产者在消息队列未满的时候,才将生产的产品放进消息队列中;消费者在消息队列不为空的时候,才从消息队列中取出产品进行消费。出队的那个步骤常用的方法是一直轮询和定时操作。

这里举一个外卖送餐的案例:

  有个生意很好的饭店,好到什么程度呢?一分钟有500人下单,这样的话,店家掌柜肯定处理不过来,于是,就先暂时不通知用户是够接单,先把所有的订单先存着,只告诉他们正在处理中,但是呢,还有一个问题,就是有一些是其他饭店专门来搞事的(眼红了),所以就要查看订单是否合法。

  上面的情景可以这样实现:用户下单之后,后台会创建一个随机的order_id对应该订单;并且该订单的初始状态(status)为待处理(0);当商家查看该订单情况时,将status改为1,表示正在处理;当商家确认这个订单可以接受时,就将该订单的status改为2,表示成功接单。

  首先在数据库中创建一个order_list订单表,表结构如下:

mysql> desc order_list;
+----------+------------+------+-----+----------+-------+
| Field    | Type       | Null | Key | Default  | Extra |
+----------+------------+------+-----+----------+-------+
| order_id | int(11)    | NO   | PRI | NULL     |       |
| mobile   | int(8)     | NO   |     | 88888888 |       |
| status   | tinyint(1) | YES  |     | 0        |       |
+----------+------------+------+-----+----------+-------+
3 rows in set (0.05 sec)

  有两个PHP程序,分别是producer.php(用户、生产者);     consumer.php(商家、消费者)  

  一旦有用户下单,就往order_list中添加一条数据,这里方便测试,于是执行下面的PHP程序,表示用户方(producer.php),每隔2秒下一次单;

<?php
	$pdo=new PDO("mysql:host=localhost;dbname=test","root","root");
	$stmt=$pdo->prepare("insert into order_list (order_id,mobile,status) values (?,?,?)");
	while(1){
		$order_id=rand(10000,99999);
		$mobile=rand(11111111,99999999);
		$stmt->execute(array($order_id,$mobile,0));
		echo date("Y-m-d H:i:s",time())."添加了一条订单,订单号为{$order_id},手机号为{$mobile}\n";
		sleep(2);
	}
 ?>

  用户提交订单后,剩下的事情就交给商家了,商家(consumer.php)生意太忙了,每4秒才能处理一个订单:

<?php
	$pdo=new PDO("mysql:host=localhost;dbname=test","root","root");
	$stmt=$pdo->prepare("update order_list set status=? where status=? limit 1");
	$stmt_select=$pdo->prepare("select order_id from order_list where status=1");//正在处理的订单号
	while(1){
		$init=0;//初始status
		$lock=1;//标记为正在处理
		$success=2;//成功接单
		//为了保证数据的一致性,处理订单之前,要先锁定一个订单,将其status由0改为1,然后才可处理
		//处理完毕后,然后再将status从1改为2

		$stmt->execute(array($lock,$init));//锁定要处理的订单
		$stmt_select->execute();
		$result=$stmt_select->fetch(PDO::FETCH_ASSOC);//查询正在处理的订单号
		$order_id=$result[‘order_id‘];
		echo date("Y-m-d H:i:s")."准备处理订单,订单号为{$order_id}\n";
		sleep(3);//处理3秒
		$stmt->execute(array($success,$lock));
		echo date("Y-m-d H:i:s")."订单处理完成,订单号为{$order_id}\n";
		sleep(1);//休息1秒
	}
 ?>

  这样就使用MySQL实现了一个简单的消息队列,可以看一下如何使用Redis实现消息队列,与这个方法类似。

原文地址:https://www.cnblogs.com/-beyond/p/8214355.html

时间: 2024-10-26 20:13:54

PHP使用MySQL实现消息队列的相关文章

mysql实现消息队列

mysql之消息队列 消息队列:在消息的传输过程中保存消息的容器. 消息队列管理器在将消息从它的源中继到它的目标时充当中间人.队列的主要目的是提供路由并保证消息的传递:如果发送消息时接收者不可用,消息队列会保留消息,直到可以成功地传递它. 如图所示: 在不使用消息队列的情况下,用户的请求数据直接写入数据库,再高并发的情况下,会对数据库造成巨的压力,同时也使得响应延迟加剧.在使用消息队列后,用户请求的数据发送给消息队列后立即返回,再由消息队列的消费者进程(通常情况下,该进程独立部署在专门的服务器集

php mysql 实现消息队列

最近遇到一个批量发送短信的需求,短信接口是第三方提供的.刚开始想到,获取到手机号之后,循环调用接口发送不就可以了吗? 但很快发现问题:当短信数量很大时,不仅耗时,而且成功率很低. 于是想到,用PHP和MySQL实现一个消息队列,一条一条的发送短信.下面介绍具体的实现方法: 首先,建立一个数据表sms,包含以下字段: id, phone, //手机号 content //短信内容 将需要发送的短信和手机号存入sms表中. 接下来,需要用PHP实现一个定时器,定时读取一条记录,并发送短信: <?ph

PHP和MySQL实现消息队列

最近遇到一个批量发送短信的需求,短信接口是第三方提供的.刚开始想到,获取到手机号之后,循环调用接口发送不就可以了吗? 但很快发现问题:当短信数量很大时,不仅耗时,而且成功率很低. 于是想到,用PHP和MySQL实现一个消息队列,一条一条的发送短信.下面介绍具体的实现方法: 首先,建立一个数据表sms,包含以下字段: id, phone, //手机号 content //短信内容 将需要发送的短信和手机号存入sms表中. 接下来,需要用PHP实现一个定时器,定时读取一条记录,并发送短信: <?ph

PHP(Mysql/Redis)消息队列的介绍及应用场景案例--转载

郑重提示:本博客转载自好友博客,个人觉得写的很牛逼所以未经同意强行转载,原博客连接 http://www.cnblogs.com/wt645631686/p/8243438.html 欢迎访问 在进行网站设计的时候,有时候会遇到给用户大量发送短信,或者订单系统有大量的日志需要记录,还有做秒杀设计的时候,服务器无法承受这种瞬间的压力,无法正常处理,咱们怎么才能保证系统正常有效的运行呢?这时候我们就要引用消息队列来实现这类的需求,这时候就需要一个中间的系统进行分流和解压.消息队列就是一个中间件,需要

mysql之消息队列

消息队列:在消息的传输过程中保存消息的容器. 消息队列管理器在将消息从它的源中继到它的目标时充当中间人.队列的主要目的是提供路由并保证消息的传递:如果发送消息时接收者不可用,消息队列会保留消息,直到可以成功地传递它. 如图所示: 在不使用消息队列的情况下,用户的请求数据直接写入数据库,再高并发的情况下,会对数据库造成巨的压力,同时也使得响应延迟加剧.在使用消息队列后,用户请求的数据发送给消息队列后立即返回,再由消息队列的消费者进程(通常情况下,该进程独立部署在专门的服务器集群上)从消息队列中获取

springboot2.0+redis实现消息队列+redis做缓存+mysql

本博客仅供参考,本人实现没有问题. 1.环境 先安装redis.mysql 2.springboot2.0的项目搭建(请自行完成),本人是maven项目,因此只需配置,获取相应的jar包,配置贴出. <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifact

第二十三天:共享内存.消息队列及mysql数据库使用

共享内存和消息队列也是进程间的通信方式. 共享内存,(和信号量的操作类似) #include<sys/shm.h> 1.int shmget(key_t key,size_t size,int shmflg); 作用:新建一块内存或者返回已建好的内存 参数:key,用于表示开辟一段内存,各进程通过这个标志访问同一块内存 size,内存的大小 shmflg,和文件操作完全相同权限表示,按位或IPC_CREATE表示创建一块内存,如果key表示的内存已经建立,即使加了IPC_CREATE也不会新建

对分布式事务、消息队列的重新认识

本质上问题可以抽象为:当一个表数据更新后,怎么保证另一个表的数据也必须要更新成功.若两张表在同一个数据库实例中,则使用本地事务就好了.否则可以采用分布式事务,或者消息队列. 前阵子从支付宝转账1万块钱到余额宝,这是日常生活的一件普通小事,但作为互联网研发人员的职业病,我就思考支付宝扣除1万之后,如果系统挂掉怎么办,这时余额宝账户并没有增加1万,数据就会出现不一致状况了. 上述场景在各个类型的系统中都能找到相似影子,比如在电商系统中,当有用户下单后,除了在订单表插入一条记录外,对应商品表的这个商品

转:为什么会需要消息队列(MQ)?

为什么会需要消息队列(MQ)? ########################################################################################## 主要原因是由于在高并发环境下,由于来不及同步处理,请求往往会发生堵塞,比如说,大量的insert,update之类的请求同时到达MySQL,直接导致无数的行锁表锁,甚至最后请求会堆积过多,从而触发too many connections错误.通过使用消息队列,我们可以异步处理请求,从而