项目中通知模块的实现

通知类

/**
 *  通知
 */
public final class Notice {

    public enum NoticeType {

        LOGIN("LOGIN", "AAA->服务端,进行登录"), //
        LOGIN_ACK("LOGIN_ACK", "服务端->AAA,返回AAA登录结果"), //
       

        /**
         * 通知类型
         */
        private String typeName;

        /**
         * 通知类型描述,链路状态
         */
        private String typeDesc;

        NoticeType(String typeName, String typeDesc) {
            this.typeName = typeName;
            this.typeDesc = typeDesc;
        }

        public String typeName() {
            return this.typeName;
        }

        public String typeDesc() {
            return this.typeDesc;
        }

    }

    /**
     * 通知类型,用于不同监听处理数据
     */
    private Notice.NoticeType noticeType;

    /**
     * 通知内容,可自定义标准,不同监听格式可不同
     */
    private Object noticeContent;

    /**
     * 通知日期实际 yyyyMMddHHmmss
     */
    private String noticeDate;

    /**
     * 通知状态 true 有效,false 失效
     */
    private boolean noticeStatus;

    /**
     * @param noticeType 通知类型
     * @param noticeContent 通知内容
     */
    public Notice(Notice.NoticeType noticeType, Object noticeContent) {
        this.noticeType = noticeType;
        this.noticeContent = noticeContent;
        noticeDate = String.valueOf(System.currentTimeMillis());
        noticeStatus = true;
    }

    public Notice.NoticeType getNoticeType() {
        return noticeType;
    }

    public Object getNoticeContent() {
        return noticeContent;
    }

    public String getNoticeString() {
        // TODO 需要处理,返回 字符串数据 暂放;
        return noticeContent != null ? noticeContent.toString() : "";
    }

    public String getNoticeDate() {
        return noticeDate;
    }

    public void setNoticeDate(String noticeDate) {
        this.noticeDate = noticeDate;
    }

    public boolean isNoticeStatus() {
        return noticeStatus;
    }

    public void setNoticeStatus(boolean noticeStatus) {
        this.noticeStatus = noticeStatus;
    }

}

通知线程类

public class NoticeRunnable implements Runnable {

    private static final int QUEUE_SIZE = 10000 * 10;

    private static final Logger LOGGER = LoggerFactory.getLogger(NoticeRunnable.class);

    private static BlockingQueue<Notice> QUEUE = new LinkedBlockingQueue<>(QUEUE_SIZE);

    private static Map<Notice.NoticeType, List<AbstractNoticeListener>> NOTICETYPE_LISTENER_LIST = new HashMap<>();

    private boolean running = true;

    public void stop() {
        this.running = false;
    }

    public boolean isFull() {
        return QUEUE.size() > QUEUE_SIZE * 0.8;
    }

    @Override
    public void run() {
        while (running || QUEUE.size() > 0) {
            try {
                Notice notice = QUEUE.poll(5, TimeUnit.SECONDS);
                if (notice == null) {
                    continue;
                }
                for (AbstractNoticeListener listener : NOTICETYPE_LISTENER_LIST.get(notice.getNoticeType())) {
                    listener.execute(notice);
                }
                notice = null;
            }
            catch (Exception e) {
                LOGGER.error(e.getMessage(), e);
            }
        }
    }

    public void addListener(AbstractNoticeListener listener) {
        for (NoticeType noticeType : listener.supportNoticeTypes()) {
            NOTICETYPE_LISTENER_LIST.computeIfAbsent(noticeType, k -> new ArrayList<>()).add(listener);
        }
    }

    public void addNotice(Notice notice) {
        try {
            QUEUE.put(notice);
            int currSize = QUEUE.size();
            if (currSize > QUEUE_SIZE * 0.8) {
                LOGGER.error("risk upload data queue current size is {}, the max is {}", currSize, QUEUE_SIZE);
            }
            // boolean offerResult = false;
            // if (QUEUE_SIZE != QUEUE.size()) {
            // offerResult = QUEUE.offer(notice, 5, TimeUnit.MICROSECONDS);
            // }
            // if (!offerResult&&LOGGER.isErrorEnabled()) {
            // LOGGER.error("offer noticeType [{}], noticeContent[{}] fail",
            // notice.getNoticeType(),notice.getNoticeContent());
            // }
        }
        catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
        }
    }

}

通知管理类

/**
 * 通知管理器 负责协作各个事件处理 支持,同步、异步 如非必要,请使用异步通知
 *
 */
public final class NoticeManager {

    private static final Logger LOGGER = LoggerFactory.getLogger(NoticeManager.class);

    private static Map<Notice.NoticeType, NoticeRunnable> NOTICETYPE_EXECUTOR = new HashMap<>();

    private static ExecutorService executor = new ThreadPoolExecutor(0, 20, 60L, TimeUnit.SECONDS,
            new SynchronousQueue<Runnable>(), new ThreadFactory() {
                private final AtomicInteger threadNumber = new AtomicInteger(1);

                @Override
                public Thread newThread(Runnable r) {
                    return new Thread(r, "risk_notice_" + threadNumber.getAndIncrement());
                }
            });

    /**
     * 监听注册 写法比较基础,可优化
     * @param noticeType
     * @param noticeListener
     */
    public static void stop() {
        try {
            for (NoticeRunnable executor : NOTICETYPE_EXECUTOR.values()) {
                executor.stop();
            }
            executor.shutdown();
            executor.awaitTermination(1, TimeUnit.MINUTES);
        }
        catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
        }
    }

    public static void registerListener(int threadCount, NoticeRunnable noticeExecutor,
            AbstractNoticeListener... noticeListeners) {
        for (AbstractNoticeListener listener : noticeListeners) {
            noticeExecutor.addListener(listener);
            for (Notice.NoticeType noticeType : listener.supportNoticeTypes()) {
                NOTICETYPE_EXECUTOR.put(noticeType, noticeExecutor);
            }
        }
        for (int i = 0; i < threadCount; i++) {
            executor.execute(noticeExecutor);
        }
    }

    /**
     * 发送通知
     * @param noticeType 通知类型
     * @param noticeContent 通知内容
     */
    public static void sendNotice(Notice.NoticeType noticeType, Object noticeContent) {
        NoticeRunnable noticeExecutor = NOTICETYPE_EXECUTOR.get(noticeType);
        if (noticeExecutor == null) {
            LOGGER.error("noticeType [{}] not exist executor", noticeType);
            throw new RuntimeException("not support");
        }
        noticeExecutor.addNotice(new Notice(noticeType, noticeContent));
    }

}

通知监听类

/**
 * 事件通知监听器 此为模板,需要集成该监听,完成具体实现,
 *
 */
public abstract class AbstractNoticeListener {

    protected final Logger LOGGER = LoggerFactory.getLogger(getClass());

    protected Gson GSON = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();

    public void execute(Notice notice) throws Exception {
        throw new RuntimeException(String.format("not support %s", notice.getNoticeType().name()));
    }

    public abstract NoticeType[] supportNoticeTypes();

}

---

public class LoginNoticeListener extends AbstractNoticeListener {

    @Override
    public NoticeType[] supportNoticeTypes() {
        return new NoticeType[] { //
                Notice.NoticeType.LOGIN, //
                Notice.NoticeType.LOGIN_ACK, //
                Notice.NoticeType.RELOGIN //
        };
    }

    @Override
    public void execute(Notice notice) {
        if (Notice.NoticeType.LOGIN.equals(notice.getNoticeType())) {
            RskRabbitmqClient.send(RiskMqConstant.LOGIN_EXCHANGE, RiskMqConstant.LOGIN_EXCHANGE,
                    ((String) notice.getNoticeContent()).getBytes(StandardCharsets.UTF_8));
        }
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值