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

當前位置:首頁 > 科技  > 軟件

轉轉游戲的賬號訂單流程重構之路

來源: 責編: 時間:2023-08-20 23:16:42 629觀看
導讀1、背景隨著需求的不斷迭代,項目代碼的復雜度也會越來越高,“屎山”也一天一天慢慢的堆積起來,對于游戲業務的賬號訂單流程也是如此。游戲訂單類型由原來的倆種增加到了現在的七種,早就已經到了需要重構的地步。但是由于

圖片kU928資訊網——每日最新資訊28at.com

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

為了想出更好的解決方案,于是對原有代碼和業務流程進行了深入的梳理和總結,主要有以下幾點:kU928資訊網——每日最新資訊28at.com

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

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

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

接口設計如下:kU928資訊網——每日最新資訊28at.com

圖片kU928資訊網——每日最新資訊28at.com

  • 第一層接口

包含前端用戶進行交互、處理mq消息以及給其它服務調用的接口。kU928資訊網——每日最新資訊28at.com

  • 第二層接口

訂單核心主流程能力接口。將下單、支付到確認收貨等“不變”的基礎能力提供給頂層接口調用,這層接口有自主發貨流程和客服發貨流程兩個實現類。kU928資訊網——每日最新資訊28at.com

public interface IGameAccountOrderDealProcess {    /**     * 處理下單未支付訂單     */    int handlePlaceOrder(GameAccountOrderContext orderContext) throws Exception;    /**     * 處理支付成功訂單     */    int handlePaySuccessOrder(GameAccountOrderContext orderContext) throws Exception;    /**     * 處理已發貨訂單     */    int handleDeliverOrder(GameAccountOrderContext orderContext) throws Exception;    /**     * 處理支付前取消訂單     */    int handleCancelBeforePayOrder(GameAccountOrderContext orderContext) throws Exception;    /**     * 處理支付后取消訂單     */    int handleCancelAfterPayOrder(GameAccountOrderContext orderContext) throws Exception;    /**     * 處理交易成功訂單     */    int handleConfirmReceiptOrder(GameAccountOrderContext orderContext) throws Exception;    /**     * 賬號交易窗數據     */    <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;    /**     * 發貨     * @param orderContext     */    boolean deliverOrder(GameAccountOrderContext orderContext) throws Exception;    /**     * 訂單確認收貨     */    ZZOpenScfBaseResult<String> confirmReceiptOrder(GameAccountOrderContext orderContext, Long uid, boolean needCheckRisk) throws Exception;}
  • 第三層接口

各種訂單類型的特殊處理,每一種訂單模式都對應一個實現類。kU928資訊網——每日最新資訊28at.com

public interface ITradeSelfHandler {    GameAccountTradeFlow.GameAccountTradeType getOrderTrade();    /*------------處理mq消息相關---------------*/    /**     *1.插入表之前設置客服和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);    /**     * 確認收貨處理     */    int handleAfterConfirmReceipt(GameAccountOrderContext orderContext) throws Exception;    /*---------------------------------*/    /**     * 獲取提現時間     */    Date getWithDrawlTime();    /**     * 發送支付成功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;    /**     * 確認收貨后一些處理     */    void otherOperationAfterReceipt(GameAccountOrderContext orderContext, Long uid);}

2.3 具體實現

  • 核心代碼收攏到一個服務,相關接口進行聚合

原先在客服后臺、定時任務、mq集群都有一些訂單的操作,但是這些代碼基本都是重復的,所以此次重構在訂單核心服務中新增相應的訂單操作功能,統一由其它服務進行RPC調用。kU928資訊網——每日最新資訊28at.com

圖片kU928資訊網——每日最新資訊28at.com

將訂單相關的接口、工具類集中到同一個包下,方便定位。kU928資訊網——每日最新資訊28at.com

圖片kU928資訊網——每日最新資訊28at.com

  • 整體類圖及設計原則圖片
  1. 命名規范:類名、變量名、方法名盡量見名知義。
  2. 單一職責:各個模塊各司其職,避免與其它模塊過度耦合。
  3. 準備訂單上下文,清除RPC重復調用問題。
//上下文實體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;//對應訂單spi狀態}//上下文準備GameAccountOrderContext orderContext = orderContextBuilder.buildAccountOrderContext(order, zzProduct, logStr);

3、上線保障

訂單流程不管對于什么業務,基本都是最重要的一個環節,為了避免產生重大問題,需要做到以下兩點:kU928資訊網——每日最新資訊28at.com

  1. 嚴格保證線下測試的準確性。
  2. 出現線上問題,影響范圍要盡可能小。

3.1 流程測試

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

  • 訂單流程正常跑通
  • 訂單分帳正確
  • 訂單保險正常
  • 各個節點與原來保持一致
  • 相關push、私信正常發送
  • 統計日志正常打印

對于每一種訂單流程,同時進行新、老流程訂單的測試。逐一對比新、老流程的買家側和賣家側各個流程節點的頁面、按鈕、跳轉、push、私信等是否保持一致。kU928資訊網——每日最新資訊28at.com

3.2 灰度策略

為了避免產生重大問題,上線后必須采取灰度策略,不然出了問題就可能就是事故了。本次采用的灰度策略是上線后按訂單類型、訂單量進行灰度,同時將灰度訂單落表記錄,配置如下:kU928資訊網——每日最新資訊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 異常機制

在一些重要的節點設置告警機制,比如上傳賬密、發貨、提現等節點出現異常時會發送企業微信告警通知,可以第一時間關閉灰度,查找問題。kU928資訊網——每日最新資訊28at.com

圖片kU928資訊網——每日最新資訊28at.com

不過對于分帳正確性保障這塊只是通過測試確保正確,這種最好是可以接入中臺的BCP(Business Check Platform)系統。它是一種標準化數據校對平臺,支持標準化數據源接入,基于事件觸發規則執行,進行業務數據校對,可以及時快速的發現業務異常數據并實時告警。kU928資訊網——每日最新資訊28at.com

4 總結

在對訂單流程進行重構之后,新增或修改某種訂單模式,只需增改相應的訂單類型處理類就可以了,也不用擔心本次修改會影響到其它的訂單模式,大大提高了開發效率。此外,重構代碼可以幫助我們進一步深入了解整個業務流程,發現代碼的壞味道,提升代碼結構設計能力。kU928資訊網——每日最新資訊28at.com

本文鏈接:http://m.www897cc.com/showinfo-26-6161-0.html轉轉游戲的賬號訂單流程重構之路

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

上一篇: 谷歌的Project IDX會扼殺其他應用程序開發框架嗎?

下一篇: 基于模塊聯邦與大倉模式的商家巨石應用拆分實踐

標簽:
  • 熱門焦點
Top 日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不
欧美黄色一区| 亚洲性感激情| 国产日韩在线看| 国产情侣久久| 黄色国产精品一区二区三区| 尤物99国产成人精品视频| 亚洲日韩第九十九页| 中国亚洲黄色| 久久精品国产免费| …久久精品99久久香蕉国产 | 狠狠色丁香婷综合久久| 亚洲国产精品999| 一区二区三区精品视频| 欧美一站二站| 欧美精品在线观看播放| 国产欧美va欧美不卡在线| 亚洲第一中文字幕在线观看| 一区二区精品在线| 欧美在线日韩在线| 欧美极品在线视频| 国产农村妇女精品| 亚洲日本中文字幕区| 性色av一区二区三区在线观看| 麻豆精品国产91久久久久久| 欧美视频一区二区在线观看 | 亚洲高清视频在线| 亚洲一区二区少妇| 免费视频一区| 国产欧美日韩专区发布| 亚洲美女淫视频| 久久久久看片| 99视频精品全国免费| 欧美中文字幕视频在线观看| 欧美人在线视频| 欧美日韩综合视频| 在线播放中文字幕一区| 亚洲一区二区三区精品动漫| 另类亚洲自拍| 国产精品天天摸av网| 国产精品天天看| 亚洲黄网站黄| 欧美一区网站| 欧美色偷偷大香| 欧美午夜精彩| 在线激情影院一区| 亚洲黄色在线视频| 欧美一级在线视频| 欧美人妖在线观看| 在线观看成人av电影| 性视频1819p久久| 久久精品天堂| 99综合在线| 美女福利精品视频| 国产一区二区高清视频| 亚洲午夜三级在线| 欧美另类专区| 亚洲国产精品电影在线观看| 欧美专区日韩视频| 国产精品美女一区二区| 一本久道久久综合婷婷鲸鱼| 欧美岛国激情| 亚洲电影免费在线| 可以看av的网站久久看| 国产亚洲欧洲一区高清在线观看 | 久久综合999| 国产一区二区三区在线播放免费观看| 亚洲一区二区在线播放| 欧美日韩一卡| 一本大道久久a久久精品综合| 欧美激情精品久久久久久变态| 在线成人中文字幕| 久久综合色天天久久综合图片| 国产综合久久久久影院| 欧美综合国产| 国产亚洲福利| 欧美一级视频精品观看| 国产精品午夜久久| 亚洲欧洲av一区二区三区久久| 国产精品久久久久免费a∨| 亚洲视频在线观看视频| 欧美日韩一卡二卡| 中国亚洲黄色| 国产精品老牛| 午夜精品久久久久久久| 国产美女精品视频免费观看| 午夜精品久久久久久久99热浪潮| 国产精品一区二区久久国产| 亚洲欧美久久久| 久久综合伊人77777| 国产在线不卡精品| 久久久www成人免费无遮挡大片| 国产综合欧美| 久久躁狠狠躁夜夜爽| 亚洲电影免费在线观看| 欧美顶级少妇做爰| 日韩视频在线一区二区| 欧美天堂在线观看| 国产精品视频在线观看| 性久久久久久久久| 国产一区二区三区四区在线观看| 最新国产成人在线观看| 欧美高清影院| 99精品视频免费| 欧美天堂亚洲电影院在线播放| 亚洲影视在线播放| 国产亚洲观看| 久久综合久色欧美综合狠狠| 亚洲黄一区二区| 欧美日韩你懂的| 亚洲女ⅴideoshd黑人| 欧美巨乳在线观看| 一区二区高清视频在线观看| 国产精品免费看久久久香蕉| 欧美中文在线观看| 精品电影在线观看| 欧美精品一区二区精品网| 在线一区二区三区四区五区| 国产精品一区二区三区免费观看| 久久精品观看| 亚洲青涩在线| 国产精品美女久久久久久久| 久久看片网站| 亚洲伦理久久| 美女精品国产| 日韩一区二区精品视频| 国产精品免费区二区三区观看| 久久精品伊人| 亚洲精品一区久久久久久| 国产精品你懂得| 免费成人av资源网| 亚洲一区二区在| 在线观看久久av| 99亚洲一区二区| 美日韩精品视频| 一区二区三区视频在线| 国产一区二区三区久久| 亚洲国内自拍| 国产精品久久一区主播| 久久婷婷国产综合尤物精品| 9色国产精品| 韩国三级在线一区| 欧美日韩一区二区三区高清| 久久久91精品国产| 宅男精品视频| 亚洲第一在线| 国产农村妇女毛片精品久久莱园子| 欧美成人免费在线视频| 亚洲欧洲在线看| 国产精品久久久久久久久婷婷 | 亚洲一区视频在线| 在线看片一区| 国产精品自拍小视频| 欧美福利电影网| 久久www成人_看片免费不卡 | 媚黑女一区二区| 午夜精品婷婷| 国产专区欧美专区| 欧美精品一区二区三区很污很色的| 欧美中文在线字幕| 亚洲香蕉成视频在线观看| 亚洲风情亚aⅴ在线发布| 国产欧美一区二区精品仙草咪| 欧美日本在线看| 老牛嫩草一区二区三区日本| 亚洲男人的天堂在线| 欧美人与禽性xxxxx杂性| 亚洲欧美综合v| 亚洲人成网站影音先锋播放| 国产亚洲精品aa| 欧美天天影院| 欧美3dxxxxhd| 久久成人综合网| 亚洲一二三级电影| 日韩视频在线永久播放| 一区二区视频免费完整版观看| 国产精品麻豆欧美日韩ww| 欧美精品国产| 麻豆91精品91久久久的内涵| 亚洲欧美视频一区二区三区| 99热在这里有精品免费| 亚洲国产一区二区在线| 伊人婷婷久久| 国产自产精品| 国产视频综合在线| 另类天堂av| 久久精品一区二区三区不卡牛牛 | 欧美本精品男人aⅴ天堂| 99天天综合性| 亚洲国产精品99久久久久久久久| 国模一区二区三区| 国产人成精品一区二区三| 国产精品美女主播在线观看纯欲| 欧美日韩一区二区三区四区五区| 欧美激情乱人伦| 欧美韩国日本一区| 中文国产一区| 9色国产精品| 日韩视频精品在线观看| 亚洲日韩第九十九页| 欧美日韩一区三区四区| 欧美日本视频在线| 欧美精品一区二区三区在线播放| 欧美阿v一级看视频| 国产午夜精品视频免费不卡69堂|