1场景场景电子商务推广手段(电子商务系统):分组券,议价,老类型新券,满减券,直减券,折扣券,券制核心流程,发放券凭证发放方式:同步发送或异步发送。谁能拿到代金券?所有用户或用户指
1场景场景
电子商务推广手段(电子商务系统):
分组券,议价,老类型新券,满减券,直减券,折扣券,券制核心流程,发放券
凭证发放方式:同步发送或异步发送。
谁能拿到代金券?所有用户或用户指定的用户都可以获得最大数量的优惠券。收款方式:用户主动收款或自动发放被动收款凭证。作用范围:商品、商家、类目的计算方法是否互斥,是否达到阈值等。需要拆卸。
商家方面:
创建优惠券并发送优惠券。
用户端:
领取优惠券下单使用优惠券支付2 Service 服务2.1 服务结构设计
接收优惠券、下订单、用优惠券支付、2服务服务、2.1服务结构设计
2.2优惠券系统的困难
优惠券的分布式交易,优惠券使用过程中的分布式问题分析。
如何防止头发过多
如何向用户大量发放优惠券
如何限制代金券的使用条件?
如何防止用户重复领取优惠券?
3存储存储
模型设计
系统的优惠券系统模型定义
优惠券制度的困难
3.1表单设计凭证批次(凭证模板),优惠券_批次
指一批优惠券的抽象和模板,包含了优惠券的大部分属性。
比如某商家创建了一批优惠券,共计1000张,使用时间为2022-11-11 00:00 ~ 2022-11-11 23:59:59。规定只能用数码产品,100券扣50。
票
发放给用户的实体,已经绑定到用户。
例如,如果一批优惠券中的一个被发送给用户,则该优惠券属于该用户。
规则
优惠券的使用是有规则和条件的。比如优惠券满100减50,需要达到100元的门槛金额才能使用。
凭证表优惠券_批量
规则表规则:
规则:
{阈值:5.01 //使用阈值金额:5 //折扣金额use_range: 3 //使用范围,0—全场,1—商家,2—类目,3—商品_id: 10 //商品id receive_count: 1 //每个用户可以领取的数量是_mutex: true //是否互斥?True表示互斥,True表示不互斥receive _ started _ at:2020-11-1 00:08:00//接收开始时间received _ ended _ at:2020-11-6 00:08:00//接收结束时间used _ started _ at: 2020-11-1 00。开始时间使用_结束_ at:2020-11-11 11:59:59//结束使用时间}优惠券表优惠券:
创建表t _ coupon(coupon _ id int null comment '凭证ID,主键',user_id int null注释'用户ID & # 039,batch_id int null注释'批次ID & # 039,status int null注释'0-未使用,1-已使用,2-过期,3-冻结',order_id varchar(255)空注释'对应的订单ID & # 039,received_time日期时间空注释'收集时间',validat_time日期时间空注释'生效日期',used_time日期时间空注释'利用时间');优惠券系统建立优惠券
1.创建新规则
插入到规则(名称,类型,规则_内容)值(“完全归约规则”,0,'{阈值:100金额:10......}');2.创建新的优惠券批。
INSERT INTO coupon_batch (coupon_name, rule_id, total_count ) VALUES(“劳斯莱斯5元代金券”, 1010, 10000);
发券
成coupon _ batch (coupon _ name,rule _ id,total _ count)值(“劳斯莱斯5元券”,1010,10000);发放代金券
如何给大量用户发放优惠券?
异步传输
对系统的短信和邮件可以通过调用第三方接口实现,站内消息可以通过在数据库中插入记录实现。
信息表消息
create table t _ message(id int null comment '信息',send_id int null注释'发件人id & # 039,rec_id int null注释'收件人id & # 039,内容vachar(255)注释'车站里的信的内容',is_read int null注释'你读过',send_time日期时间注释'发送时间')评论'信息表';先考虑用户数量很少的情况,如果一个商家想给大家发站内消息,首先要遍历用户表,然后根据用户表中的所有用户将站内消息插入消息表。这样,如果有100个用户,发送一个站内消息需要100次插入操作。
用户数量已经增加到一万。
发一条站内消息,要反复插入几万条数据。而且这几万条数据的内容都是一样的!假设一封站内信占100K,发一封站内信要十几米。为此,可以将原来的表拆分成两个表:
信息表消息
信息表消息_内容
要发送站内信函,请将站内信函的内容插入message_content。在消息表中,为所有用户插入一条记录,用站内字母标识数以千计的W级用户。
有[不活跃用户]的问题。假设有1000万注册用户,按照“二八”原则,其中活跃用户占20%。如果采用上述拆分成两个表的情况,发送一封“站内信”需要1000万次插入操作。可能剩下的80%用户就再也不会登录了。事实上,其中只有20%需要插入数据。
信息表消息:
create table t _ message(id int null comment '信息',# send _ id int null comment & # 039发件人id & # 039,删除字段rec _ id int null comment & # 039收件人id & # 039,message_id int null注释'外键,信息内容',is_read int null注释'你读过')评论'信息表';创建表t _ message _ content(id int null comment '信息内容id & # 039,send_id int null注释'发件人id & # 039,content varchar(255)空注释'内容',send_time日期时间空注释'发送时间');用户端操作
登录后先查询message_content中没有记录在消息中的数据,表示是未读站内信。在站内查阅信件内容时,将相关记录插入消息中。
系统侧操作
发送站内信函时:
只在 message_content 插入站内信的主体内容message 不插入记录假设商家要给 10W 用户发券
只有message_content被插入到站内信件的正文中。消息不插入记录。假设商家要给10W用户发优惠券。
有什么问题?重复消费导致超额支付!
提供符合操作条件的用户文件,上传到凭证发放管理后台,选择凭证管理服务器发送,根据【用户ID】和【凭证批次ID】生成消息,发送到MQ凭证服务器进行消费消息。
#记得用事务!插入优惠券(用户标识,优惠券标识,批量标识)值(1001,66889,1111);UPDATE coupon _ batch SET total _ count = total _ count-1,assign_count = assign_count + 1其中batch_id = 1111且total _ count >0;优惠券收集步骤检查优惠券余额。
SELECT total _ count FROM coupon _ batch其中batch _ id = 1111添加优惠券用户表,扣除保证金。
#关注商业!插入优惠券(用户标识,优惠券标识,批量标识)值(1001,66889,1111);UPDATE coupon _ batch SET total _ count = total _ count-1,assign_count = assign_count + 1其中batch_id = 1111且total _ count >0;在领取优惠券的过程中,其实也会出现类似的秒杀场景。尖峰场景中有哪些问题,如何解决?
解决用户重复或多次收藏的问题。
Redis数据验证!
在收到优惠券之前检查缓存。
#判断成员元素是否是设置的sis成员键值sis成员batch _ id: 1111: user _ id1001的成员,并在收到凭证后更新缓存。
#向集合中添加一个或多个成员元素,集合中已存在的成员元素将被忽略。Sadd键值1......valuen sadd batch _ ID:1111:User _ ID 1001优惠券
什么时候查看优惠券使用规则?
确认订单(√)提交订单,立即付款。
订单确认页面,查看优惠券:
判断是否过期判断适用范围判断是否达到门槛判断是否互斥返回可用券
判断是否过期,判断适用范围,判断是否达到阈值,判断是否互斥并返回可用优惠券。
SELECT batch_id FROM coupon WHERE user_id = 1001 AND status = 0; SELECT rule_id FROM coupon_batch WHERE batch_id = 1111; SELECT name, type, rule_content FROM rule WHERE rule_id = 1010;
选择可用券,并返回结果
从优惠券中选择batch_id,其中user_id = 1001,status = 0;SELECT rule_id FROM coupon_batch其中batch _ id = 1111从规则中选择名称、类型、规则内容,其中规则id = 1010。选择可用的优惠券并返回结果。
同时操作多个服务,如何保证一致性?
多个服务同时运营时如何保证一致性?
表格设计
操作记录表Coupon_opt_record
create table t _ coupon _ opt _ record(user _ id int null comment '用户id & # 039,coupon _ id int null comment & # 039优惠券id & # 039,操作int null注释'操作,0-锁定,1-核销,2-解锁',operated_at datetime空注释'操作时间');TCC,尝试-确认-取消,是分布式事务的主流解决方案。
第一阶段:尝试
冻结资源,储备业务资源。
创建订单时,将优惠券状态更改为“冻结”
第二阶段:确认
确认业务操作,真实提交,第一次尝试扣除冻结资源。
订单支付成功,优惠券状态更改为已使用。
第三阶段:取消
取消业务操作,取消试用阶段预留的业务资源。
如果支付失败/超时或订单关闭,将优惠券状态更改为“未使用”
秤扩展快速过期凭证提醒定时凭证扫表
缺点:扫描数据量太大。随着历史数据越来越多,会影响线上主要业务,最终导致SQL变慢。
延迟消息
缺点:部分优惠券有效期过长(超过30天),可能造成大量MQ积压。
添加通知表单
优点:扫描数据量小,效率高。删除无用的通知数据记录。
通知表设计(notify_msg)
create table t _ notify _ msg(id bigint auto _ increment comment '自增主键',coupon_id bigint空注释'优惠券id & # 039,user_id bigint空注释'用户id & # 039,notify_day varchar(255) null注释'需要执行通知的日期',notify _ type int null comment '通知类型,1-逾期提醒',notif_time时间戳空注释'通知的时间,在时间戳的几天之内',status int null注释'状态,0-初始状态,1-成功,2-失败',约束t _ notify _ msg _ id _ uin dex unique(id));alter table t_notify_msg添加主键(id);过期凭单提醒:
在创建优惠券的时候就将需要提醒的记录插入提醒表中notify_msg把用户ID+批次ID+通知日期作为唯一索引,防止同一个批次有重复的记录通知,保证每天只会被通知一次建立notify_time,通知时间索引,每日的通知扫描通过该索引列查询,通过索引列来提高查询效率通知完成后该表中的数据变失去了意义,通过定时任务将该数据删除数据库层面优化 – 索引
创建优惠券时,将需要提醒的记录插入到提醒表中。notify_msg以用户ID+批次ID+通知日期作为唯一索引,防止同一批次出现重复记录通知。保证每天只通知您一次,以建立通知时间和通知时间索引。每日通知通过此索引列进行扫描,以提高查询效率。通知完成后,此表中的数据变得没有意义,通过计划任务& # 889索引删除此数据,在数据库级别对其进行优化
出票接口,限流保护前端限流
点击一次,按钮会短暂变灰。
后端电流限制
有的请求直接跳转到【忙页】