统计事件分发情况

package com.nuzar.fcms.framework.bizevent.dto;

import org.apache.commons.lang3.time.DateUtils;

import java.time.Clock;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 事件分发统计
 */
public class BizEventDistStat {
    
    private AtomicInteger remainingDistTotal;
    
    private Long eventId;
    
    private long beginTime;

    public BizEventDistStat(Long eventId, int expectTotal){
        this.eventId = eventId;
        this.remainingDistTotal = new AtomicInteger(expectTotal);
        this.beginTime = Clock.systemUTC().millis();
    }

    public Long getEventId(){
        return this.eventId;
    }
    
    /**
     * 完成一次处理,剩余数量扣减一次
     */
    public void completeOnce() {
        this.remainingDistTotal.decrementAndGet();
    }

    /**
     * 所有分发都完成了 true
     * @return
     */
    public boolean hasAllCompleted(){
        return this.remainingDistTotal.get() <= 0;
    }

    /**
     * 经过了多少时间
     * @return
     */
    public long elapsedMillisTime(){
        return Clock.systemUTC().millis() - this.beginTime;
    }

    @Override public String toString() {
        return "BizEventDistStat{remainingDistTotal=" + remainingDistTotal + ", eventId=" + eventId
                + ", beginTime=" + beginTime + '}';
    }
}
package com.nuzar.fcms.framework.bizevent.service;

import com.nuzar.fcms.framework.bizevent.config.BizEventProperties;
import com.nuzar.fcms.framework.bizevent.constant.BizFlowEventRecordStatusEnum;
import com.nuzar.fcms.framework.bizevent.dto.BizEventDistStat;
import com.nuzar.fcms.framework.bizevent.model.BizFlowEventRecord;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;

/**
 * 客户端事件分发管道处理器,各个客户端对事件进行选择构建分发事件
 */
@Slf4j
public class AppClientEventDistPipelineProcessor implements InitializingBean {
    
    @Resource IBizFlowEventRecordService bizFlowEventRecordService;
     
    @Resource ClientEventProcessManager clientEventProcessManager;

    @Resource BizEventProperties bizEventProperties;
    
    // 统计事件分发情况,根据分发情况进行事件状态的更新
    private LinkedBlockingQueue<BizEventDistStat> bizEventDistStatQueue;

    public void handle(BizFlowEventRecord event) throws InterruptedException {
        // 根据eventType获取当前关注该事件的所有客户端处理列表
        List<ClientEventProcessor> processors = clientEventProcessManager.getProcessorsByEventType(event.getEventType());
        BizEventDistStat eventDistStat = new BizEventDistStat(event.getId(), processors.size());
        bizEventDistStatQueue.put(eventDistStat);
        processors.forEach(proc ->{
                proc.offerEvent(event, eventDistStat);
        });
        
    }

    @Override public void afterPropertiesSet() throws Exception {
        this.bizEventDistStatQueue = new LinkedBlockingQueue<>(this.bizEventProperties.getBizEventDistStatQueueCapacity());
        Thread distStatThread = new Thread(() -> {
            for(;;){
                try {
                    BizEventDistStat stat = bizEventDistStatQueue.take(); // when empty then wait next event
                    if(stat.hasAllCompleted()){
                        //在什么条件下才更新完成? 当订阅当前事件的处理器数量与分发消息完成数一致时(剩余分发总数为0),则认为分发完成
                        bizFlowEventRecordService.updateEventStatus(bizFlowEventRecordService.getById(stat.getEventId()), 
                                BizFlowEventRecordStatusEnum.COMPLETED);
                    }else if(stat.elapsedMillisTime() < bizEventProperties.getDistStatLimitElapsedMillis()){
                        // 没有完成,在监控有效时间内,继续监控
                        bizEventDistStatQueue.put(stat);
                    }else{
                        // 事件为处理中状态,需要排查,不再监控
                        log.error("监控到超时分发的事件记录:{}", stat);
                    }
                }catch(Throwable e){
                    log.error("事件分发监控处理异常:", e);
                }
                LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(8));
            }
        });
        distStatThread.setName("AppClientEventDistPipelineProcessor-DistStatThread");
        distStatThread.setDaemon(true);
        distStatThread.start();
        log.info(">>>>>>BizEvent dist queue monitor thread init done. Thread:{}", distStatThread.getName());
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值