社區(qū)團(tuán)購系統(tǒng)定制方案:從“大單體”到“業(yè)務(wù)中臺”的架構(gòu)演進(jìn)之路
一、定制不是“堆功能”,而是“切業(yè)務(wù)”
上周和一位區(qū)域團(tuán)購平臺的CTO聊了很久。他們的平臺覆蓋了200個社區(qū),日訂單峰值接近5萬單,但原有的單體系統(tǒng)撐不住了——每天晚高峰搶菜時段,數(shù)據(jù)庫CPU直接飆到90%,最要命的是團(tuán)長提現(xiàn)和對賬總差幾毛錢。

“我們用的是某大廠的標(biāo)準(zhǔn)化SaaS,但業(yè)務(wù)稍微復(fù)雜一點就卡死?!?/strong>?他的這句話,道出了很多企業(yè)轉(zhuǎn)向定制開發(fā)的真實原因。標(biāo)準(zhǔn)化系統(tǒng)只解決“有沒有”,而定制方案要解決的是“撐不撐得住”和“算不算得清”。
相比于SaaS模板,定制化系統(tǒng)的核心優(yōu)勢在于數(shù)據(jù)主權(quán)和擴(kuò)展能力:你擁有100%的源代碼和數(shù)據(jù)庫控制權(quán),可以按業(yè)務(wù)發(fā)展無限擴(kuò)展,還能對接ERP、WMS等內(nèi)部系統(tǒng)。但前提是——架構(gòu)得對。
二、微服務(wù)怎么拆?我們用“團(tuán)”這個業(yè)務(wù)實體說話
很多技術(shù)負(fù)責(zé)人上來就問:“用Spring Cloud還是Dubbo?”其實技術(shù)棧不是首要問題,怎么拆服務(wù)才是決定后續(xù)三年維護(hù)成本的關(guān)鍵。
我們復(fù)盤過一個失敗案例。早期團(tuán)隊按標(biāo)準(zhǔn)電商拆:用戶、商品、訂單、支付、庫存五個服務(wù)。上線兩周就發(fā)現(xiàn)問題——社區(qū)團(tuán)購的核心不是“商品”,而是“團(tuán)”。
同一個蘋果,A小區(qū)今天開團(tuán)價是4.9元,B小區(qū)可能是5.5元;庫存也是按團(tuán)維度的,A團(tuán)剩10份,B團(tuán)已經(jīng)搶光。如果讓商品服務(wù)管價格、庫存服務(wù)管數(shù)量,一次下單要跨三四個服務(wù)來回確認(rèn),性能損耗極大。
最終沉淀下來的服務(wù)劃分方案是這樣的:
??group-service(團(tuán)服務(wù)):這是業(yè)務(wù)中臺的核心,管理“開團(tuán)”“參團(tuán)”“成團(tuán)”狀態(tài),以及提貨點信息。所有其他服務(wù)都重度依賴它。
??product-service(商品服務(wù)):注意,商品價格和庫存是按“團(tuán)”維度管理的,不再用全局庫存。
??inventory-service(庫存服務(wù)):獨立出來處理預(yù)扣、支付后扣減、次日未提貨返還等復(fù)雜邏輯,用Redis+Lua保證原子性。
??order-service、payment-service、delivery-service?各自獨立。
教訓(xùn)是什么??別為了微服務(wù)而微服務(wù)。“團(tuán)”這個強(qiáng)業(yè)務(wù)概念,必須有一個核心服務(wù)來承載和協(xié)調(diào)。拆分邊界不是技術(shù),而是業(yè)務(wù)能力與變更頻率。
三、分布式事務(wù):放棄強(qiáng)一致性,擁抱最終一致性
社區(qū)團(tuán)購最頭疼的技術(shù)難點是什么?下單鏈路跨服務(wù)。
用戶下單,涉及group-service(校驗團(tuán)狀態(tài))、inventory-service(扣庫存)、order-service(生成訂單)。怎么保證要么一起成功、要么一起失敗?
我們試過Seata的AT模式,但性能損耗明顯,維護(hù)也復(fù)雜。最終采用的是“本地消息表+消息隊列”的最終一致性方案:
下單入口在order-service的一個本地事務(wù)中,同時生成訂單并向本地消息表插入一條“扣庫存”消息
定時任務(wù)掃描消息表,通過RocketMQ發(fā)送給inventory-service
inventory-service消費消息執(zhí)行預(yù)扣庫存,如果失敗則回發(fā)“扣庫存失敗”消息
order-service消費失敗消息,將訂單狀態(tài)改為“無效”
兜底策略:每小時跑一次對賬Job,對比訂單狀態(tài)和庫存流水,不一致的自動補償或告警
這套方案在5萬單/天的壓力下跑得很穩(wěn)。核心思想是:核心鏈路只做必要的事,非核心的異步處理,最終能對上賬就行。
四、高并發(fā)應(yīng)對:別讓數(shù)據(jù)庫成為短板
社區(qū)團(tuán)購的業(yè)務(wù)特性是高頻次、短周期、強(qiáng)爆發(fā)。一場“9.9元秒殺榴蓮”,瞬間涌入的流量能直接把數(shù)據(jù)庫打掛。
我們的應(yīng)對策略分層落地:
1、流量入口層:Spring Cloud Gateway做統(tǒng)一限流和熔斷,單IP每秒超過5次請求直接攔截。
2、緩存層:商品詳情、團(tuán)信息全部上Redis。注意,團(tuán)狀態(tài)這種高頻變化的數(shù)據(jù),我們用Redis Hash + 本地緩存(Caffeine)兩級緩存,本地緩存設(shè)2秒過期,極大減輕Redis壓力。
3、數(shù)據(jù)庫層:讀寫分離是標(biāo)配,主庫寫、從庫讀。庫存扣減這種高并發(fā)寫操作,先在Redis里預(yù)減,異步同步到MySQL。
4、消息隊列削峰:秒殺時用戶點擊“立即購買”,請求先發(fā)到RocketMQ,后端服務(wù)異步消費。前端快速響應(yīng)“請求已接收”,避免請求堆積。
這套組合拳下來,數(shù)據(jù)庫的讀請求90%以上被緩存攔截,寫壓力通過MQ削峰,系統(tǒng)穩(wěn)了很多。
五、關(guān)于定制方案的幾點反思
如果用現(xiàn)在的眼光回頭看,inventory-service和group-service的耦合還是有點緊,部分邏輯可以下沉為領(lǐng)域能力。但整體架構(gòu)經(jīng)受住了考驗。
給正在選型的企業(yè)幾點建議:
第一,別一上來就追求大而全的微服務(wù)。50個團(tuán)長以內(nèi)的區(qū)域平臺,SpringBoot單體+Redis緩存完全夠用,等業(yè)務(wù)起來再拆分也不遲。
第二,關(guān)注非功能性需求。很多需求文檔只寫功能,不寫并發(fā)量、響應(yīng)時間、數(shù)據(jù)一致性級別。這些才是定制方案的核心價值所在。
第三,驗技術(shù)更驗經(jīng)驗。找定制開發(fā)服務(wù)商,不僅要看他做過什么,還要問他怎么處理庫存超賣、怎么保證對賬平、晚高峰扛過多少Q(mào)PS。
社區(qū)團(tuán)購的系統(tǒng)定制,本質(zhì)上是在業(yè)務(wù)復(fù)雜度和技術(shù)成本之間找平衡點。沒有最好的架構(gòu),只有最合適的。如果你的業(yè)務(wù)正在從“微信群接龍”走向“數(shù)字化運營”,希望這些經(jīng)驗對你有用。