马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
一、供应商轮转逻辑编写
1.1.供应商轮转
测试对接重试是手动的将对接的返回业务状态码设置称为:StatusCode.ORDER_REQ_FAILED,真实情况下,我们必要根据对接供应商返回的错误信息码来决定充吧系统添加什么类型的任务,所以必要判断对接返回的业务状态码,
步骤1:默认对接聚合,聚合返回的状态码是:StatusCode.BALANCE_NOT_ENOUGH 余额不敷,我们必要轮转下一个供应商:极速
- @Override
- public void recharge(RechargeRequest rechargeRequest) {
- //限制最大重试次数 如果超过了最大次数,停止供应商对接,订单失败---实际业务中是对接订单服务
- if(rechargeRequest.getRepeat() > supplierConfig.getMaxrepeat()){
- updateTrade(rechargeRequest.getOrderNo(), OrderStatusEnum.FAIL.getCode());
- return;
- }
- Result<RechargeResponse> result = doDispatchSupplier(rechargeRequest);
- if(result !=null){
- //需要根据对接返回的业务状态码来确定后续任务的类型及操作逻辑
- if(result.getCode() == StatusCode.BALANCE_NOT_ENOUGH){
- //模拟余额不足 轮转--到极速
- rechargeRequest.setSupply(Constants.jisuapi);
- rechargeRequest.setRepeat(0);
- rechargeRequest.setErrorCode(StatusCode.BALANCE_NOT_ENOUGH);
-
- }else if(result.getCode() == StatusCode.ORDER_REQ_FAILED) {
- //重试逻辑的编写---添加重试任务
- rechargeRequest.setErrorCode(StatusCode.ORDER_REQ_FAILED);
- }
- supplierTask.addRetryTask(rechargeRequest);
-
- }
- }
复制代码
步骤2:添加完轮转任务后,必要去消费轮转任务,在SupplierTaskImpl类中再次添加一个方法用于消费轮转任务,
必要进行方法的改造:在SupplierTaskImpl类中已有一个消费对接重试的任务,消费轮转的任务和重试任务二者之间就是任务的类型取值差别,消费逻辑一样,可抽取
在SupplierTask接口中新增轮转方法- /**
- * 供应商轮转
- */
- public void roundRecharge();
- @Override
- @Scheduled(fixedRate = 1000)
- public void retryRecharge() {
- retry(TaskTypeEnum.ORDER_REQ_FAILED);
- }
复制代码
- @Override
- @Scheduled(fixedRate = 1000)
- public void roundRecharge() {
- retry(TaskTypeEnum.BALANCE_NOT_ENOUGH);
- }
-
- private void retry(TaskTypeEnum taskTypeEnum){
- ResponseMessage responseMessage = taskServiceClient.poll(taskTypeEnum.getTaskType(), taskTypeEnum.getPriority());
- if(responseMessage.isFlag()){
- if(responseMessage.getData() !=null){
- String taskStr = JSON.toJSONString(responseMessage.getData());
- Task task = JSON.parseObject(taskStr,Task.class);
- RechargeRequest rechargeRequest = ProtostuffUtil.deserialize(task.getParameters(), RechargeRequest.class);
- rechargeRequest.setRepeat(rechargeRequest.getRepeat()+1);
- System.out.println("消费了"+taskTypeEnum.getDesc()+"任务,"+rechargeRequest);
- supplierService.recharge(rechargeRequest);
- }
- }
- }
复制代码
步骤3:轮转任务消费后就会去对接极速的接口,我们必要在对接供应商接口实现类:SupplierServiceImpl中完成和极速的对接
对接极速和聚合不一样,聚合要求传递的是JSON格式的数据,而极速要求传递的就是普通表单的key/value数据,并且我们模拟一下请求极速返回错误的情形
- private Result<RechargeResponse> doPostJisu(RechargeRequest rechargeRequest) {
- log.info("doPostJisu,{}",rechargeRequest);
- HttpHeaders headers = new HttpHeaders();
- headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
- //设置表单参数
- MultiValueMap<String, String> map= new LinkedMultiValueMap<String, String>();
- map.add("mobile",rechargeRequest.getMobile());
- map.add("amount",rechargeRequest.getPamt()+"");
- map.add("outorderNo", rechargeRequest.getOrderNo());
- map.add("repeat", ""+rechargeRequest.getRepeat());
-
- //模拟请求失败
- map.add("req_status", ""+StatusCode.ERROR);
- HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<MultiValueMap<String, String>>(map, headers);
- ResponseEntity<String> responseEntity = restTemplate.postForEntity(rechargeRequest.getRechargeUrl(), requestEntity , String.class);
- //转换成统一对象
- Result<RechargeResponse> result= JSON.parseObject(responseEntity.getBody(), new TypeReference<Result<RechargeResponse>>(){});
- return result;
- }
复制代码
步骤4:测试:
依次启动:chongba_schedule_service,chongba_schedule_job,chongba_recharge_web,chongba_recharge_mock,chongba_recharge_supplier
访问:http://localhost:191/,进行话费充值
1.2.供应商排除
默认供应商聚合我们因为余额不敷无法调用,我们是手动编写轮转到极速,在现实业务中,我们系统可能会接许多个供应商,当我们在默认供应商处余额不敷时要从剩下的供应商中选出一个供应商进行对接的调用。此外还需将余额不敷的供应商做一个排除,下次调用时跳过这些供应商
1:轮转时:缓存集成,将那些因为我们系统在对方平台余额不敷的供应商编号缓存到redis中,使用Set集合存储,轮转时获取下一个供应商则直接从供应商配置类中读取所有的供应商所在列表,找出一个作为新的供应商,但得包管不是被排除的
2:与供应商对接前先判断RechargeRequest对象中默认传递过来的供应商是否可用,如果不可用则自动更换供应商。
- @Autowired
- private CacheService cacheService;
- @Override
- public void recharge(RechargeRequest rechargeRequest) {
- //限制最大重试次数 如果超过了最大次数,停止供应商对接,订单失败---实际业务中是对接订单服务
- if(rechargeRequest.getRepeat() > supplierConfig.getMaxrepeat()){
- updateTrade(rechargeRequest.getOrderNo(), OrderStatusEnum.FAIL.getCode());
- return;
- }
- String checkSupply = checkSupply(rechargeRequest.getSupply());
- if(checkSupply!=null){
- rechargeRequest.setSupply(checkSupply);
- }else {
- updateTrade(rechargeRequest.getOrderNo(),OrderStatusEnum.FAIL.getCode());
- return;
- }
- Result<RechargeResponse> result = doDispatchSupplier(rechargeRequest);
- if(result !=null){
-
- 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);
- }
- }
- private String checkSupply(String supply) {
- Set<String> excludes = cacheService.setMembers(Constants.exclude_supplier);
- if(excludes.contains(supply)){
- return nextSupply();
- }else {
- return supply;
- }
- }
- private String nextSupply() {
- Set<String> excludes = cacheService.setMembers(Constants.exclude_supplier);
- Map<String, String> allApis = supplierConfig.getApis();
- for (String supply : allApis.keySet()) {
- if(!excludes.contains(supply)){
- return supply;
- }
- }
- return null;
- }
复制代码
再次启动相干工程进行测似
1.3.供应商恢复
如果我们平台在某些供应商处余额不敷,我们做了供应商排除,每次对接时都会过滤掉该供应商,一般供应商平台会关照我们进行充值,一旦充值成功,该供应商的接口应该恢复调用,因此我们必要提供一个接口用于恢复供应商,即将该供应商编号从缓存redis中的排除名单中删掉即可。
步骤1:在chongba_recharge_supplier模块下创建一个包:com.chongba.supplier.controller,在该包下创建RechargeNotifyController,提供一个供应商恢复的web层接口
- @Slf4j
- @RestController
- public class RechargeNotifyController {
-
- @Autowired
- private CacheService cacheService;
-
- @RequestMapping("/recovery")
- public String recovery(String supply){
- Set<String> excluedes = cacheService.setMembers(Constants.exclude_supplier);
- if(excluedes.contains(supply)){
- cacheService.sRemove(Constants.exclude_supplier,supply);
- return "恢复成功!";
- }else {
- return "供应商编号不存在!";
- }
- }
- }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |