准实时前端监控探索

实时数据能立即反映线上业务情况,对业务来说能很快看到业务变化带来的实时影响,对技术人员来说能实时观察线上出现的一些波动,有利于及时发现线上问题。

数据埋点上报经过数据部门处理后,有两个离线表,天表和小时表,天表是第二天才能看到前一天的数据,小时表是可以看到当天过去的时间内的数据,为了更早看到数据效果,尝试采用小时表来进行数据监控。

流程基本如下:

过程介绍

架设服务基于Egg.js,Egg 对定时任务支持很好,新建一个定时任务文件在app/schedule 下即可,每个文件都是一个独立的定时任务。

js 复制代码
const Subscription = require('egg').Subscription;

class ScheduleTask extends Subscription {
	static get schedule() {
		return {
			interval: '5m', // 每5分钟执行一次任务
			type: 'worker',
		};
	
	}
	// subscribe 是真正定时任务执行时被运行的函数
	async subscribe() {
		const pageTypes = getConfig(); // 加载录入的埋点
		await this.ctx.service.task.runData(pageTypes);
		this.ctx.service.task.refreshTask(); // 刷新任务,获取查询结果
	}
}

module.exports = ScheduleTask;

查询结果

查询每个小时埋点结果前,先要确定从哪个时间节点开始查询,这里手动指定一个,查询当前时间2个小时前的数据,比如当前是12点,我们就从10点开始查。

注意用这个时间作为游标,需要缓存起来,后面移动游标的时候需要用到。

在 task 这个service 中,执行 sql 查询,sql如下:

sql 复制代码
const sql = `
SELECT
	pagetype,
	hour,
	count(token) as c
FROM
	page_action_1h
WHERE
	pagetype in ('${pageTypes.join('\',\'')}')
	and actiontype='pv'
	and dt='${dateCursor.format('YYYY-MM-DD')}'
	and hour='${queryHour < 10 ? '0' + queryHour : queryHour}'
group by hour, pagetype

`;

dateCursor 就是缓存的游标,page_action_1h 是表名,表中有用户标识token, pagetypeactiontypedthour,等字段。

注意这里是一条sql 查询多个 pagetype,任务提交后并不会立即返回所有数据,可能单独一个pagetype 有结果后就返回,所以需要循环查询任务执行进度,只有所有的页面结果都返回后才可以执行数据处理,间隔时间根据服务执行效率灵活调整,这里间隔时间设置1分钟。

数据处理

假设sql执行请求的到了如下结果:

json 复制代码
[
  [ 'page1', '10', '4818' ],
  [ 'page2', '10', '2932' ],
  [ 'page3', '10', '1474' ]
]

10点这个时段的数据查询出来了,然后就可以对时间游标dateCursor 加1,这样下一次定时任务查询的就是下一个小时的数据了,本次的数据先存储起来,然后进行对比。

存储方式选择存储到redis中,redis存储结构如下: monitor_key:

json 复制代码
{
  "page1": {
    "10": "4818",
    "11": "5945"
  },
  "page2": {
    "10": "2932",
    "11": "1509"
  },
  "page3": {
    "10": "1474",
    "11": "3438"
  }
}

当下一个小时数据执行完成时,就有了两个时段的数据,对比两个时段的数据量就能看到数据变化趋势,并进行报警。

数据存储一个key中,因为是以小时时段存储的,没有记录日期,所以依赖的是任务不断执行,不断刷新下一个小时的数据,以当前时间为节点,只有当前时间之前的数据查询返回之后才进行下一个时段的查询。

另一个方案是每个小时存储一个key,设置24小时过期时间,直接查询所有匹配的小时即可,保留下来的数据就是一天的数据量。

报警规则

我们可以指定当数据量下降一定比例的时候,上升一定比例的时候发送报警信息。 基于已有数据还可以指定其他报警规则:

  • 区间段内的平均值
  • 区间段内的尖刺值
  • 最大值预警,最小值预警

上线效果

数据累计之后便可以绘制页面访问量级趋势图,报警的时候一并发送会更直观得观察趋势异常情况。

线上持续运行后,发现一个关键问题,小时表的数据生成时间很不稳定,可能是数据量计算所占任务时间长短不一,有时候可以一小时内生成上一个小时的数据,有时候则需要两三个小时甚至更长时间。这对于一个本身实时性不那么强的报警来说,时效性又打了一层折扣。最终效果并没有达到预期。

通过以上的探索,我们尝试了准实时前端监控的方案,利用小时表来获取更快的实时数据反馈。我们搭建了定时任务来定期查询并存储数据,利用 Redis 存储结构来对比数据变化趋势,并设置报警规则来实时监测异常情况。

然而,在线上实践中发现了小时表数据生成时间不稳定的问题,导致实时性不如预期。这对于一个实时性要求不高的报警系统来说,影响并不是很大,但也暴露了需要进一步优化的空间。

所以在未来我们将需找其他方式的实时数据报警,以提供更准确、实时的数据反馈和监控功能,助力业务发展和故障排查。

相关推荐
GISer_Jing1 分钟前
前端架构学习
前端·学习·架构
前端一课2 分钟前
【vue高频面试题】第4题:Vue 3 中的 setup() 是什么?它的执行时机是什么?能做什么?
前端·面试
前端一课2 分钟前
【vue高频面试题】第5题:Vue3 的父子组件通信方式有哪些?分别适用于什么场景?
前端·面试
Funny Valentine-js3 分钟前
web实验后端php测试文本
前端·javascript·php·html5·cookie·telnet·session
前端一课6 分钟前
【vue高频面试题】第6题:Vue3 中 Composition API 和 Options API 有什么区别?为什么 Composition API 更推荐
前端·面试
前端一课10 分钟前
【vue高频面试题】第7题:Vue3 中 `v-model` 的工作原理是什么?为什么 Vue3 支持多个 v-model?如何在子组件中实现?
前端·面试
luguocaoyuan10 分钟前
前端沙箱隔离技术详解:从原理到实践
前端
前端一课12 分钟前
【vue高频面试题】第3题:Vue 3 中的 computed 是什么?和 watch 有什么区别?什么时候用哪一个?
前端·面试
Json____17 分钟前
vue2-数码购物商城-前端静态网站
前端·vue·数码商城
@大迁世界20 分钟前
03.CSS嵌套 (Nesting)
前端·css