一、網絡異常重試邏輯編寫
如果在對接供應商的過程中出現了網絡異常,我們需要做一個補償機制,在任務類型枚舉類:TaskTypeEnum中有一種業務狀態碼是針對遠程調用失敗的
步驟一:在對接供應商的方法:SupplierServiceImpl類中的recharge方法中,對調用供應商的代碼塊加上try{}catch{},捕獲到異常后,添加重試任務,任務類型枚舉為:TaskTypeEnum.REMOTEERROR,業務狀態碼為:StatusCode.REMOTEERROR
@Override
public void recharge(RechargeRequest rechargeRequest) {//.......................前面的代碼省略Result<RechargeResponse> result = null;try {result = doDispatchSupplier(rechargeRequest);} catch (Exception e) {log.error("recharge exception ,{}",e.getMessage());//添加遠程調用重試任務rechargeRequest.setErrorCode(StatusCode.REMOTEERROR);supplierTask.addRetryTask(rechargeRequest);return;}if(result !=null){//判斷成功還是失敗if(result.getCode() == StatusCode.OK){log.info("下單成功,等待充值處理回調!");//特別注意此時訂單狀態還不能修改為充值成功-----供應商回調之后才能修改為成功updateTrade(rechargeRequest.getOrderNo(),OrderStatusEnum.UNAFFIRM.getCode());//充值處理中等待確認return;}else {//失敗就分好幾種:余額不足輪轉 下單失敗重試等if(result.getCode() == StatusCode.BALANCE_NOT_ENOUGH){//模擬余額不足 輪轉--到極速/* rechargeRequest.setSupply(Constants.jisuapi);rechargeRequest.setRepeat(0);rechargeRequest.setErrorCode(StatusCode.BALANCE_NOT_ENOUGH);*///將我們余額不足的供應商放入reids 排除集合中cacheService.sAdd(Constants.exclude_supplier,rechargeRequest.getSupply());String nextSupply = nextSupply();System.out.println("輪轉到新的供應商為:"+nextSupply);if(nextSupply !=null){rechargeRequest.setSupply(nextSupply);rechargeRequest.setRepeat(0);rechargeRequest.setErrorCode(StatusCode.BALANCE_NOT_ENOUGH);}else {//沒有供應商了updateTrade(rechargeRequest.getOrderNo(),OrderStatusEnum.FAIL.getCode());return;}}else if(result.getCode() == StatusCode.ORDER_REQ_FAILED) {//重試邏輯的編寫---添加重試任務rechargeRequest.setErrorCode(StatusCode.ORDER_REQ_FAILED);}supplierTask.addRetryTask(rechargeRequest);}}
}
步驟二:在供應商任務接口SupplierTask中添加遠程調用異常重試方法:rechargeException
/*** 遠程調用異常重試*/public void rechargeException();
步驟三:實現遠程調用重試方法
@Override
@Scheduled(fixedRate = 1000)
public void rechargeException() {retry(TaskTypeEnum.REMOTEERROR);
}
步驟四:測試:除了chongba_recharge_mock不啟動之外,其他都啟動,進行話費充值,模擬遠程調用失敗場景。
二、供應商話費充值成功邏輯編寫
對接調用成功后我們需要將訂單狀態改為處理中,一段時間后供應商會回調我們系統,我們需要做的就是更改訂單狀態為充值成功。
步驟一:模擬對接極速成功的情況,在SupplierServiceImpl類中的方法doPostJisu(RechargeRequest rechargeRequest)中,模擬極速返回成功
//map.add("req_status", ""+StatusCode.ERROR);
map.add("req_status", ""+StatusCode.OK);
步驟二:對接下單方法: recharge(RechargeRequest rechargeRequest)邏輯修改,添加對接成功的判斷,目前都是失敗的情況
判斷對接返回的Result結果中的業務狀態碼,如果是成功的就對接訂單修改訂單狀態為處理中,否則就是目前的一些異常邏輯
@Override
public void recharge(RechargeRequest rechargeRequest) {//.................前面的省略Result<RechargeResponse> result = null;try {result = doDispatchSupplier(rechargeRequest);} catch (Exception e) {log.error("recharge exception ,{}",e.getMessage());//添加遠程調用重試任務rechargeRequest.setErrorCode(StatusCode.REMOTEERROR);supplierTask.addRetryTask(rechargeRequest);return;}if(result !=null){//判斷成功還是失敗if(result.getCode() == StatusCode.OK){log.info("下單成功,等待充值處理回調!");//特別注意此時訂單狀態還不能修改為充值成功-----供應商回調之后才能修改為成功updateTrade(rechargeRequest.getOrderNo(),OrderStatusEnum.UNAFFIRM.getCode());//充值處理中等待確認return;}else {//失敗就分好幾種:余額不足輪轉 下單失敗重試等if(result.getCode() == StatusCode.BALANCE_NOT_ENOUGH){//模擬余額不足 輪轉--到極速/* rechargeRequest.setSupply(Constants.jisuapi);rechargeRequest.setRepeat(0);rechargeRequest.setErrorCode(StatusCode.BALANCE_NOT_ENOUGH);*///將我們余額不足的供應商放入reids 排除集合中cacheService.sAdd(Constants.exclude_supplier,rechargeRequest.getSupply());String nextSupply = nextSupply();System.out.println("輪轉到新的供應商為:"+nextSupply);if(nextSupply !=null){rechargeRequest.setSupply(nextSupply);rechargeRequest.setRepeat(0);rechargeRequest.setErrorCode(StatusCode.BALANCE_NOT_ENOUGH);}else {//沒有供應商了updateTrade(rechargeRequest.getOrderNo(),OrderStatusEnum.FAIL.getCode());return;}}else if(result.getCode() == StatusCode.ORDER_REQ_FAILED) {//重試邏輯的編寫---添加重試任務rechargeRequest.setErrorCode(StatusCode.ORDER_REQ_FAILED);}supplierTask.addRetryTask(rechargeRequest);}}
}
步驟三:成功后極速平臺會進行一個回調,在chongba_recharge_mock模塊中的MockJisuRechargeController中的add方法,回調充吧系統,回調方法在該模塊下的BaseController中:rechargeNotify
實際業務中是充吧系統在供應商平臺進行配置,回調地址為:
notify-url: http://127.0.0.1:99/order/notify
需要在chongba_recharge_supplier模塊的RechargeNotifyController類中補全接收回調的方法,在實際業務中是調用訂單的服務處理訂單狀態。
@Autowired
protected OrderTradeMapper orderTradeMapper;
?
@RequestMapping(value = "/order/notify")
public String notify(@RequestBody String result) {JSONObject jsonObject = (JSONObject) JSON.parse(result);String orderNo= (String) jsonObject.get("orderNo");int status= Integer.parseInt(jsonObject.get("status").toString());log.info("充值回調成功修改訂單{}的狀態為{}",orderNo,status);updateTrade(orderNo, status);return "sucess";
}
?
private void updateTrade(String orderNo, int orderStatus) {//修改訂單狀態QueryWrapper<OrderTrade> queryWrapper = new QueryWrapper<>();queryWrapper.eq("order_no", orderNo);OrderTrade orderTrade = orderTradeMapper.selectOne(queryWrapper);if(orderTrade!=null) {orderTrade.setOrderStatus(orderStatus);orderTradeMapper.update(orderTrade, queryWrapper);}
}
步驟四:測試
啟動所有工程,進行話費充值業務,充值成功后進入訂單列表,查看訂單狀態,因為目前的邏輯是供應商5秒后回調我們系統,所以5秒后刷新一下訂單列表頁面,查看訂單狀態已改變。