• ConcurrentLinkedQueue数字货币钱包使用案例


    package cc.zeelan.resources.helper.queue;
    
    import java.util.Iterator;
    import java.util.concurrent.ConcurrentLinkedQueue;
    
    import org.springframework.scheduling.annotation.Scheduled;
    import org.springframework.stereotype.Component;
    
    import cc.zeelan.resources.om.transaction.TranctionOrder;
    import cn.hutool.core.lang.Validator;
    import cn.hutool.core.thread.ThreadUtil;
    import cn.hutool.core.util.ObjectUtil;
    import cn.hutool.http.HttpRequest;
    import cn.hutool.http.HttpResponse;
    import cn.hutool.json.JSONUtil;
    
    /**
     * 队列推送订单通知
     */
    @Component
    public class QueueNotifyHelper {
    	/**
    	 * 推送请求最大请求错误超过5次,则抛弃该推送
    	 */
    	private static final int max_counter = 5;
    	/**
    	 * 请求超时
    	 */
    	private static final int time_out = 3000;
    	/**
    	 * 该队列是一个基于链接节点的无界线程安全队列,它采用先进先出的规则对节点进行排序
    	 */
    	private static ConcurrentLinkedQueue<TranctionOrder> queue = new ConcurrentLinkedQueue<TranctionOrder>();
    
    	/**
    	 * 添加到队列
    	 */
    	public static void offer(TranctionOrder order) {
    		queue.offer(order);
    	}
    
    	@Scheduled(cron = "0/5 * * * * ?")
    	public void push() {
    		Iterator<TranctionOrder> iterator = queue.iterator();
    		while (iterator.hasNext()) {
    			TranctionOrder queueOrder = iterator.next();
    			if (ObjectUtil.isNotNull(queueOrder) && Validator.isUrl(queueOrder.getNotifyUrl())) {// 当队列元素不为空
    				ThreadUtil.execAsync(new Runnable() {// 防止远程推送请求,队列阻塞
    					@Override
    					public void run() {
    						notifyService(queueOrder.getNotifyUrl(), queueOrder);
    					}
    				});
    			}
    		}
    	}
    
    	/**
    	 * 推送服务
    	 * 
    	 * @see 因为线程,可能会超出max_counter的数量,但不影响后续业务,所以不需要加锁
    	 * @param notifyUrl 通知URL
    	 * @param order     预支付订单
    	 */
    	private void notifyService(String notifyUrl, TranctionOrder order) {
    		HttpResponse r = HttpRequest.post(notifyUrl).body(JSONUtil.toJsonStr(order)).timeout(time_out).execute().sync();
    		if (r.isOk()) {// 当请求成功之后,从队列当中移出该元素
    			queue.remove(order);
    		} else {// 请求失败,放回队列进行补偿操作
    			order.setCounter(Math.addExact(order.getCounter(), 1));
    			if (order.getCounter() > max_counter) {// 当错误超过五次,则放弃推送,
    				queue.remove(order);
    			} else {// 添加到队列,继续推送
    				offer(order);
    			}
    		}
    	}
    }
    

      

  • 相关阅读:
    服务器性能调优(netstat监控大量ESTABLISHED连接与Time_Wait连接问题)
    maven/gredle配置阿里云仓库镜像,加速下载maven依赖
    Mac文件上传下载到服务器指定命令
    mysql-管理命令【创建用户、授权、修改密码、删除用户和授权、忘记root密码】
    springmvc返回不带引号的字符串
    maven过滤配置文件
    git常用命令/git 部分高级命令备忘录
    SpringBoot中使用Fastjson/Jackson对JSON序列化格式化输出的若干问题
    修改mysql配置中my.conf中max_allowed_packet变量
    ZK安装、ZK配置、ZK集群部署踩过的大坑
  • 原文地址:https://www.cnblogs.com/light-zhang/p/15200349.html
Copyright © 2020-2023  润新知