日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > windows >内容正文

windows

优惠券系统设计思想

發(fā)布時間:2024/3/13 windows 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 优惠券系统设计思想 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 場景
    • 優(yōu)惠券的種類
    • 優(yōu)惠券系統(tǒng)的核心流程
      • 發(fā)券
      • 領(lǐng)券
      • 用券
    • 需求拆解
      • 商家側(cè)
      • 用戶側(cè)
  • 服務(wù)
    • 服務(wù)結(jié)構(gòu)設(shè)計
    • 優(yōu)惠券系統(tǒng)設(shè)計技術(shù)難點
  • 存儲
    • 表單設(shè)計
      • 券批次(券模板)
      • 規(guī)則
    • 建券
      • 新建規(guī)則
      • 新建優(yōu)惠券批次
    • 發(fā)券
      • 如何給大量用戶發(fā)券?
      • 觸達系統(tǒng)
      • 系統(tǒng)用戶數(shù)增加到`w級`
      • `千w級`用戶數(shù)
      • 給 10W 用戶發(fā)券
    • 領(lǐng)券
      • 步驟
      • 用戶重復(fù)領(lǐng)取或多領(lǐng)
    • 用券
      • 返回可用券
      • 選擇可用券,并返回結(jié)果
      • 同時操作多個服務(wù),如何保證一致性?
      • 表設(shè)計
  • 擴展
    • 快過期券提醒
    • 過期券提醒
    • 數(shù)據(jù)庫層面優(yōu)化
    • 發(fā)券接口,限流保護

場景

電商大廠常見促銷手段:

  • 優(yōu)惠券
  • 拼團
  • 砍價
  • 老帶新

優(yōu)惠券的種類

  • 滿減券
  • 直減券
  • 折扣券

優(yōu)惠券系統(tǒng)的核心流程

發(fā)券

發(fā)券的方式:同步發(fā)送 or 異步發(fā)送

領(lǐng)券

  • 誰能領(lǐng)?

所有用戶 or 指定的用戶

  • 領(lǐng)取上限

一個優(yōu)惠券最多能領(lǐng)取多少張?

  • 領(lǐng)取方式

用戶主動領(lǐng)取 or 自動發(fā)放被動領(lǐng)取

用券

  • 作用范圍

商品、商戶、類目

  • 計算方式

是否互斥、是否達到門檻等

需求拆解

商家側(cè)

  • 創(chuàng)建優(yōu)惠券
  • 發(fā)送優(yōu)惠券

用戶側(cè)

  • 領(lǐng)取優(yōu)惠券
  • 下單
  • 使用優(yōu)惠券
  • 支付

服務(wù)

服務(wù)結(jié)構(gòu)設(shè)計

優(yōu)惠券系統(tǒng)設(shè)計技術(shù)難點

  • 券的分布式事務(wù),使用券的過程會出現(xiàn)的分布式問題分析?
  • 如何防止超發(fā)?
  • 如何大批量給用戶發(fā)券?
  • 如何限制券的使用條件?
  • 如何防止用戶重復(fù)領(lǐng)券?

存儲

表單設(shè)計

券批次(券模板)

指一批優(yōu)惠券的抽象、模板,包含優(yōu)惠券的大部分屬性。

如商家創(chuàng)建了一批優(yōu)惠券,共1000張,使用時間為2022-11-11 00:00:00 ~ 2022-11-11 23:59:59,規(guī)定只有數(shù)碼類目商品才能使用,滿100減50。

發(fā)放到用戶的一個實體,已與用戶綁定。

如將某批次的優(yōu)惠券中的一張發(fā)送給某個用戶,此時優(yōu)惠券屬于用戶。

create table t_coupon (coupon_id int null comment '券ID,主鍵',user_id int null comment '用戶ID',batch_id int null comment '批次ID',status int null comment '0-未使用、1-已使用、2-已過期、3-凍結(jié)',order_id varchar(255) null comment '對應(yīng)訂單ID',received_time datetime null comment '領(lǐng)取時間',validat_time datetime null comment '有效日期',used_time datetime null comment '使用時間' );

規(guī)則

優(yōu)惠券的使用有規(guī)則和條件限制,比如滿100減50券,需要達到門檻金額100元才能使用。

規(guī)則內(nèi)容:

{ threshold: 5.01 // 使用門檻 amount: 5 // 優(yōu)惠金額 use_range: 3 // 使用范圍,0—全場,1—商家,2—類別,3—商品 commodity_id: 10 // 商品 id receive_count: 1 // 每個用戶可以領(lǐng)取的數(shù)量 is_mutex: true // 是否互斥,true 表示互斥,false 表示不互斥 receive_started_at: 2020-11-1 00:08:00 // 領(lǐng)取開始時間 receive_ended_at: 2020-11-6 00:08:00 // 領(lǐng)取結(jié)束時間 use_started_at: 2020-11-1 00:00:00 // 使用開始時間 use_ended_at: 2020-11-11 11:59:59 // 使用結(jié)束時間 }

建券

新建規(guī)則

INSERT INTO rule (name, type, rule_content) VALUES(“滿減規(guī)則”, 0, '{ threshold: 100 amount: 10 ...... }');

新建優(yōu)惠券批次

INSERT INTO coupon_batch (coupon_name, rule_id, total_count ) VALUES(“勞斯萊斯5元代金券”, 1010, 10000);

發(fā)券

如何給大量用戶發(fā)券?

異步發(fā)送!

觸達系統(tǒng)

  • 短信、郵件

可通過調(diào)用第三方接口的方式實現(xiàn)

  • 站內(nèi)信

通過數(shù)據(jù)庫插入記錄來實現(xiàn)

信息表 message

create table t_message (id int null comment '信息ID',send_id int null comment '發(fā)送者id',rec_id int null comment '接受者id',content vachar(255) comment '站內(nèi)信內(nèi)容',is_read int null comment '是否已讀',send_time datetime comment '發(fā)送時間' ) comment '信息表';

先考慮用戶量很少的情況,商家要給所有人發(fā)站內(nèi)信,則先遍歷用戶表,再按照用戶表中的所有用戶依次將站內(nèi)信插入到 message 表中。這樣,如果有100個用戶,則群發(fā)一條站內(nèi)信要執(zhí)行100個插入操作。

系統(tǒng)用戶數(shù)增加到w級

發(fā)一條站內(nèi)信,就得重復(fù)插入上萬條數(shù)據(jù)。而且這上萬條數(shù)據(jù)的 content 一樣!假設(shè)一條站內(nèi)信占100K,發(fā)一次站內(nèi)信就要消耗十幾M。對此,可將原來的表拆成兩個表:

信息表 message

信息內(nèi)容表 message_content

發(fā)一封站內(nèi)信的步驟

  • 往 message_content 插入站內(nèi)信的內(nèi)容
  • 在 message 表中,給所有用戶插入一條記錄,標(biāo)識有一封站內(nèi)信
  • 千w級用戶數(shù)

    這就有【非活躍用戶】的問題,假設(shè)注冊用戶一千萬,根據(jù)二八原則,其中活躍用戶占20%。若采用上面拆成兩個表的情況,發(fā)一封“站內(nèi)信”,得執(zhí)行一千萬個插入操作。可能剩下80%用戶基本都不會再登錄,其實只需對其中20%用戶插入數(shù)據(jù)。

    信息表 message

    create table t_message (id int null comment '信息 ID',# send_id int null comment '發(fā)送者 id', 去除該字段rec_id int null comment '接受者 id',message_id int null comment '外鍵,信息內(nèi)容',is_read int null comment '是否已讀' )comment '信息表';

    信息內(nèi)容表 message_content

    create table t_message_content (id int null comment '信息內(nèi)容id',send_id int null comment '發(fā)送者id',content varchar(255) null comment '內(nèi)容',send_time datetime null comment '發(fā)送時間' );

    用戶側(cè)操作

    登錄后,首先查詢 message_content 中的那些沒有在 message 中有記錄的數(shù)據(jù),表示是未讀的站內(nèi)信。在查閱站內(nèi)信的內(nèi)容時,再將相關(guān)的記錄插入 message。

    系統(tǒng)側(cè)操作

    發(fā)站內(nèi)信時:

    • 只在 message_content 插入站內(nèi)信的主體內(nèi)容
    • message 不插入記錄

    給 10W 用戶發(fā)券

    有什么問題?重復(fù)消費,導(dǎo)致超發(fā)!

  • 運營提供滿足條件的用戶文件,上傳到發(fā)券管理后臺并選擇要發(fā)送的優(yōu)惠券
  • 管理服務(wù)器根據(jù)【用戶ID】、【券批次ID】生成消息,發(fā)送到MQ
  • 優(yōu)惠券服務(wù)器消費消息
  • # 記住使用事務(wù)哦! INSERT INTO coupon (user_id, coupon_id,batch_id)VALUES(1001, 66889, 1111);UPDATE coupon_batch SET total_count = total_count - 1,assign_count = assign_count + 1WHERE batch_id = 1111 AND total_count > 0;

    領(lǐng)券

    步驟

    • 校驗優(yōu)惠券余量
    SELECT total_count FROM coupon_batch WHERE batch_id = 1111;
    • 新增優(yōu)惠券用戶表,扣減余量
    # 注意事務(wù)! INSERT INTO coupon (user_id, coupon_id,batch_id)VALUES(1001, 66889, 1111); UPDATE coupon_batch SET total_count = total_count - 1,assign_count = assign_count + 1WHERE batch_id = 1111 AND total_count > 0;

    用戶領(lǐng)券過程中,其實也會出現(xiàn)類似秒殺場景。秒殺場景下會有哪些問題,如何解決?

    用戶重復(fù)領(lǐng)取或多領(lǐng)

    Redis 數(shù)據(jù)校驗!

    1.領(lǐng)券前,先查緩存

    # 判斷成員元素是否是集合的成員 SISMEMBER KEY VALUE SISMEMBER batch_id:1111:user_id 1001

    2.領(lǐng)券

    3.領(lǐng)券后,更新緩存

    # 將一或多個成員元素加入到集合中,已經(jīng)存在于集合的成員元素將被忽略 SADD KEY VALUE1......VALUEN SADD batch_id:1111:user_id 1001xxxxxxxxxx # 將一或多個成員元素加入到集合中,已經(jīng)存在于集合的成員元素將被忽略 SADD KEY VALUE1......VALUENSADD batch_id:1111:user_id 1001# 將一或多個成員元素加入到集合中,已經(jīng)存在于集合的成員元素將被忽略 SADD KEY VALUE1......VALUENSADD batch_id:1111:user_id 1001

    用券

    • 何時校驗優(yōu)惠券使用規(guī)則?
  • 確認訂單(√)
  • 提交訂單
  • 立即付款
    • 確認訂單頁,對優(yōu)惠券進行校驗:
  • 判斷是否過期
  • 判斷適用范圍
  • 判斷是否達到門檻
  • 判斷是否互斥
  • 返回可用券

    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;

    選擇可用券,并返回結(jié)果

    同時操作多個服務(wù),如何保證一致性?

    表設(shè)計

    # 優(yōu)惠券操作記錄表create table t_coupon_opt_record (user_id int null comment '用戶id',coupon_id int null comment '優(yōu)惠券id',operating int null comment '操作,0-鎖定、1-核銷、2-解鎖',operated_at datetime null comment '操作時間' );

    TCC,Try-Confirm-Cancel,目前分布式事務(wù)主流解決方案。

    • 階段一:Try

    對資源進行凍結(jié),預(yù)留業(yè)務(wù)資源
    創(chuàng)建訂單時,將優(yōu)惠券狀態(tài)改為 “凍結(jié)”

    • 階段二:Confirm

    確認執(zhí)行業(yè)務(wù)操作,做真正提交,將第一步Try中凍結(jié)的資源,真正扣減
    訂單支付成功,將優(yōu)惠券狀態(tài)改為 “已使用”

    • 階段三:Cancel

    取消執(zhí)行業(yè)務(wù)操作,取消Try階段預(yù)留的業(yè)務(wù)資源
    支付失敗/超時或訂單關(guān)閉情況,將優(yōu)惠券狀態(tài)改為 “未使用”

    擴展

    快過期券提醒

    • 定時掃券表

    缺點:掃描數(shù)據(jù)量太大,隨著歷史數(shù)據(jù)越來越多,會影響線上主業(yè)務(wù),最終導(dǎo)致慢SQL。

    • 延時消息

    缺點:有些券的有效時間太長了(30天)以上,有可能造成大量 MQ 積壓

    • 新增通知表

    優(yōu)點:掃描的數(shù)據(jù)量小,效率高。刪除無用的已通知的數(shù)據(jù)記錄

    # 通知信息表create table t_notify_msg (id bigint auto_increment comment '自增主鍵',coupon_id bigint null comment '券id',user_id bigint null comment '用戶id',notify_day varchar(255) null comment '需要執(zhí)行通知的日期',notify_type int null comment '通知類型,1-過期提醒',notif_time timestamp null comment '通知的時間,在該時間戳所在天內(nèi)通知',status int null comment '通知狀態(tài),0-初始狀態(tài)、1-成功、2-失敗',constraint t_notify_msg_id_uindexunique (id) );alter table t_notify_msgadd primary key (id);

    過期券提醒

  • 在創(chuàng)建優(yōu)惠券的時候就將需要提醒的記錄插入提醒表中notify_msg
  • 把用戶ID+批次ID+通知日期作為唯一索引,防止同一個批次有重復(fù)的記錄> 通知,保證每天只會被通知一次
  • 建立notify_time,通知時間索引,每日的通知掃描通過該索引列查詢,通> 過索引列來提高查詢效率
  • 通知完成后該表中的數(shù)據(jù)變失去了意義,通過定時任務(wù)將該數(shù)據(jù)刪除
  • 數(shù)據(jù)庫層面優(yōu)化

    發(fā)券接口,限流保護

    • 前端限流

    點擊一次后,按鈕短時間內(nèi)置灰

    • 后端限流

    部分請求直接跳轉(zhuǎn)到【繁忙頁】

    總結(jié)

    以上是生活随笔為你收集整理的优惠券系统设计思想的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。