WebH5页面中做了实践,核心的代码很简单

优采云 发布时间: 2021-07-27 19:54

  WebH5页面中做了实践,核心的代码很简单

  我们先在Web的H5页面上练过,核心代码很简单。首先,在页面加载时绑定所有的点击事件,并上报页面浏览事件数据。其次,user_action_id属性用于指示元素是否需要上报点击事件,user_action_relation属性用于声明当前元素关联到哪个元素。具体的代码实现就不解释了,很简单。

  $(d).ready(function() {

// 页面浏览上报

pvUpload({page: getPageUrl()},

$.extend({title: getTitle()}, getUrlParams()));

// 绑定点击事件

$(d).bind('click', function(event) {

var $target = $(event.target);

// 查找是否是需要上报的元素

var $ua = $target.closest('[user_action_id]');

if ($ua.length > 0) {

var userActionId = $ua.attr('user_action_id');

var userActionRelation = $("[user_action_relation=" + userActionId + "]");

var relationData = [];

// 查找相关联的元素的数据信息

if (userActionRelation.length > 0) {

userActionRelation.each(function() {

var jsonStr = JSON.stringify({

"r_placeholder_element": $(this).get(0).tagName,

'r_placeholder_text': $(this).text()

});

jsonStr = jsonStr.replace(/\placeholder/g, $(this).attr('id'));

jsonStr = JSON.parse(jsonStr);

relationData.push(jsonStr);

});

}

// 点击事件上报

clickUpload({page: getPageUrl(), element: userActionId},

$.extend({title: getTitle()}, getUrlParams(), relationData));

}

});

});

  上面的代码可以嵌入到任何HTML页面中,然后在相应的元素中声明即可。例如,

  

提 交

  如何存储后端

  数据进入后台后,首先连接到Kafka队列,以生产-消费者模式进行处理。这样做的好处如下: 一是功能分离。上报的API接口不关心数据处理功能,只负责访问数据;第二,数据缓冲,数据上报速率不可控,取决于用户使用频率。这种模式可以在一定程度上缓冲数据;第三,易于扩展。当数据量较大时,可通过增加数据处理工作者进行扩展,以提高处理速度。

  

  除了前端上报的数据内容外,我们还需要向后端添加一些其他必要的信息。在数据接入Kafka队列之前,需要添加五个维度的信息:客户端类型(Web/Android/IOS)、事件类型(浏览/点击)、时间、客户端IP、用户代理。消费者Worker从Kafka取回数据后,需要添加一个名为event_id的字段。下面将解释其具体含义。所以最后保存的数据格式如下:

  {

"uuid": "2b8c376e-bd20-11e6-9ebf-525499b45be6",

"event_time": "2016-12-08T18:08:12",

"page": "www.example.com/poster.html",

"element": "register",

"client_type": 0,

"event_type": 0,

"user_agent": "Mozilla\/5.0 (Linux; Android 5.1; m3 Build\/LMY47I) AppleWebKit\/537.36 (KHTML, like Gecko) Version\/4.0 Chrome\/37.0.0.0 Mobile MQQBrowser\/6.8 TBS\/036887 Safari\/537.36 MicroMessenger\/6.3.31.940 NetType\/WIFI Language\/zh_CN",

"ip": "59.174.196.123",

"timestamp": 1481218631,

"event_id": 12,

"attrs": {

"title": "test",

"user_id": 1234

}

}

  再看event_id的含义。在前端传递过来的一组数据中,可以通过页面和元素来区分发生了什么事件,但是这些都是前端UI的名称,大部分都是开发者可以理解的语言,所以我们需要有兴趣的给活动添加一个通俗易懂的名称,比如上面数据对应的活动名称是“在海报页面注册”。将页面+元素和事件名称进行关联映射,然后将对应的数据记录id作为事件id添加到上述数据中,方便后面数据分析中基于事件id进行事件聚合。有两种方式:一是让相关人员通过页面进行配置,手动关联;另一种是前端上报时带上事件名称,目前这两种方式我们都在使用。

  最后来看数据存储的问题。传统的关系型数据库在存储数据时,是使用行列的二维结构来表示数据的。每行数据具有相同的列字段。这种存储方式说明不适合上面的数据格式,因为我们无法预测attrs里面有哪些字段数据。例如,用户行为数据和日志数据都是半结构化数据。所谓半结构化数据,就是结构变化的结构化数据(WIKI中定义),适用于使用NoSQL进行数据存储。我们选择 ElasticSearch 进行数据存储,主要基于两个考虑:

  Elasticsearch的使用请参考Elasticsearch使用总结一文。我不会在这里过多解释。使用 Elasticsearch 进行数据存储,最重要的就是建立 Elasticsearch 的映射模板和批量插入。 Elasticsearch 会根据插入的数据自动创建缺失的 index 和 doc 类型,并为字段创建映射,我们要做的就是创建一个动态模板,告诉 Elasticsearch 如何自动创建。请参阅以下内容。批量插入可以通过 Elasticsearch 的批量 API 轻松解决。

  "user_action_record": {

"order": 0,

"template": "user_action_record_*",

"settings": {

},

"mappings": {

"_default_": {

"dynamic_templates": [{

"string_fields": {

"mapping": {

"type": "string",

"fields": {

"raw": {

"index": "not_analyzed",

"ignore_above": 256,

"type": "string"

}

}

},

"match_mapping_type": "string"

}

}],

"properties": {

"timestamp": {

"doc_values": true,

"type": "date"

}

},

"_all": {

"enabled": false

}

}

}

}

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线