一、前言
大数据分析最核心的是数据,而数据的发送尤为重要。如何保证数据能够完整、准确、及时地上传到指定的服务端,是所有数据采集 SDK 需要面临的核心问题。神策数据 Web JS SDK[1] 综合考虑数据发送的各项功能,设计并实现了一套适用于前端数据发送的方案。下面针对神策数据 Web JS SDK 数据发送方案进行详细的介绍,希望能够给大家提供一些参考。
二、数据发送架构解析
2.1 简介
Web JS SDK 致力于高效且稳定地采集页面数据,这就需要一个稳定简洁的架构。网页是基于浏览器运行的,浏览器本身并没有多少缓存功能。因此,Web JS SDK 的架构设计中数据默认是即时采集、即时发送的策略。
2.2 数据发送架构图
Web JS SDK 数据发送架构如图 2-1 所示:
2.3 数据发送流程
Web JS SDK 数据从采集到发送的流程如图 2-2 所示:
通过上图可以知道,数据发送流程主要包括下面几个步骤:
1. 首先会针对上传的事件以及属性做格式校验;
2. 批量发送配置下,将数据缓存到 localstorage,达到发送条件后通过网络发送。发送成功后将已发送的数据删除,发送失败后等待下次发送时机;
3. H5 页面在 App 中打开,可以通过配置项将 H5 采集的数据上报给 App 端的 SDK(Android SDK 或 iOS SDK),数据实时通过 WebView 中间层上报给 App 端,App 端控制数据上报;
4. 实时发送配置下,数据会先保存到发送队列中,然后逐条发送,发送完成后(不论成功与否)将已发送的数据删除;
5. 无论批量发送还是实时发送,请求时间超过设置的超时时间(实时发送默认为 3 秒,批量发送默认为 6 秒)后,都会取消该请求。
三、数据发送时间
Web JS SDK 监控到用户产生了行为,就会生成一条数据。为了最大限度地保证数据的准确性和安全性,会要求数据采集 SDK 尽快将数据同步到指定的服务端。因此,如何选择合适的时间是发送数据需要面临的核心问题。
时间戳是指格林威治时间 1970 年 01 月 01 日 00 时 00 分 00 秒(北京时间 1970 年 01 月 01 日 08 时 00 分 00 秒)起至现在的总秒数。通俗的讲,时间戳能够表示在一个特定时间点已经存在的、完整的、可验证的数据。
物理时间指的就是时间戳;显示时间是指物理时间按照不同的时区,转化成符合各地区的显示时间。例如:我们生活中常见的“北京时间”和“纽约时间”。
3.1 客户端时间戳
客户端时间戳会存在被用户修改的风险,从而导致采集的 time 不符合实际情况。针对时间戳的问题,首先想到的应该是同步或者校准客户端时间。但是,同步或者校准不仅需要网络权限,还需要一个稳定的时间服务器。因此,这并不适用于 Web 端。针对这一问题,目前神策采用的是 “时间修正” 策略。
时间修正机制解释如下:发生事件时的时间(time)值为 t1,发送数据时的时间(_flush_time)的值为 t2(客户端时间,且 _flush_time 不入库),服务端接收到数据的时间($recive_time)为 t3(服务端时间)。如果 |t3 - t2| > 60s,则认为客户端的时间不准确,会对事件触发时间进行修正,修正后事件时间 t1‘ = t1 + (t3 - t2) 。
下面以图 3-1 为例介绍 “时间修正” 的过程:
用户在时间戳 T1(8:00)时触发了一个 $pageview