springboot实现简易的支付对象连接池

        为了实现提高支付对象的连接效果,我通过使用一个定时器来实现一个AlipayClient的简易连接池,当用户正在使用AlipayClient对象进行支付的时候,通过修改连接对象连接池的对象来达到,别人无法使用的效果,保证了支付对象的一对一性,不会出现在同一个时间段内多人同时使用同一个对象。并且通过AtomicInteger来实现在高并发环境下进行计数,达到限流的操作。希望各位大佬留下你们宝贵的意见,使这个来连接池的效果更加明显。

连接对象的封装:

package org.tamall.payservice.config;

import com.alipay.api.AlipayClient;
import lombok.Data;

/**
 * @author Lenovo
 */
@Data
public class PayClientBean {
    //alipay对象
    private AlipayClient alipayClient;
    //是否永久存在(是否为核心对象)
    private Boolean isPermanentSurvival;
    //连接对象状态(0:存活,1:闲置,2:正在使用,3:回收)
    private Integer objectStatus;
    //对象创建时间
    private long createTime;

    public PayClientBean(AlipayClient ac,boolean isPermanentSurvival,Integer state){
        this.alipayClient = ac;
        this.isPermanentSurvival = isPermanentSurvival;
        this.objectStatus = state;
        this.createTime = System.currentTimeMillis();
    }
}

连接池的简易实现:

package org.tamall.payservice.config;

import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import lombok.Setter;
import lombok.extern.log4j.Log4j2;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.tamall.payservice.common.PayClientBeanState;
import org.tamall.payservice.exception.LimException;

import java.util.Objects;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * alipay连接对象池
 * @author Lenovo
 */
@Configuration
@ConfigurationProperties(prefix = "alipay")
@Setter
@Log4j2
public class PayConfig {

    @Resource(name = "createpool")
    ThreadPoolTaskExecutor threadPool;

    //用来存储alipy客户端的连接对象
    private CopyOnWriteArrayList<PayClientBean> coreAlipayClientPool = new CopyOnWriteArrayList<>();

    private String netWorkUrl;
    private String appId;
    //设置私钥
    private String privateKey;
    //公钥
    private String publicKey;
    private String format="json";
    //设置字符类型
    private String chartSet = "UTF-8";
    //设置签名类型
    private String signType="RSA2";
    //链接超时时间
    private int connectionTimeOut = 3000;
    //读取超时时间
    private int  readTimeOut = 1500;
    //设置连接的存货时间
    private int livingTime = 5000;
    //设置默认存在的连接数,默认为5
    private int permanentSurvivalCount = 5;
    //设置最大连接数
    private int maxConnectionCount = 15;
    //定时回收时间,单位(秒)默认3秒进行一次回收
    private long timedRecyclingTime = 3;
    //拒绝服务临界值
    private int rejectServiceCriticalValue = 25;


    //请求个数
    private static AtomicInteger count = new AtomicInteger(0);
    //设置初始化方法
    @PostConstruct
    @Operation(description = "初始化方法")
    private void init(){
        if(rejectServiceCriticalValue < maxConnectionCount){
            throw new IllegalArgumentException("拒绝服务临界值必须大于最大连接数总和");
        }
        System.out.println("=========alipay连接池开始进行加载========");
        for (int i = 0; i < permanentSurvivalCount; i++) {
            threadPool.submit(()->coreAlipayClientPool.add(
                    new PayClientBean(createClient(),true,PayClientBeanState.FREE_STATE)
            ));
        }
        try{
            //启用定时方法
            expirationChecker();
        }catch (Exception e){
            log.error("初始化出现错误");
        }
        System.out.println("=========alipay连接池加载完成========");
    }


    public  PayClientBean getClient(){
        //请求加1,具备线程安全
        count.incrementAndGet();
        if(count.get() > rejectServiceCriticalValue){
            count.decrementAndGet();
            log.error("避免服务器压力过载,拒绝返回请求对象");
            throw new LimException("避免服务器压力过载,拒绝服务");
        }
        int listlen = coreAlipayClientPool.size();
        ReentrantLock lock = new ReentrantLock();
        Condition condition = lock.newCondition();
        //进行加锁,保证线程安全
        lock.lock();
        PayClientBean p = null;
        /*
          判断是否进行阻塞,阻塞条件总的连接数大于等于最大连接数,且所有连接对象处于活动状态
          总的连接数 = 缓存连接数 + 生成的连接数
          */
        if(listlen >= maxConnectionCount &&  isAllActive()){
            DisarmWait disarmWait = new DisarmWait(condition, lock);
            try{
                disarmWait.start();
                log.info("请求进入等待状态");
                condition.await();
            }catch (Exception e){
                log.error("等待出现错误");
                condition.notify();
                lock.unlock();
            }
        }else if(listlen <= maxConnectionCount && querState()){
            log.info("返回空闲对象");
            for (PayClientBean pa :coreAlipayClientPool){
                if(pa.getObjectStatus().equals(PayClientBeanState.FREE_STATE)){
                    pa.setObjectStatus(PayClientBeanState.ACTIVE_STATE);
                    p = pa;
                    break;
                }
            }
        } else {
            log.info("创建新对象");
           p=  new PayClientBean(createClient(),false,PayClientBeanState.ACTIVE_STATE);
           coreAlipayClientPool.add(p);
        }
        lock.unlock();
        return p;
    }
    /**
     * 长时间监听集合,并在满足条件后解除等待,停止线程
     * */

    public class DisarmWait extends Thread{
        private final Condition condition;
        private final ReentrantLock lock;
        public DisarmWait(Condition condition,ReentrantLock lock){
            this.condition  =condition;
            this.lock = lock;
        }
        @Override
        public void run() {
            boolean flg = true;
            while (flg){
                try{
                    //空余位置,重新创建对象,解除等待
                    if(coreAlipayClientPool.size() < maxConnectionCount){
                        log.info("等待结束");
                        lock.lock();
                        try {
                            condition.signal();
                        }catch (Exception e){
                            log.error("结束等待出现异常",e);
                        }finally {
                           lock.unlock();
                        }
                        flg = false;
                    }else{
                        //出现空闲对象,解除等待
                        for (PayClientBean p:coreAlipayClientPool){
                            if(p.getObjectStatus().equals(PayClientBeanState.FREE_STATE)){
                                log.info("等待结束");
                                lock.lock();
                                try {
                                    condition.signal();
                                }catch (Exception e){
                                    log.error("结束等待出现异常",e);
                                }finally {
                                    lock.unlock();
                                }
                                flg = false;
                            }
                        }
                    }
                }catch (Exception e){
                    log.error("等待出现错误",e);
                    flg = false;
                }
            }
        }
    }
    //所有连接对象是否处于使用状态
    public boolean isAllActive(){
        for (PayClientBean p : coreAlipayClientPool){
            if(p.getObjectStatus().equals(PayClientBeanState.ACTIVE_STATE)){
                return true;
            }
        }
        return false;
    }

    //查询对象状态是否为正在使用,如果是返回true,不是返回false
    private boolean querState(){
        for (PayClientBean p : coreAlipayClientPool){
            if(p.getObjectStatus().equals(PayClientBeanState.FREE_STATE)){
                return true;
            }
        }
        return false;
    }

    //对象归还器
    public synchronized void returnObject(PayClientBean p){
        int index = coreAlipayClientPool.lastIndexOf(p);
        /*
          只要不对PayClientBean对象的equal方法进行重写,那么即使创建了一个新的对象,
          也不会在列表中找到对应的索引
          */
        if(index ==-1){
            log.error("对象不存在于集合中");
            throw  new RuntimeException("传入非集合中的对象");
        }
        //归还时减少请求数
        count.decrementAndGet();
        //刷新一次创建时间
        coreAlipayClientPool.get(index).setCreateTime(System.currentTimeMillis());
        coreAlipayClientPool.get(index).setObjectStatus(PayClientBeanState.FREE_STATE);
    }






    @Operation(description = "过期检查器,定时进行回收,不可以被继承和重写")
    private synchronized   void expirationChecker(){
        ScheduledExecutorService scheduledExecutorService= null;
        try{
            scheduledExecutorService = Executors.newScheduledThreadPool(1);
            Runnable task = ()->{
                    coreAlipayClientPool.forEach(e->{
                        //检查是否位空闲状态和非缓存连接,并且已经过期
                        if(e.getObjectStatus().equals(PayClientBeanState.FREE_STATE)
                        && e.getIsPermanentSurvival().equals(false)
                       && System.currentTimeMillis() - e.getCreateTime() >= livingTime){
                            log.info("创建时间,{},当前时间,{}",e.getCreateTime(),System.currentTimeMillis());
                            log.info("回收完成一个支付连接客户端对象!");
                            coreAlipayClientPool.remove(e);
                        }
                    });
            };
            //每两分钟执行一次
            scheduledExecutorService.scheduleWithFixedDelay(task ,0,timedRecyclingTime, TimeUnit.SECONDS);
        }catch (Exception e){
            log.error("创建ScheduledExecutorService出现异常",e);
            if(Objects.isNull(scheduledExecutorService)){
                scheduledExecutorService.shutdown();
            }
        }

    }

    // 用来创建AlipayClient的方法
    @Operation(description = "用于创建一个新的AlipayClient实例对象")
    private AlipayClient createClient() {
        AlipayConfig ap = new AlipayConfig();
        ap.setAlipayPublicKey(publicKey);
        ap.setCharset(chartSet);
        ap.setAppId(appId);
        ap.setConnectTimeout(connectionTimeOut);
        ap.setFormat(format);
        ap.setReadTimeout(readTimeOut);
        ap.setSignType(signType);
        ap.setServerUrl(netWorkUrl);
        ap.setPrivateKey(privateKey);
        ap.setConnectTimeout(connectionTimeOut);
        DefaultAlipayClient defaultAlipayClient =null;
        try{
            defaultAlipayClient  = new DefaultAlipayClient(ap);
        }catch (Exception e){
            log.error("创建连接对象出现错误",e);
        }
        return defaultAlipayClient;
    }




}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吃着烧烤敲代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值