日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁 > 科技  > 軟件

轉(zhuǎn)轉(zhuǎn)游戲的賬號訂單流程重構(gòu)之路

來源: 責(zé)編: 時間:2023-08-20 23:16:42 564觀看
導(dǎo)讀1、背景隨著需求的不斷迭代,項目代碼的復(fù)雜度也會越來越高,“屎山”也一天一天慢慢的堆積起來,對于游戲業(yè)務(wù)的賬號訂單流程也是如此。游戲訂單類型由原來的倆種增加到了現(xiàn)在的七種,早就已經(jīng)到了需要重構(gòu)的地步。但是由于

圖片fwr28資訊網(wǎng)——每日最新資訊28at.com

既然有七種訂單類型,這好辦啊。可以采用策略+模板模式啊,一個抽象模板+七個子類就可以啦。但是后來仔細(xì)一想,如果將所有的處理邏輯都放在父類和子類當(dāng)中,其實代碼整體也顯得十分臃腫。fwr28資訊網(wǎng)——每日最新資訊28at.com

為了想出更好的解決方案,于是對原有代碼和業(yè)務(wù)流程進(jìn)行了深入的梳理和總結(jié),主要有以下幾點:fwr28資訊網(wǎng)——每日最新資訊28at.com

  1. 所有訂單流程都是在客服發(fā)貨和自主發(fā)貨基礎(chǔ)上衍生出來的。
  2. 所有訂單流程都包含下單、支付、上傳賬密、發(fā)貨、確認(rèn)收貨等節(jié)點。
  3. 在這些節(jié)點里不同訂單類型大多會有各自一些特定操作,但是這些操作其實并不屬于訂單的主流程。

通過以上分析,是不是可以將下單到確認(rèn)收貨作為一層,將不同訂單類型的特定處理實現(xiàn)作為一層呢?這樣不就將訂單流程中各種特殊處理從訂單主流程剝離開了嗎,因此最終決定采用三層接口+策略模板的設(shè)計方案。fwr28資訊網(wǎng)——每日最新資訊28at.com

2.2 三層接口+策略模板模式

接口設(shè)計如下:fwr28資訊網(wǎng)——每日最新資訊28at.com

圖片fwr28資訊網(wǎng)——每日最新資訊28at.com

  • 第一層接口

包含前端用戶進(jìn)行交互、處理mq消息以及給其它服務(wù)調(diào)用的接口。fwr28資訊網(wǎng)——每日最新資訊28at.com

  • 第二層接口

訂單核心主流程能力接口。將下單、支付到確認(rèn)收貨等“不變”的基礎(chǔ)能力提供給頂層接口調(diào)用,這層接口有自主發(fā)貨流程和客服發(fā)貨流程兩個實現(xiàn)類。fwr28資訊網(wǎng)——每日最新資訊28at.com

public interface IGameAccountOrderDealProcess {    /**     * 處理下單未支付訂單     */    int handlePlaceOrder(GameAccountOrderContext orderContext) throws Exception;    /**     * 處理支付成功訂單     */    int handlePaySuccessOrder(GameAccountOrderContext orderContext) throws Exception;    /**     * 處理已發(fā)貨訂單     */    int handleDeliverOrder(GameAccountOrderContext orderContext) throws Exception;    /**     * 處理支付前取消訂單     */    int handleCancelBeforePayOrder(GameAccountOrderContext orderContext) throws Exception;    /**     * 處理支付后取消訂單     */    int handleCancelAfterPayOrder(GameAccountOrderContext orderContext) throws Exception;    /**     * 處理交易成功訂單     */    int handleConfirmReceiptOrder(GameAccountOrderContext orderContext) throws Exception;    /**     * 賬號交易窗數(shù)據(jù)     */    <T extends TradeFlowData> T getOrderTradeData(String logStr, Long orderId, Integer device, Long uid);    /**     * 上傳賬密     */    ZZOpenScfBaseResult<String> uploadAccountAndPwd(GameAccountSelfTrade.AccountPwdArg arg, long uid, String logStr, ServiceHeaderEntity header) throws Exception;    /**     * 發(fā)貨     * @param orderContext     */    boolean deliverOrder(GameAccountOrderContext orderContext) throws Exception;    /**     * 訂單確認(rèn)收貨     */    ZZOpenScfBaseResult<String> confirmReceiptOrder(GameAccountOrderContext orderContext, Long uid, boolean needCheckRisk) throws Exception;}
  • 第三層接口

各種訂單類型的特殊處理,每一種訂單模式都對應(yīng)一個實現(xiàn)類。fwr28資訊網(wǎng)——每日最新資訊28at.com

public interface ITradeSelfHandler {    GameAccountTradeFlow.GameAccountTradeType getOrderTrade();    /*------------處理mq消息相關(guān)---------------*/    /**     *1.插入表之前設(shè)置客服和extendInfo     */    void fillExtraOrderInfoBeforeInsert(GameAccountOrderResultEntity orderEntity, GameAccountOrderContext orderContext);    /**     * 下單后處理     */    void handleAfterPlaceOrder(GameAccountOrderContext orderContext);    /**     * 支付前取消處理     */    void handleCancelBeforePay(GameAccountOrderContext orderContext);    /**     * 支付后取消處理     */    int handleCancelAfterPay(GameAccountOrderContext orderContext) throws Exception;    /**     * 支付后一些額外處理     */    int handleAfterPaySuccess(GameAccountOrderContext orderContext);    /**     * 確認(rèn)收貨處理     */    int handleAfterConfirmReceipt(GameAccountOrderContext orderContext) throws Exception;    /*---------------------------------*/    /**     * 獲取提現(xiàn)時間     */    Date getWithDrawlTime();    /**     * 發(fā)送支付成功push     */    void orderAlreadyPayPushMsgNew(GameAccountOrderContext orderContext, Pair<String, String> jumpUrl);    /**     * 獲取分帳賬戶、類別信息     */    List<AccountOrderSplitModel> getOrderSplitModelList(GameAccountOrderContext orderContext, OrderMaxSettleInfo settleInfo);    /**     * 定制各自spiUi     */    void buildOrderSpiUiData(GameAccountOrderContext orderContext, GameOrderSpiConfig bConfig, GameOrderSpiConfig sConfig, SpiUiData spiUiData) throws Exception;    /**     * 確認(rèn)收貨后一些處理     */    void otherOperationAfterReceipt(GameAccountOrderContext orderContext, Long uid);}

2.3 具體實現(xiàn)

  • 核心代碼收攏到一個服務(wù),相關(guān)接口進(jìn)行聚合

原先在客服后臺、定時任務(wù)、mq集群都有一些訂單的操作,但是這些代碼基本都是重復(fù)的,所以此次重構(gòu)在訂單核心服務(wù)中新增相應(yīng)的訂單操作功能,統(tǒng)一由其它服務(wù)進(jìn)行RPC調(diào)用。fwr28資訊網(wǎng)——每日最新資訊28at.com

圖片fwr28資訊網(wǎng)——每日最新資訊28at.com

將訂單相關(guān)的接口、工具類集中到同一個包下,方便定位。fwr28資訊網(wǎng)——每日最新資訊28at.com

圖片fwr28資訊網(wǎng)——每日最新資訊28at.com

  • 整體類圖及設(shè)計原則圖片
  1. 命名規(guī)范:類名、變量名、方法名盡量見名知義。
  2. 單一職責(zé):各個模塊各司其職,避免與其它模塊過度耦合。
  3. 準(zhǔn)備訂單上下文,清除RPC重復(fù)調(diào)用問題。
//上下文實體public class GameAccountOrderContext {    private String logStr;    private Long orderId;    private Integer mqStatus;    private Order order;    private GameAccountOrderResultEntity accountOrderEntity;    private AccountOrderStatusEnum orderStatus;    private Boolean hasInsuranceService;//訂單是否有保險    private GameAccountTradeFlow.GameAccountTradeType tradeType;    private GameAccountProductData accountProductData;    private ZZProduct product;    private ZZProductExt productExt;    private Map<String, String> extValueMap;    private AccountHelpSaleClue helpSaleClue;//幫賣線索    private DistributionShareInfoDTO distributionShareInfo;//分銷信息    private ITradeSelfHandler tradeSelfHandler;    private Integer serviceUiStatus;//對應(yīng)訂單spi狀態(tài)}//上下文準(zhǔn)備GameAccountOrderContext orderContext = orderContextBuilder.buildAccountOrderContext(order, zzProduct, logStr);

3、上線保障

訂單流程不管對于什么業(yè)務(wù),基本都是最重要的一個環(huán)節(jié),為了避免產(chǎn)生重大問題,需要做到以下兩點:fwr28資訊網(wǎng)——每日最新資訊28at.com

  1. 嚴(yán)格保證線下測試的準(zhǔn)確性。
  2. 出現(xiàn)線上問題,影響范圍要盡可能小。

3.1 流程測試

根據(jù)賬號訂單流程的特點,在測試的時候遵循以下原則:fwr28資訊網(wǎng)——每日最新資訊28at.com

  • 訂單流程正常跑通
  • 訂單分帳正確
  • 訂單保險正常
  • 各個節(jié)點與原來保持一致
  • 相關(guān)push、私信正常發(fā)送
  • 統(tǒng)計日志正常打印

對于每一種訂單流程,同時進(jìn)行新、老流程訂單的測試。逐一對比新、老流程的買家側(cè)和賣家側(cè)各個流程節(jié)點的頁面、按鈕、跳轉(zhuǎn)、push、私信等是否保持一致。fwr28資訊網(wǎng)——每日最新資訊28at.com

3.2 灰度策略

為了避免產(chǎn)生重大問題,上線后必須采取灰度策略,不然出了問題就可能就是事故了。本次采用的灰度策略是上線后按訂單類型、訂單量進(jìn)行灰度,同時將灰度訂單落表記錄,配置如下:fwr28資訊網(wǎng)——每日最新資訊28at.com

[  {    "orderType": 6,//訂單類型    "dayNum": 50,//每日灰度量    "isTotalGray": true//是否全量  }] /**  * 判斷訂單是否走新交易流程  */public boolean isNewOrderProcess(String logStr, GameAccountOrderContext orderContext) {        Long orderId = orderContext.getOrderId();        try {            if (gameGrayTestService.isNewTradeProcessOrder(orderId)){                return true;            }            GameAccountOrderResultEntity orderEntity = accountOrderManage.getGameAccountOrderEntity(orderId, logStr);            GameAccountTradeFlow.GameAccountTradeType orderTradeType = orderContext.getTradeType();            String orderRedisSet = String.format("account_order_gray_set_%s_%s", Objects.nonNull(orderEntity) ? orderEntity.getSelfType() : orderTradeType.getSelfType(), DateUtil.format(new Date(), "yyyy-MM-dd"));            if (ZZGameRedisUtil.sismember(orderRedisSet, orderId.toString())){                return true;            }            if (newAccountOrderTradeSwitch){                return true;            }            Optional<OrderGrayConfig> grayConfigOptional = grayConfigList.stream().filter(c->c.getOrderType() == orderTradeType.getSelfType()).findFirst();            if (grayConfigOptional.isPresent()){                OrderGrayConfig grayConfig = grayConfigOptional.get();                if (Objects.nonNull(grayConfig.getIsTotalGray()) && grayConfig.getIsTotalGray()){                    return true;                }                if (orderContext.getOrderStatus() != AccountOrderStatusEnum.place_order){//只處理新訂單                    return false;                }                String dayNumKey = String.format(NEW_ORDER_PROCESS_GRAY_NUM, DateUtil.format(new Date(), "yyyy-MM-dd"), orderTradeType.getSelfType());                if (NumberUtils.toInt(ZZGameRedisUtil.get(dayNumKey)) < grayConfig.getDayNum()){                    int result = gameGrayTestService.insertNewTradeProcessOrder(orderId);                    log.info("{} desc=insert_gray_order_data orderId={} result={}", logStr, orderId, result);                    if (result > 0){                        ZZGameRedisUtil.increAndGet(dayNumKey, 1);                        ZZGameRedisUtil.expire(dayNumKey, 3600*24);                        ZZGameRedisUtil.sadd(orderRedisSet, orderId.toString());                        ZZGameRedisUtil.expire(orderRedisSet, 3600*24);                    }                    return result >= 0;                }                return false;            }        } catch (Exception e) {            log.error("{} desc=isNewOrderProcess_error orderId={}", orderContext.getLogStr(), orderContext.getOrderId(), e);        }        return false;}

3.3 異常機(jī)制

在一些重要的節(jié)點設(shè)置告警機(jī)制,比如上傳賬密、發(fā)貨、提現(xiàn)等節(jié)點出現(xiàn)異常時會發(fā)送企業(yè)微信告警通知,可以第一時間關(guān)閉灰度,查找問題。fwr28資訊網(wǎng)——每日最新資訊28at.com

圖片fwr28資訊網(wǎng)——每日最新資訊28at.com

不過對于分帳正確性保障這塊只是通過測試確保正確,這種最好是可以接入中臺的BCP(Business Check Platform)系統(tǒng)。它是一種標(biāo)準(zhǔn)化數(shù)據(jù)校對平臺,支持標(biāo)準(zhǔn)化數(shù)據(jù)源接入,基于事件觸發(fā)規(guī)則執(zhí)行,進(jìn)行業(yè)務(wù)數(shù)據(jù)校對,可以及時快速的發(fā)現(xiàn)業(yè)務(wù)異常數(shù)據(jù)并實時告警。fwr28資訊網(wǎng)——每日最新資訊28at.com

4 總結(jié)

在對訂單流程進(jìn)行重構(gòu)之后,新增或修改某種訂單模式,只需增改相應(yīng)的訂單類型處理類就可以了,也不用擔(dān)心本次修改會影響到其它的訂單模式,大大提高了開發(fā)效率。此外,重構(gòu)代碼可以幫助我們進(jìn)一步深入了解整個業(yè)務(wù)流程,發(fā)現(xiàn)代碼的壞味道,提升代碼結(jié)構(gòu)設(shè)計能力。fwr28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-6161-0.html轉(zhuǎn)轉(zhuǎn)游戲的賬號訂單流程重構(gòu)之路

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 谷歌的Project IDX會扼殺其他應(yīng)用程序開發(fā)框架嗎?

下一篇: 基于模塊聯(lián)邦與大倉模式的商家巨石應(yīng)用拆分實踐

標(biāo)簽:
  • 熱門焦點
  • 影音體驗是真的強(qiáng) 簡單聊聊iQOO Pad

    大公司的好處就是產(chǎn)品線豐富,非常細(xì)分化的東西也能給你做出來,例如早先我們看到了新的vivo Pad2,之后我們又在iQOO Neo8 Pro的發(fā)布會上看到了iQOO的首款平板產(chǎn)品iQOO Pad。雖
  • Automa-通過連接塊來自動化你的瀏覽器

    1、前言通過瀏覽器插件可實現(xiàn)自動化腳本的錄制與編寫,具有代表性的工具就是:Selenium IDE、Katalon Recorder,對于簡單的業(yè)務(wù)來說可快速實現(xiàn)自動化的上手工作。Selenium IDEKat
  • 三言兩語說透柯里化和反柯里化

    JavaScript中的柯里化(Currying)和反柯里化(Uncurrying)是兩種很有用的技術(shù),可以幫助我們寫出更加優(yōu)雅、泛用的函數(shù)。本文將首先介紹柯里化和反柯里化的概念、實現(xiàn)原理和應(yīng)用
  • Python異步IO編程的進(jìn)程/線程通信實現(xiàn)

    這篇文章再講3種方式,同時講4中進(jìn)程間通信的方式一、 Python 中線程間通信的實現(xiàn)方式共享變量共享變量是多個線程可以共同訪問的變量。在Python中,可以使用threading模塊中的L
  • 小紅書1周漲粉49W+,我總結(jié)了小白可以用的N條漲粉筆記

    作者:黃河懂運營一條性教育視頻,被54萬人&ldquo;珍藏&rdquo;是什么體驗?最近,情感博主@公主是用鮮花做的,火了!僅僅憑借一條視頻,光小紅書就有超過128萬人,為她瘋狂點贊!更瘋狂的是,這
  • 拼多多APP上線本地生活入口,群雄逐鹿萬億市場

    Tech星球(微信ID:tech618)文 | 陳橋輝 Tech星球獨家獲悉,拼多多在其APP內(nèi)上線了&ldquo;本地生活&rdquo;入口,位置較深,位于首頁的&ldquo;充值中心&rdquo;內(nèi),目前主要售賣美食相關(guān)的
  • 認(rèn)真聊聊東方甄選:如何告別低垂的果實

    來源:山核桃作者:財經(jīng)無忌爆火一年后,俞敏洪和他的東方甄選依舊是頗受外界關(guān)心的&ldquo;網(wǎng)紅&rdquo;。7月5日至9日,為期5天的東方甄選&ldquo;甘肅行&rdquo;首次在自有App內(nèi)直播,
  • 朋友圈可以修改可見范圍了 蘋果用戶可率先體驗

    近日,iOS用戶迎來微信8.0.27正式版更新,除了可更換二維碼背景外,還新增了多項實用功能。在新版微信中,朋友圈終于可以修改可見范圍,簡單來說就是已發(fā)布的朋友圈
  • 中關(guān)村論壇11月25日開幕,15位諾獎級大咖將發(fā)表演講

    11月18日,記者從2022中關(guān)村論壇新聞發(fā)布會上獲悉,中關(guān)村論壇將于11月25至30日在京舉行。本屆中關(guān)村論壇由科學(xué)技術(shù)部、國家發(fā)展改革委、工業(yè)和信息化部、國務(wù)
Top 主站蜘蛛池模板: 屯留县| 衡阳市| 于都县| 福建省| 老河口市| 贡觉县| 新邵县| 新巴尔虎左旗| 于田县| 祥云县| 濮阳县| 东乌| 确山县| 祁连县| 如皋市| 宾阳县| 湟源县| 邮箱| 乐平市| 新兴县| 马尔康县| 怀来县| 巩义市| 六枝特区| 五家渠市| 江北区| 利川市| 南雄市| 百色市| 沙洋县| 永嘉县| 仁寿县| 蒲江县| 黄梅县| 叙永县| 郯城县| 闽侯县| 轮台县| 日照市| 保定市| 民权县|