阿里云监控服务可用于收集获取阿里云资源的监控指标或用户自定义的监控指标,探测服务可用性,以及针对指标设置警报。使您全面了解阿里云上的资源使用情况、业务的运行状况和健康度,并及时收到异常报警做出反应,保证应用程序顺畅运行。
阿里云事件监控文档地址
因为线上交易,退款,请求超时需要事件监控报警,公司服务器部署在阿里云,只需要接入阿里云的事件监控,我这里主要描述客户端如何实现异步+消息队列接入阿里云的事件监控,其实阿里云事件监控文档也有介绍,我这里主要是讲线上代码 应用。
首先是maven依赖:
<!--事件监控-->
<dependency>
<groupId>com.aliyun.openservices</groupId>
<artifactId>aliyun-cms</artifactId>
<version>0.1.2</version>
</dependency>
<dependency>
<groupId>com.fshows</groupId>
<artifactId>fsframework-extend</artifactId>
<version>1.2.9.3</version>
</dependency>
实例化阿里事件监控代码:
public static AliyunEventUtil getInstance(String accessKey, String secretKey) {
if (instance == null) {
Class var2 = AliyunEventUtil.class;
synchronized(AliyunEventUtil.class) {
if (instance == null) {
instance = new AliyunEventUtil(accessKey, secretKey);
}
}
}
return instance;
}
单例方式实现阿里云事件监控客户端,AliyunEventUtil的变量修饰private static volatile AliyunEventUtil instance = null;
private AliyunEventUtil(String accessKey, String secretKey) {
// 接入阿里云事件地址http://metrichub-cms-cn-hangzhou.aliyuncs.com 根据服务器部署在哪个区
this.cmsClient = new CMSClient("http://metrichub-cms-cn-hangzhou.aliyuncs.com", accessKey, secretKey);
// 事件的队列
this.eventQueue = new LinkedBlockingQueue(10000);
// 实现一个schedule定时线程池 核心线程是1
this.schedule = new ScheduledThreadPoolExecutor(1, (new Builder()).namingPattern("aliyun-event-pool-%d").daemon(true).build());
// 设置实现定时
this.schedule.scheduleAtFixedRate(this, 5L, 1L, TimeUnit.SECONDS);
}
这里普及一下ScheduledThreadPoolExecutor的基本知识:
// 核心线程数为1的定时线程池
public ScheduledThreadPoolExecutor(int corePoolSize,
ThreadFactory threadFactory) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
new DelayedWorkQueue(), threadFactory);
};
//当达到延时时间initialDelay后,任务开始执行。上一个任务执行结束后到下一次
//任务执行,中间延时时间间隔为delay。以这种方式,周期性执行任务。
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
long initialDelay,
long delay,
TimeUnit unit);
业务实现监控事件放入队列:
AliyunEventUtil aliyunEventUtil = AliyunEventUtil.getInstance("accessKey","secretKey");
EventEntry entry = new EventEntry(StrUtil.format("test_{}", "little_sky"), groupId, event_name);
boolean result = aliyunEventUtil.put(entry);
if (!result) {
System.out.println("fail");
}
aliyunEventUtil.put 放入线程池的队列:
public boolean put(EventEntry event) {
if (this.cmsClient == null) {
return false;
} else {
boolean b = this.eventQueue.offer(event);
if (!b) {
LogUtil.warn(log, "事件队列已满,丢弃事件:{}", new Object[]{event});
return false;
} else {
return true;
}
}
}
// 定时线程池执行的方法
public void run() {
do {
this.batchPut();
} while(this.eventQueue.size() > 10);
}
private void batchPut() {
List<CustomEvent> events = new ArrayList();
for(int i = 0; i < 99; ++i) {
// 从队列取出来
EventEntry e = (EventEntry)this.eventQueue.poll();
if (e == null) {
break;
}
events.add(CustomEvent.builder().setContent(e.getContent()).setName(e.getName()).setGroupId(e.getGroupId()).build());
}
if (!events.isEmpty()) {
this.uploadEventBatch0(events);
}
}
最终请求阿里云的事件监控
private boolean uploadEventBatch0(List<CustomEvent> eventList) {
try {
if (eventList != null && !eventList.isEmpty()) {
CustomEventUploadRequest request = (CustomEventUploadRequest)CustomEventUploadRequest.builder().setEventList(eventList).build();
CustomEventUploadResponse response = this.cmsClient.putCustomEvent(request);
if (response == null) {
return false;
} else if (!"200".equals(response.getCode())) {
LogUtil.error(log, "AliyunEventUtil ---- >> uploadEventBatch 上传异常,返回结果:requestId={}, code = {},message={}", new Object[]{response.getRequestId(), response.getCode(), response.getMessage()});
return false;
} else {
return true;
}
} else {
return false;
}
} catch (CMSException var4) {
LogUtil.error(log, "AliyunEventUtil ---- >> uploadEvent 上传异常: Ex = {}", var4);
this.cmsClient = null;
return false;
}
}
参考文章:https://www.jianshu.com/p/502f9952c09b(线程池之ScheduledThreadPoolExecutor)
https://www.cnblogs.com/WangHaiMing/p/8798709.html (BlockingQueue深入解析-BlockingQueue看这一篇就够了)