通知类
/**
* 通知
*/
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));
}
}
}