大話(huà)業(yè)務(wù)場(chǎng)景與解決方案-做任務(wù)

大話(huà)業(yè)務(wù)場(chǎng)景與解決方案-做任務(wù)

背景

多數(shù)的移動(dòng)端APP都會(huì)有做任務(wù)領(lǐng)取獎(jiǎng)勵(lì)的功能模塊玻蝌,這類(lèi)需求的目的是培養(yǎng)用戶(hù)使用習(xí)慣蟹肘,提升用戶(hù)活躍性词疼,用戶(hù)完成任務(wù)獲得積分獎(jiǎng)勵(lì),通過(guò)積分兌換商品或者充值話(huà)費(fèi)帘腹,微信體現(xiàn)等贰盗。

擬定需求場(chǎng)景(如圖↓),概要:APP底部導(dǎo)航中新增小任務(wù)Tab阳欲,點(diǎn)擊Tab可查看任務(wù)完成進(jìn)度和領(lǐng)取情況舵盈,點(diǎn)擊去完成跳轉(zhuǎn)到做任務(wù)的業(yè)務(wù)界面,當(dāng)用戶(hù)完成任務(wù)并且滿(mǎn)足領(lǐng)取條件的時(shí)候球化,任務(wù)Tab需要紅點(diǎn)提醒用戶(hù)當(dāng)前有獎(jiǎng)勵(lì)可領(lǐng)取秽晚,用戶(hù)領(lǐng)取后并且當(dāng)前沒(méi)有待領(lǐng)取獎(jiǎng)勵(lì)小紅點(diǎn)消失,任務(wù)完成進(jìn)度和領(lǐng)取狀態(tài)僅保持當(dāng)天筒愚,隔天刷新爆惧。

任務(wù)需求

業(yè)務(wù)分析

在開(kāi)發(fā)前需要對(duì)需求進(jìn)行整理,對(duì)細(xì)節(jié)進(jìn)行確認(rèn)锨能,然后設(shè)計(jì)解決方案,預(yù)估開(kāi)發(fā)時(shí)間芍耘,這里將對(duì)于業(yè)務(wù)中核心的內(nèi)容進(jìn)行梳理:

  1. 用戶(hù)想要完成任務(wù)址遇,需要去操作其他業(yè)務(wù)功能,如:評(píng)論成功后需要完成每日評(píng)論任務(wù)斋竞,關(guān)注主題后完成關(guān)注新手任務(wù)倔约,這里就涉及核心問(wèn)題,任務(wù)需要依賴(lài)于其他業(yè)務(wù)

  2. 為了保障后續(xù)拓展性坝初,任務(wù)需要支持后臺(tái)管理浸剩,配置任務(wù)名,描述鳄袍,任務(wù)類(lèi)型(每日绢要,新手,活動(dòng))拗小,完成次數(shù)重罪,獎(jiǎng)勵(lì)積分?jǐn)?shù)量,去完成跳轉(zhuǎn)uri 等

  3. 用戶(hù)完成任務(wù)后不用自動(dòng)領(lǐng)取獎(jiǎng)勵(lì)哀九,需要進(jìn)入到任務(wù)列表點(diǎn)擊領(lǐng)取操作剿配,可領(lǐng)取時(shí)導(dǎo)航Tab需要小紅點(diǎn)提醒,和產(chǎn)品確認(rèn)任務(wù)的完成和提醒的用戶(hù)體驗(yàn) 可以接受短時(shí)間延遲

  4. 用戶(hù)多次操作業(yè)務(wù)阅束,或者出現(xiàn)重復(fù)操作(惡意并發(fā)請(qǐng)求刷積分)呼胚,保證任務(wù)只能完成一次并且只能領(lǐng)取一次獎(jiǎng)勵(lì),需要保證冪等性


方案設(shè)計(jì)

核心目標(biāo):
  1. 任務(wù)依賴(lài)其他業(yè)務(wù)息裸,需要進(jìn)行解耦蝇更,不影響其他業(yè)務(wù)的功能和性能
  2. 設(shè)計(jì)后臺(tái)可管理沪编,便于后續(xù)拓展
  3. 抽象任務(wù)模塊,代碼抽象開(kāi)發(fā)
  4. 完成任務(wù)和領(lǐng)取需要保證冪等性
  5. 高可用
名詞定義:

事件

  • 任務(wù)中涉及依賴(lài)其他業(yè)務(wù)簿寂,這里需要抽象出一個(gè)概念漾抬,用戶(hù)通過(guò)操作業(yè)務(wù),完成任務(wù)的這個(gè)操作常遂,我們把這個(gè)過(guò)程定義為用戶(hù)完成任務(wù)事件觸發(fā)完成纳令,如:評(píng)論事件,點(diǎn)贊事件克胳,關(guān)注事件平绩,等
解決方案:

在實(shí)現(xiàn)方案上,采用異步消耗隊(duì)列的方式漠另,依賴(lài)業(yè)務(wù)接口埋入事件上報(bào)捏雌,將用戶(hù)成功操作業(yè)務(wù)的任務(wù)事件上報(bào)到隊(duì)里中,然后開(kāi)發(fā)消息消耗的腳本程序笆搓,對(duì)消息中用戶(hù)觸發(fā)的任務(wù)事件進(jìn)行業(yè)務(wù)邏輯處理和DB操作性湿,更新用戶(hù)任務(wù)進(jìn)度和可領(lǐng)取狀態(tài),響應(yīng)給用戶(hù)(完成任務(wù)紅點(diǎn)提醒)满败,設(shè)計(jì)圖:


任務(wù)功能設(shè)計(jì)圖
  • 依賴(lài)業(yè)務(wù)解耦
    • 依賴(lài)業(yè)務(wù)將操作成功用戶(hù)的任務(wù)事件上報(bào)到消息隊(duì)列肤频,然后程序進(jìn)行異步消耗
    • 方案解決了依賴(lài)業(yè)務(wù)之間的強(qiáng)耦合,并且基本不影響現(xiàn)有依賴(lài)業(yè)務(wù)的接口性能
  • 高可用:
    • 通過(guò)調(diào)度系統(tǒng)啟動(dòng)多進(jìn)程對(duì)隊(duì)列進(jìn)行消耗
      • 進(jìn)程守護(hù)系統(tǒng)算墨,守護(hù)進(jìn)程毕模活,奔潰重啟净嘀,可對(duì)執(zhí)行日志進(jìn)行記錄與查看
      • 如: gocron
    • 消息隊(duì)列監(jiān)控报咳,無(wú)法及時(shí)消耗進(jìn)行預(yù)警,保障即時(shí)性挖藏,避免長(zhǎng)時(shí)間的延遲
      • rabbitmq
      • redis list
      • ... ...
    • 容錯(cuò)與補(bǔ)償
      • 隊(duì)列消耗失敗需要進(jìn)行記錄暑刃,并可根據(jù)業(yè)務(wù)場(chǎng)景,通過(guò)另外程序進(jìn)行補(bǔ)充處理
      • 用戶(hù)操作業(yè)務(wù)上報(bào)任務(wù)事件不限制次數(shù)膜眠,以免用戶(hù)沒(méi)完成任務(wù)稍走,允許用戶(hù)重新嘗試去做任務(wù),程序消耗需要控制任務(wù)只能完成一次

表結(jié)構(gòu):

-- 任務(wù)表
CREATE TABLE `task` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增',
  `icon` varchar(300) NOT NULL DEFAULT '' COMMENT '圖標(biāo)',
  `title` varchar(30) NOT NULL DEFAULT '' COMMENT '任務(wù)標(biāo)題',
  `type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '任務(wù)類(lèi)型柴底,新手任務(wù)=1,每日任務(wù)=2',
  `event` int(11) NOT NULL DEFAULT '0' COMMENT '事件',
  `des` varchar(30) NOT NULL DEFAULT '' COMMENT '任務(wù)描述',
  `target_num` int(11) NOT NULL DEFAULT '0' COMMENT '目標(biāo)數(shù)量',
  `points` int(11) NOT NULL DEFAULT '0' COMMENT '金幣',
  `sort` int(11) NOT NULL DEFAULT '0' COMMENT '排序',
  `status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '狀態(tài) 0=下線(xiàn)婿脸,1=上線(xiàn),-1=刪除',
  `app_version` varchar(15) NOT NULL DEFAULT '' COMMENT 'app版本號(hào)',
  `app_version_compare` varchar(10) NOT NULL DEFAULT '' COMMENT 'app版本號(hào)比較運(yùn)算符',
  `operator` varchar(10) NOT NULL DEFAULT '' COMMENT '操作人',
  `jump_uri` varchar(300) NOT NULL DEFAULT '' COMMENT '跳轉(zhuǎn)協(xié)議',
  `create_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時(shí)間',
  `update_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新時(shí)間',
  `event_begin` timestamp NOT NULL DEFAULT '1970-01-02 00:00:00' COMMENT '事件開(kāi)始時(shí)間',
  `event_end` timestamp NOT NULL DEFAULT '1970-01-02 00:00:00' COMMENT '事件結(jié)束時(shí)間',
  `task_begin` timestamp NOT NULL DEFAULT '1970-01-02 00:00:00' COMMENT '任務(wù)開(kāi)始時(shí)間',
  `task_end` timestamp NOT NULL DEFAULT '1970-01-02 00:00:00' COMMENT '任務(wù)結(jié)束時(shí)間',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 用戶(hù)任務(wù)情況表
CREATE TABLE `user_task_case` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用戶(hù)任務(wù)情況',
  `user_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '用戶(hù)ID',
  `task_id` int(11) NOT NULL DEFAULT '0' COMMENT '任務(wù)id',
  `task_type` int(11) NOT NULL DEFAULT '0' COMMENT '任務(wù)類(lèi)型',
  `event` int(11) NOT NULL DEFAULT '0' COMMENT '事件',
  `task_uni` varchar(30) NOT NULL DEFAULT '' COMMENT '任務(wù)唯一標(biāo)識(shí)(唯一約束) ',
  `target_num` int(11) NOT NULL DEFAULT '0' COMMENT '目標(biāo)數(shù)量',
  `finish_num` int(11) NOT NULL DEFAULT '0' COMMENT '完成數(shù)量',
  `points` int(11) NOT NULL DEFAULT '0' COMMENT '可領(lǐng)取金幣數(shù)量',
  `status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '狀態(tài) 0=待完成柄驻,1=待領(lǐng)取狐树,2=已經(jīng)領(lǐng)取',
  `finish_at` timestamp NOT NULL DEFAULT '1970-01-02 00:00:00' COMMENT '完成任務(wù)時(shí)間',
  `get_at` timestamp NOT NULL DEFAULT '1970-01-02 00:00:00' COMMENT '領(lǐng)取時(shí)間',
  `create_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時(shí)間',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uni_user_id_task_uni` (`user_id`,`task_uni`) USING BTREE,
) ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COMMENT='用戶(hù)任務(wù)情況表';

更新語(yǔ)句:

-- 更新領(lǐng)取狀態(tài),注意:WHERE條件鸿脓,強(qiáng)校驗(yàn)
UPDATE user_task_case 
SET  `status`=2,finish_at=CURRENT_TIMESTAMP
WHERE id=:id AND user_id=:user_id AND `status`=1 AND finish_num>=target_num

表重點(diǎn)字段說(shuō)明:

  • task_uni
    • 任務(wù)唯一標(biāo)識(shí)
  • user_id和task_uni 組合唯一約束索引
    • 每日任務(wù):
      • 任務(wù)id_任務(wù)類(lèi)型_日期(task_id_type_date)
    • 默認(rèn)都是只做一次(新手任務(wù)/活動(dòng)任務(wù)):
      • 任務(wù)id(task_id)
  • 冪等性
    • user_task_case 表中 user_id和task_uni 組合唯一約束索引抑钟,通過(guò)mysql的唯一約束涯曲,保證了多進(jìn)程并行消耗事件隊(duì)列的情況下,每日任務(wù)和一次性任務(wù)不能重復(fù)INSERT
    • 通過(guò)UPDATE的WHERE條件校驗(yàn)保障領(lǐng)取的冪等性

管理后臺(tái):

產(chǎn)品在規(guī)劃需求的時(shí)候會(huì)設(shè)計(jì)出相關(guān)后臺(tái)在塔,但是不一定設(shè)計(jì)的合理幻件,所以這里需要根據(jù)確認(rèn)的解決方案協(xié)助產(chǎn)品對(duì)于管理后臺(tái)進(jìn)行調(diào)整,保障后續(xù)的拓展性

任務(wù)管理

任務(wù)添加

代碼層面:

  • 面向抽象開(kāi)發(fā)蛔溃,合理使用設(shè)計(jì)模式绰沥,便于后續(xù)的拓展

話(huà)外篇:

談近一年的感悟,近一年參與了新APP項(xiàng)目的開(kāi)發(fā)贺待,從0開(kāi)始搭建項(xiàng)目徽曲,看著DAU一點(diǎn)點(diǎn)兒的漲起來(lái),還是挺有成就感的麸塞。

角色上產(chǎn)生了變化秃臣,現(xiàn)在感覺(jué)自己更像是一個(gè)項(xiàng)目的參與者,而不是任務(wù)的執(zhí)行人哪工,完成業(yè)務(wù)開(kāi)發(fā)的同時(shí)也會(huì)對(duì)產(chǎn)品上有根深了解奥此。

空閑時(shí)間也會(huì)對(duì)競(jìng)品調(diào)研以及用戶(hù)使用意見(jiàn)或者問(wèn)題進(jìn)行跟進(jìn),站在用戶(hù)角度提供產(chǎn)品上的一些建議雁比。

后續(xù)會(huì)把新項(xiàng)目開(kāi)發(fā)過(guò)程中遇到問(wèn)題或者常見(jiàn)的業(yè)務(wù)場(chǎng)景下的解決方案進(jìn)行梳理出來(lái)進(jìn)行博文分享得院。


首發(fā)于Github : ??《大話(huà)WEB開(kāi)發(fā)》,WEB開(kāi)發(fā)相關(guān)經(jīng)驗(yàn)總結(jié)分享章贞,歡迎大家Star一波,后續(xù)想看不迷路 ??

發(fā)布時(shí)間:2020-04-06

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末非洲,一起剝皮案震驚了整個(gè)濱河市鸭限,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌两踏,老刑警劉巖败京,帶你破解...
    沈念sama閱讀 217,185評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異梦染,居然都是意外死亡赡麦,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén)帕识,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)泛粹,“玉大人,你說(shuō)我怎么就攤上這事肮疗「幔” “怎么了瓜喇?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,524評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)澎迎。 經(jīng)常有香客問(wèn)我,道長(zhǎng)鳍刷,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,339評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮宗侦,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘忆蚀。我一直安慰自己矾利,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評(píng)論 6 391
  • 文/花漫 我一把揭開(kāi)白布蜓谋。 她就那樣靜靜地躺著梦皮,像睡著了一般。 火紅的嫁衣襯著肌膚如雪桃焕。 梳的紋絲不亂的頭發(fā)上剑肯,一...
    開(kāi)封第一講書(shū)人閱讀 51,287評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音观堂,去河邊找鬼让网。 笑死,一個(gè)胖子當(dāng)著我的面吹牛师痕,可吹牛的內(nèi)容都是我干的溃睹。 我是一名探鬼主播,決...
    沈念sama閱讀 40,130評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼胰坟,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼因篇!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起笔横,我...
    開(kāi)封第一講書(shū)人閱讀 38,985評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤竞滓,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后吹缔,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體商佑,經(jīng)...
    沈念sama閱讀 45,420評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評(píng)論 3 334
  • 正文 我和宋清朗相戀三年厢塘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了茶没。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,779評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡晚碾,死狀恐怖抓半,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情格嘁,我是刑警寧澤琅关,帶...
    沈念sama閱讀 35,477評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響涣易,放射性物質(zhì)發(fā)生泄漏画机。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評(píng)論 3 328
  • 文/蒙蒙 一新症、第九天 我趴在偏房一處隱蔽的房頂上張望步氏。 院中可真熱鬧,春花似錦徒爹、人聲如沸荚醒。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,716評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)界阁。三九已至,卻和暖如春胖喳,著一層夾襖步出監(jiān)牢的瞬間泡躯,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,857評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工丽焊, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留较剃,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,876評(píng)論 2 370
  • 正文 我出身青樓技健,卻偏偏與公主長(zhǎng)得像写穴,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子雌贱,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容