PHP消息队列学习
在我们平常网站设计时,会遇到“给用户群发短信”,“商城订单系统大批量订单处理”,“商城秒杀活动”等需求,这些功能,都有一个共同的特点:就是在面对高迸发的同时,必须要保证系统处理数据的有效性。那么如何处理这些数据,“消息队列”就是很好的选择。
接下来我们主要了解以下知识:
1.队列是什么东西?它能做哪些事情?
2.队列的应用场景有哪些?
3.如何使用队列对业务进行解耦?
4.如何使用redis队列来缓解系统压力?
一、认识消息队列
1.1 消息队列概念
从本质上来说消息队列就是一个队列结构的中间件,就是说消息放入(即入队)这个中间件之后可以不马上处理,而等待另外一个程序进行处理读取(出队)这些消息数据,并且按照顺序逐次处理。也就是说你的遇到一个并发特别大而且耗时特别长,还不需要马上进程处理返回结果的功能时,可以使用消息队列解决此类问题。
1.2 核心结构
由一个业务系统进行入队,把消息逐次插入到消息队列中,插入成功之后直接返回成功结果,然后另一个消息处理系统,这个系统会把消息系统中的记录逐次读取出来并进行处理,完成出队流程。
1.3 应用场景
数据冗余:比如商城的订单系统,后续需要严格可靠的进行数据转换和记录,消息队列可以把这些订单数据持久化存储在队列中,如果队列中有订单数据,则后续处理程序进行获取,后续处理完之后将队列中与该条订单对应的元素删除,这样就能保证每条订单都能被有效处理,以下是一些消息队列常见的使用场景。
系统解耦:软件开发尽量做到“高内聚,低耦合”,使用消息队列之后,可以做到入队系统和出队系统相互分开,互不影响,假如入队系统出现故障崩溃,出队系统不受影响,依然能够正常运作。
流量削峰:例如商城秒杀和抢购,可以配合缓存来使用消息队列,能够有效顶住瞬间的高访问量,防止服务器因承受不住压力崩溃。
异步通信:消息发送之后,如果消息入队成功之后可以直接返回发送成功。
扩展性:商城订单队列,不仅可以处理订单,还可以给其他业务使用,比如下单成功之后,必然为其生成一条快递派送订单。
排序保证:有些场景需要按照产品的顺序进行处理,比如单进单出从而保证数据按照一定的顺序处理,可以使用消息队列。
1.4 常见队列的实现优缺点
队列介质:
1、数据库,比如mysql(可靠性高,容易实现,数据量大时速度慢)
2、缓存,例如redis(速度快,单个消息报包过大时效率低)
3、消息系统,例如rabbitMq(专业性强,可靠,学习成本高)
消息处理触发机制:
1、死循环方式读取:易实现,故障时无法及时恢复。(比较适合做秒杀,比较集中,运维集中维护)
2、定时任务:压力均分,有处理上限;可选择用户访问量低时段减小服务器压力;目前比较流行的处理触发机制。(唯一缺点是间隔和数据需要注意,不要等上一个任务还没有完成下一个任务又开始了)
3.守护进程:类似于php-fpm和php-cg,需要shell基础
二、解耦案例:队列处理“订单系统”和“配送系统”
对于订单流程,我们可以设计两个系统,即“订单系统”和“配送系统”。在网购中我们都知道,当我们下单之后,在我的订单中可以看到我的货物正在配送中,这时就要参与进来一个“配送系统”。如果在架构时把“订单系统”和“配送系统”设计在一起,就会出现一些问题。对于订单系统来说,因为系统压力较大,但是“配送系统”却没有必要即时做出反应;第二个,我们不希望在订单系统出现故障时,配送系统也无法运行,这个时候两个系统就会相互影响正常运转。所以我们要把两个系统的耦合度降到最低。这个可以用“对列表”来实现两者之间的沟通。
2.1 架构设计
1、首先订单系统接收到用户的订单,然后进行订单的处理。
2、然后会把这些订单信息写到对列表中,这个对列表是沟通订单系统和订单系统的关键。
3、由配送系统定时执行的一个程序来读取队列进行处理。
4、配送系统处理之后,会把已处理的记录进行标记处理
2.2 程序流程
三、流量消峰案例:Redis 的 list 类型实现秒杀/抢购活动
redis 基于内存,它的速度非常快,redis对数据库有一个非常好的补充作用,因为它是可持久化的,redis会周期性把数据写到硬盘中,因此它不需要担心断电问题,redis提供了5种不同的数据类型(字符串,双向表链,哈希,集合,有序集合)。
一般情况下,做秒杀案例,抢购,瞬间高并发,需要排队的案例中,redis是一个很好的选择。
3.1 redis数据类型中的list类型
redis 的list 是一个双向链表,可以从头部或者尾部追加数据。
* LPUSH/LPUSHX :将值插入到(/存在的)列表头部
* RPUSH/RPUSHX: 将值插入到(/存在的)列表尾部
* LPOP : 移除并获取列表的第一个元素
* RPOP: 移除并获取列表的最后一个元素
* LTRIM: 保留指定区间内的元素
* LLEN: 获取列表长度
* LSET: 通过索引设置列表元素的值
* LINDEX: 通过索引获取列表中的元素
* LRANGE: 获取列表指定范围内的元素
3.2 架构设计
1、首先记录哪一个用户参与了秒杀同时记录他的时间。
2、将用户的id存到redis列表中,让它排队。如果规定只有前10个用户可以参与活动,如果列表中个数已经够了就不会让它继续插入数据。这样redis的列表长度就为10个。
3、最后慢慢的将redis中的数据写入到数据库中,以减小数据的压力。
3.3 代码初级设计
1、当用户开始参与秒杀时,将秒杀程序的请求写入Redis(uid, time)中。
2、假如只有10个人可以秒杀成功,检查Redis已经存放数据的长度,达到上限后不再插入,说明秒杀已完成。
3、最后循环处理存入Redis中的10条数据,然后慢慢取数据存入到数据库中。
在秒杀这一块对数据库压力特别大,如果我们直接在用户发起秒杀请求时,每次都查询数据库是否已经达到秒杀人数上限的话,会造成数据库压力巨大。现在通过Redis的一个队列list,然后把秒杀请求放入到Redis里面,最后将秒杀成功的数据通过入库程序写入到数据库,这样的话会极大缓解mysql的压力。
本文参考来自:https://www.cnblogs.com/dump/p/8243868.html
PHP消息队列学习的更多相关文章
- Rabbit五种消息队列学习(一) – 总述
RabbitMQ支持五种消息传递类型,分别如下图所示: 上图中显示6中消息队列分别为: 1.简单队列 一个生产者将消息放到队列中,一个消费者监听队列 2.工作队列(Work queues) 一个生产者 ...
- RabbitMQ五种消息队列学习(三)–Work模式
由于在实际应用中,简单队列模型无法解决很多实际问题,而且生产者和消费者是一对一的关系.模型较为单一.故引入Work模式. 结构图 一个生产者.多个消费者. 一个消息只能被一个消费者获取. 测试实现: ...
- Rabbit五种消息队列学习(二) – 简单队列
队列结构图 P:消息的生产者 C:消息的消费者 红色:队列 生产者将消息发送到队列,消费者从队列中获取消息. 测试 1.连接MQ public static Connection getConnect ...
- NSQ:分布式消息队列学习记录
参考资料: NSQ:分布式的实时消息平台 初识NSQ分布式实时消息架构 深入NSQ之旅 nsq topic和channel的区别
- 消息队列——RabbitMQ学习笔记
消息队列--RabbitMQ学习笔记 1. 写在前面 昨天简单学习了一个消息队列项目--RabbitMQ,今天趁热打铁,将学到的东西记录下来. 学习的资料主要是官网给出的6个基本的消息发送/接收模型, ...
- Linux进程间通信IPC学习笔记之消息队列(SVR4)
Linux进程间通信IPC学习笔记之消息队列(SVR4)
- skynet源代码学习 - 从全局队列中弹出/压入一个消息队列过程
学习云风的skynet源代码,简单记录下. void skynet_globalmq_push(struct message_queue * queue) { struct global_queue ...
- 【框架学习与探究之消息队列--EasyNetQ(1)】
前言 本文欢迎转载,实属原创,本文原始链接地址:http://www.cnblogs.com/DjlNet/p/7603554.html 废话 既然都是废话了,所以大家就可以跳过了,这里是博主有事没事 ...
- 【框架学习与探究之消息队列--EasyNetQ(2)】
声明 本文欢迎转载,系博主原创,本文原始链接地址:http://www.cnblogs.com/DjlNet/p/7654902.html 前言 此文章,是承接上篇:[框架学习与探究之消息队列--Ea ...
随机推荐
- Nodejs mysql pool使用实例
前段时间在写一个版本发布工具,用到express+mysql实现,当站点运行很长一段空白时间后,node进程会自动down掉,提示mysql连接错误,谷歌后发现是mysql自身的特性导致,因此后来改为 ...
- 大数据“重磅炸弹”——实时计算框架 Flink
Flink 学习 项目地址:https://github.com/zhisheng17/flink-learning/ 博客:http://www.54tianzhisheng.cn/tags/Fli ...
- nginx去掉url中的index.php
使用情境:我想输入www.abc.com/a/1后,实际上是跳转到www.abc.com/index.php/a/1 配置Nginx.conf在你的虚拟主机下添加: location / { ...
- collectd 与 logstash配置
节点 node1: 配置logstash node2: 配置collectd, collectd收集本地的信息, 通过配置将信息发送到node1节点 node1安装配置logstash rpm -iv ...
- easyui框架中关于dialog自带关闭事件的使用
easyui是一个开源的第三方控件库,虽然使用比较方便,但其中有些事件和样式会与其他的控件或者框架形成冲突. 今天谈一下easyui 中dialog这个控件(对话框) easyui dialog一般在 ...
- C#实现对EXCEL指定单元格进行操作
using System; using System.Collections.Generic; using System.Text; using Microsoft.Office.Interop.Ex ...
- vue resource patch方法的传递数据 form data 为 [object Object]
今天在测试 iblog 登录时,传送过去的数据总是 [object Object],以至于后台识别不出来. vue 使用了 vueResource 组件,登录方法为 patch. 经过探索,终于在官网 ...
- Nginx 安装(CentOS )非yum安装
Nginx 安装(CentOS ) 一.安装编译工具及库文件 yum -y install make zlib zlib-devel gcc-c++ libtool openssl openssl-d ...
- vue-cli之脚手架
一.创建VUE项目 npm install vue-cli -g vue init webpack myprject cd myproject npm run dev 补充: 组件:它是可扩展的htm ...
- Catch the moments of your life. Catch them while you're young and quick.
Catch the moments of your life. Catch them while you're young and quick.趁你还年轻利落,把握住生活中的美好瞬间吧!