在Magento中用MySQL模拟队列发送电子邮件
1. 需求
顾客在网站上购买特定商品并且这些商品的总金额超过特定金额后,使用email给顾客发送一个优惠券;假如某件商品已经降价了,则此商品的金额不计算在目标总金额内;
2. 需求分析
①发送优惠券的规则:i. 购物车中包换特定商品;ii. 这些商品的总金额大于预先设定的特定金额
②顾客本次购买的订单中,如果某个商品的实际价格小于原价,则表示此件商品的实际价格是打折后的,则它的价格不会计算在目标总金额内
③每次顾客完成支付后,需要对所有的订单商品验证是否符合发送优惠券的规则,此操作可能会比较耗费时间
④如果某一个订单验证通过,则生成优惠券并通过email发送,但是发送email这一操作比较耗时
Magento 里可以很方便的 observer 订单保存( sales_order_save_after )的操作, 在 observer 的方法中,只需要判断这个订单的状态为’processing’即表示为“已支付”,此时可以进行优惠规则验证。
验证通过,即可通过 email 发送优惠券。但是考虑到验证规则和发送email比较耗时,而 observer 又是实时的,假如直接在 sales_order_save_after 之后进行这两项操作,订单成功页面会出现比较大的延迟。
3. 解决办法
在这里,我为 验证优惠规则 和 通过email发送优惠券 这两个操作建立了一个 mysql 表
|
1
2 3 4 5 6 7 8 9 10 11 12 13 |
CREATE TABLE `coupon_queue` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Queue Id', `event_code` varchar(255) DEFAULT '' COMMENT 'Event Code', `event_identifier` varchar(255) DEFAULT '' COMMENT 'Event Identifier', `event_data` varchar(255) DEFAULT '' COMMENT 'Event Data', `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'Created At', `executed_at` timestamp NULL DEFAULT NULL COMMENT 'Execute At', `execute_result` varchar(255) DEFAULT '' COMMENT 'Event Execute Result', `is_executed` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Event Execute Status', PRIMARY KEY (`id`), UNIQUE KEY `UNQ_COUPON_QUEUE_EVENT_IDENTIFIER` (`event_identifier`), KEY `IDX_COUPON_QUEUE_EVENT_CODE_IS_EXECUTED` (`event_code`,`is_executed`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Event Queue Table'; |
其中,
event_code 表示某类事件,
event_identifier 表示某一个事件, 具有唯一性;
event_data 是执行事件所必需的数据, 它是一个对 array 进行序列化后的得到的字符串;
execute_result 是事件执行的结果,如果事件执行中有报错,会将报错信息写入这里;
created_at, executed_at 分别是事件的创建时间和执行时间
is_executed 表示此事件是否已经执行过了
通过 observer ‘sales_order_save_after’, 每次当有’processing’的订单的时候, 会在 coupon_queue 中插入一行数据:
|
1
2 |
INSERT INTO coupon_queue (event_code, event_identifier, event_data, created_at, is_executed)
VALUES ( 'add_order_to_queue', '9200000217_processing', 'a:2:{s:8:"order_id";s:10:"9200000217";s:12:"order_status";s:10:"processing";}', '2017-02-23 11:06:40', 0 ) |
在 coupon_queue 表中插入一行的代价是很小的,对性能的影响可以忽略不计。然后再通过计划任务来每5分钟执行 coupon_queue 表中未执行的项目:
首先是读取未执行的 add_order_to_queue 事件:
|
1
|
SELECT * FROM coupon_queue WHERE event_code = 'add_order_to_queue' AND is_executed = 0;
|
coupon_queue 表中 event_data 是已经经过序列化的 array, 对其反序列化后可以得到执行事件时所需要数据。
在取得 add_order_to_queue 事件的数据后,通过对 event_data 反序列化,可以得到预先为执行此事件准备的数据。事件 add_order_to_queue 的作用是验证order是否符合发放优惠券的条件,如果验证通过,则会在 coupon_queue 表中插入另一个新的事件:
|
1
2 |
INSERT INTO coupon_queue (event_code, event_identifier, event_data, created_at, is_executed)
VALUES ('send_coupon_code_by_email', '9200000217_processing_1_14', 'a:4:{s:8:"order_id";s:10:"9200000217";s:12:"order_status";s:10:"processing";s:13:"promo_rule_id";s:2:"14";s:8:"promo_id";s:1:"1";}', '2017-02-23 11:10:10', 0); |
和上面 add_order_to_queue 事件一样,可以通过如下SQL来获取即将执行的事件的数据:
|
1
|
SELECT * FROM coupon_queue WHERE event_code = 'send_coupon_code_by_email' AND is_executed = 0;
|
这个事件是用来发送email的。和处理 add_order_to_queue 事件一样, 通过反序列 event_data 后可以获得执行发送 email 事件的数据,然后发送email给顾客。
这样一来,就把订单成功 -> 验证优惠券发放规则 -> 发送email 这一流程转换为两个队列,避免在订单高峰期时,这个非常耗时的流程,对网站业务逻辑的冲击,将实时性不高的业务推迟处理,有效减少了下单成功页面的响应时间。
如果您觉得阅读本文对您有帮助,欢迎转载本文,但是转载文章之后必须在文章页面明显位置保留此段声明,否则保留追究法律责任的权利。
作 者:www.jpdou.top
原文链接:http://www.jpdou.top/use-mysql-to-simulate-queue-to-send-email/
在Magento中用MySQL模拟队列发送电子邮件的更多相关文章
- PHP 命令行模式实战之cli+mysql 模拟队列批量发送邮件(在Linux环境下PHP 异步执行脚本发送事件通知消息实际案例)
源码地址:https://github.com/Tinywan/PHP_Experience 测试环境配置: 环境:Windows 7系统 .PHP7.0.Apache服务器 PHP框架:ThinkP ...
- javamail模拟邮箱功能发送电子邮件-基础实战篇(javamail API电子邮件实例)
引言: JavaMail 是一种可选的.能用于读取.编写和发送电子消息的包 JavaMail jar包下载地址:http://java.sun.com/products/javamail/downlo ...
- javamail模拟邮箱功能发送电子邮件-中级实战篇【新增附件发送方法】(javamail API电子邮件实例)
引言: JavaMail jar包下载地址:http://java.sun.com/products/javamail/downloads/index.html 此篇是紧随上篇文章而封装出来的,阅读本 ...
- python#模拟发送电子邮件
#-*- coding:utf-8 -*- #模拟发送电子邮件 from email.mime.text import MIMEText from_addr = 'aa@sss.com' passwo ...
- JAVA实现发送电子邮件
相信大家对于网站也好,手机app也好,用户注册时,需要进行邮箱验证的功能特别好奇吧,本篇我将带领大家一起实现一下这个简单而又神奇的小功能,让我们的应用也可以加入这些神奇的元素.废话不多说,下面开始我们 ...
- WordPress ”无法发送电子邮件,可能原因:您的主机禁用了mail()函数“的解决办法
WordPress网站中出现 "无法发送电子邮件,可能原因:您的主机禁用了mail()函数"的情况一般都是因为所在主机环境不支持在线邮件收发功能导致,如果不支持的话,那么像类似 N ...
- poj3984迷宫问题 广搜+最短路径+模拟队列
转自:http://blog.csdn.net/no_retreats/article/details/8146585 定义一个二维数组: int maze[5][5] = { 0, 1, 0, ...
- 5. redis管道, 发布订阅, 模拟队列
一. 发布订阅 #订阅scribe 127.0.0.1:6379> SUBSCRIBE "channel_1" Reading messages... (press Ctrl ...
- 使用appium模拟用户发送短信
一段简单粗糙的代码.主要是实现的功能是模拟用户发送短信的功能. python版本3.5.2 appium版本1.4.16.1 from appium import webdriver desired_ ...
随机推荐
- 洛谷-铺地毯-NOIP2011提高组复赛
题目描述 为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯.一共有 n 张地毯,编号从 1 到n .现在将这些地毯按照编号从小到大的顺序平行于 ...
- IPSec方案部署(多业务场景)
技术点详解—IPSec方案部署 通过前面几期的介绍可以发现IPSec所涉及的参数很多,在具体方案部署过程中有许多灵活选择的地方,本期专栏就专门对IPSec在几种典型环境中的方案部署进行介绍. 一. ...
- IoC概述
---------------siwuxie095 IoC,即 Inversion of Control,控制反转,它是 Spring 容器的内核 AOP.声明式事务等功能都是在此基础上开花结果,即 ...
- 6.docker常用命令
docker 常见命令 更细的配置请参考官方文档 第一大部分容器生命周期管理 01 .docker run :创建一个新的容器并运行一个命令 $ docker run [OPTIONS] IMAGE ...
- linux 的有用的网站
从windows下移到linux下还有很长的路走阿,慢慢记录一些有用的网站吧 http://www.yolinux.com/ http://linux.die.net/
- html css将图片或div置于顶层
在做这个功能时,图片被挡住了.. 解决办法 在这个图片的css里加上z-index:数字:(数字可以为正也可以为负数) z-index:1肯定在z-index:-1的上面 用这个属性来给div分层 是 ...
- C# 写 LeetCode easy #27 Remove Element
27. Remove Element Given an array nums and a value val, remove all instances of that value in-place ...
- c# 一维数组的声明方式
1.直接指定数组元素 int [] arr = {2,4,1,8,4}; 2.只指定数组长度不指定元素值 指定一个长度为5的int型数组 int [] arr = new int[5]; 3.不指定 ...
- ProtoBuf练习(二)
重复数据类型 protobuf语言的重复字段类型相当于C++的std::list数据类型 工程目录结构 $ ls proto/ TServer.proto TSession.proto proto文件 ...
- 通过Python调用Spice-gtk
序言 通过Virt Manager研究学习Spice gtk的Python方法 你将学到什么 Virt Manager研究 显示代码定位 首先我们使用Virt Manager来观察桌面连接窗口 然后我 ...