`
hbxflihua
  • 浏览: 660079 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

使用spring-retry实现支付系统异步通知

阅读更多

支付系统异步通知承接上文:DelayQueue实现支付系统异步通知 

本篇介绍通过spring-retry来实现支付系统异步通知功能。

 

1、添加所需的jar

<dependency>
	<groupId>org.springframework.retry</groupId>
	<artifactId>spring-retry</artifactId>
	<version>1.1.2.RELEASE</version>
</dependency>

 2、实现任务重试服务

package com.huatech.service;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.HashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.retry.RetryException;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.EnableRetry;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;

import com.huatech.common.delay.RetMessage;
import com.huatech.common.util.HttpsUtil;
/**
 * 任务重试服务
 * 
 * 	第一次成功则不再重试;
 * 	第一次失败,10分钟后重试第二次;
 * 	第二次失败,20分钟后重试第三次;
 * 	第三次失败,40分钟后重试第四次;
 * 	第四次失败,60分钟后重试第五次;
 * @author lh
 *
 */
//@Configuration
@EnableRetry
@Service
public class TaskRetryService {
	
	
	private static final Logger LOGGER = LoggerFactory.getLogger(TaskRetryService.class);
	
	//返回结果
	private static final String RES_SUCCESS = "success";
	//时间单位:10min
	private static final long TIME_UNIT = 1000 * 60 * 10;
	//重试次数
	private static final int MAX_ATTEMPTS = 5;
	
	 @Retryable(value = {RetryException.class, RuntimeException.class},
	            maxAttempts = MAX_ATTEMPTS,
	            backoff = @Backoff(delay = TIME_UNIT, maxDelay=TIME_UNIT * 6, multiplier= 2 ))
	public void notice(RetMessage msg){
		HashMap<String, String> paramMap = new HashMap<String, String>();
		paramMap.put("reqData", msg.getReqData());
		String httpResult = null;
		try {
			httpResult = HttpsUtil.getInstance().doPostRetString(msg.getUrl(), null, paramMap);
			LOGGER.info("第{}次异步回调,返回结果{},返回参数:{},响应结果:{}", msg.getTimes(), httpResult,
					paramMap.get("reqData"), RES_SUCCESS.equals(httpResult));
			if (!RES_SUCCESS.equals(httpResult)) {
				msg.setTimes(msg.getTimes() + 1);
				msg.setSuccess(false);
				throw new RetryException("retry failed");
			}else{
				msg.setSuccess(true);
			}
		} catch (URISyntaxException | IOException e) {
		}		
	}

}

 

分享到:
评论
2 楼 hbxflihua 2019-01-19  
ivi13 写道
这种方式会有个问题,假如有个商户的交易量特别大,通知全部失败,一段时间内线程数会猛增,会导致系统问题吧

这个问题提的好。通知全部失败还不是最坏的,回调接口地址失效完全可以在方法调用前做一层校验。另外,通知类操作可以独立出一个服务来,即使线程数暴增,也不会影响到其他的业务。最坏的情况其实是回调接口大量失败,这种你做前置校验的意义已经不大了。
1 楼 ivi13 2018-11-20  
这种方式会有个问题,假如有个商户的交易量特别大,通知全部失败,一段时间内线程数会猛增,会导致系统问题吧

相关推荐

Global site tag (gtag.js) - Google Analytics