用户点击商品埋点的实现方案

在高并发、可扩展性和高可用性的前提下,实现用户点击商品的埋点,方案应包括 数据采集、数据传输、数据存储和数据分析 四个主要环节。下面是一个完整的埋点实现方案:

1. 方案架构

整体流程:

  1. 前端埋点:用户点击商品时,前端(Web/APP)触发埋点事件并上报数据。
  2. 后端接收:后端提供 API 接收埋点数据,并进行基础校验和格式化。
  3. 消息队列(Kafka/RabbitMQ):后端将埋点数据异步写入 Kafka,解耦流量压力,保证高吞吐。
  4. 数据存储:
    • 实时分析:使用 Flink/Spark Streaming 订阅 Kafka,实时处理点击数据。
    • 离线存储:埋点数据写入 Elasticsearch(ES) 用于查询,或者 Hadoop/Hive 进行离线分析。
  5. 数据分析:使用 Flink/Spark + ClickHouse/Hive 分析商品点击数据,供业务使用(如推荐系统、用户行为分析)。

2. 具体实现

(1) 前端埋点(Web & App)

前端可以采用手动埋点或者无埋点方案:

  • 手动埋点:前端在商品详情页点击事件中手动上报数据。
  • 自动埋点:使用 SDK 监听所有 click 事件,并自动收集数据。

示例(Web 前端埋点代码):

document.getElementById('product').addEventListener('click', function() {let clickData = {userId: getUserId(),productId: getProductId(),timestamp: new Date().getTime(),pageUrl: window.location.href,userAgent: navigator.userAgent};navigator.sendBeacon('/track/click', JSON.stringify(clickData));
});
// navigator.sendBeacon 适用于埋点请求,不会阻塞页面跳转。

(2) 后端埋点 API(Java SpringBoot)

后端提供一个 API 来接收埋点数据,并将其写入 Kafka。

@RestController
@RequestMapping("/track")
public class TrackingController {@PostMapping("/click")public ResponseEntity<String> trackClick(@RequestBody ClickEvent event) {// 校验数据if (event.getUserId() == null || event.getProductId() == null) {return ResponseEntity.badRequest().body("Invalid parameters");}// 异步处理,将数据写入 KafkaKafkaTrackingService.trackClick(event);return ResponseEntity.ok("Click event tracked successfully");}
}

优化点:

  • 请求校验:检查 userId、productId 是否为空,防止垃圾数据。
  • 异步处理:埋点 API 只负责接收请求,数据处理交给 Kafka,提高系统吞吐量。

(3) 使用 Kafka 进行高并发数据存储

Kafka 适用于高吞吐数据流,将埋点数据写入 Kafka,保证系统的解耦和可扩展性。

import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import java.util.Properties;public class KafkaTrackingService {private static KafkaProducer<String, String> producer;static {Properties props = new Properties();props.put("bootstrap.servers", "localhost:9092");props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");producer = new KafkaProducer<>(props);}public static void trackClick(ClickEvent event) {String message = event.getUserId() + "," + event.getProductId() + "," + event.getTimestamp();producer.send(new ProducerRecord<>("click-events", event.getUserId(), message));}
}

Kafka 优势:

  • 高吞吐、低延迟:Kafka 可以处理百万级 TPS 的数据写入。
  • 持久化日志:保证埋点数据不会丢失。

(4) 数据消费(Flink 实时计算 + Elasticsearch 查询)

Kafka 数据可以被 Flink/Spark Streaming 订阅,进行实时数据分析,并写入 Elasticsearch 供查询。
使用 Flink 消费 Kafka 并写入 ES

StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();// 读取 Kafka 数据流
FlinkKafkaConsumer<String> kafkaConsumer = new FlinkKafkaConsumer<>("click-events",new SimpleStringSchema(),properties
);
DataStream<String> clickStream = env.addSource(kafkaConsumer);// 解析数据并写入 Elasticsearch
clickStream.map(event -> {String[] fields = event.split(",");Map<String, String> jsonMap = new HashMap<>();jsonMap.put("userId", fields[0]);jsonMap.put("productId", fields[1]);jsonMap.put("timestamp", fields[2]);return jsonMap;
}).addSink(new ElasticsearchSink.Builder<>(esHosts, esSinkFunction).build());env.execute();

为什么用 Flink?

  • 实时计算:可以在毫秒级别计算点击热度。
  • 无界数据流:适用于埋点这种持续流数据。

(5) 数据查询(Elasticsearch)

商品点击量可以在 ES 中查询,支持实时查询和聚合分析:

GET click-tracking/_search
{"query": {"match": {"productId": "12345"}},"aggs": {"click_count": {"value_count": {"field": "productId"}}}
}

这样可以快速获取商品点击数,提供给热门商品推荐系统。

3. 方案优势

方案 优点
前端上报(sendBeacon) 低延迟,不影响用户体验

方案优点
前端上报(sendBeacon)低延迟,不影响用户体验
Kafka 消息队列解耦系统,支持高并发写入
Flink 实时计算毫秒级分析,支持实时推荐
Elasticsearch 查询支持秒级查询商品点击数据

4. 总结

  • 前端埋点:采用 sendBeacon 异步上报埋点数据,避免阻塞用户操作。
  • 后端接收:SpringBoot 提供 API,数据写入 Kafka,保证高并发吞吐。
  • Kafka 处理:解耦埋点数据,支持多消费者(Flink、Spark)。
  • Flink 实时计算:从 Kafka 读取数据,实时分析用户点击行为。
  • ES 存储:支持快速查询,满足热门商品推荐、用户行为分析等需求。

这套方案能够满足高并发、实时分析、灵活扩展的要求

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/70344.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++】AVLTree(AVL树)简单模拟

文章目录 1.AVL树的结点2.AVL树的插入3.AVL树的旋转3.1 新节点插入较高左子树的左侧---左左&#xff1a;右单旋3.2 新节点插入较高右子树的右侧---右右&#xff1a;左单旋3.3 新节点插入较高左子树的右侧---左右&#xff1a;先左单旋再右单旋3.4 新节点插入较高右子树的左侧---…

零基础Vue入门6——Vue router

本节重点&#xff1a; 路由定义路由跳转 前面几节学习的都是单页面的功能&#xff08;都在专栏里面https://blog.csdn.net/zhanggongzichu/category_12883540.html&#xff09;&#xff0c;涉及到项目研发都是有很多页面的&#xff0c;这里就需要用到路由&#xff08;vue route…

【数据结构】(6) LinkedList 链表

一、什么是链表 1、链表与顺序表对比 不同点LinkedListArrayList物理存储上不连续连续随机访问效率O(N)O(1&#xff09;插入、删除效率O(1)O(N) 3、链表的分类 链表根据结构分类&#xff0c;可分为单向/双向、无头结点/有头节点、非循环/循环链表&#xff0c;这三组每组各取…

使用Pygame制作“俄罗斯方块”游戏

1. 前言 俄罗斯方块&#xff08;Tetris&#xff09; 是一款由方块下落、行消除等核心规则构成的经典益智游戏&#xff1a; 每次从屏幕顶部出现一个随机的方块&#xff08;由若干小方格组成&#xff09;&#xff0c;玩家可以左右移动或旋转该方块&#xff0c;让它合适地堆叠在…

(苍穹外卖)项目结构

苍穹外卖项目结构 后端工程基于 maven 进行项目构建&#xff0c;并且进行分模块开发。 1). 用 IDEA 打开初始工程&#xff0c;了解项目的整体结构&#xff1a; 对工程的每个模块作用说明&#xff1a; 序号名称说明1sky-take-outmaven父工程&#xff0c;统一管理依赖版本&…

【漫画机器学习】082.岭回归(或脊回归)中的α值(alpha in ridge regression)

岭回归&#xff08;Ridge Regression&#xff09;中的 α 值 岭回归&#xff08;Ridge Regression&#xff09;是一种 带有 L2​ 正则化 的线性回归方法&#xff0c;用于处理多重共线性&#xff08;Multicollinearity&#xff09;问题&#xff0c;提高模型的泛化能力。其中&am…

websocket自动重连封装

websocket自动重连封装 前端代码封装 import { ref, onUnmounted } from vue;interface WebSocketOptions {url: string;protocols?: string | string[];reconnectTimeout?: number; }class WebSocketService {private ws: WebSocket | null null;private callbacks: { [k…

【华为OD-E卷 - 115 数组组成的最小数字 100分(python、java、c++、js、c)】

【华为OD-E卷 - 数组组成的最小数字 100分&#xff08;python、java、c、js、c&#xff09;】 题目 给定一个整型数组&#xff0c;请从该数组中选择3个元素组成最小数字并输出 &#xff08;如果数组长度小于3&#xff0c;则选择数组中所有元素来组成最小数字&#xff09; 输…

在Vue3 + Vite 项目中使用 Tailwind CSS 4.0

文章目录 首先是我的package.json根据官网步骤VS Code安装插件验证是否引入成功参考资料 首先是我的package.json {"name": "aplumweb","private": true,"version": "0.0.0","type": "module","s…

AURIX TC275学习笔记4 官方GTM例程 GTM_TOM_PWM_1

文章目录 概述其他例程 代码分析IfxGtm_enable()IfxGtm_Cmu_enableClocks&#xff08;&#xff09;IfxGtm_Tom_Pwm_initConfig&#xff08;&#xff09;IfxGtm_Tom_Pwm_init&#xff08;&#xff09;IfxGtm_Tom_Pwm_start&#xff08;&#xff09;fadeLED() 概述 目的&#xf…

ASP.NET Core中间件的概念及基本使用

什么是中间件 中间件是ASP.NET Core的核心组件&#xff0c;MVC框架、响应缓存、身份验证、CORS、Swagger等都是内置中间件。 广义上来讲&#xff1a;Tomcat、WebLogic、Redis、IIS&#xff1b;狭义上来讲&#xff0c;ASP.NET Core中的中间件指ASP.NET Core中的一个组件。中间件…

app专项测试(网络测试流程)

一、网络测试的一般流程 step1&#xff1a;首先要考虑网络正常的情况 ① 各个模块的功能正常可用 ② 页面元素/数据显示正常 step2&#xff1a;其次要考虑无网络的情况 ① APP各个功能在无网络情况下是否可用 ② APP各个页面之间切换是否正常 ③ 发送网络请求时是…

Vue el-input密码输入框 按住显示密码,松开显示*;阻止浏览器密码回填,自写密码输入框;校验输入非汉字内容;文本框聚焦到内容末尾;

输入框功能集合 <template><div style"padding: 10px"><!-- 密码输入框 --><el-input:type"inputType"v-model"password"placeholder"请输入密码"auto-complete"new-password"id"pwd"style…

【数据结构】_复杂度

目录 1. 算法效率 2. 时间复杂度 2.1 时间复杂度概念 2.2 准确的时间复杂度函数式 2.3 大O渐进表示法 2.4 时间复杂度的常见量级 2.5 时间复杂度示例 3. 空间复杂度 3.1 空间复杂度概念 3.2 空间复杂度示例 1. 算法效率 一般情况下&#xff0c;衡量一个算法的好坏是…

Day48_20250130【回校继续打卡】_单调栈part1_739.每日温度|496.下一个更大元素I|503.下一个更大元素II

Day48_20250130_单调栈part1_739.每日温度|496.下一个更大元素I|503.下一个更大元素II 20250130补完 739.每日温度 题目 给定一个整数数组 temperatures &#xff0c;表示每天的温度&#xff0c;返回一个数组 answer &#xff0c;其中 answer[i] 是指对于第 i 天&#xff0…

ASP.NET Core中间件Markdown转换器

目录 需求 文本编码检测 Markdown→HTML 注意 实现 需求 Markdown是一种文本格式&#xff1b;不被浏览器支持&#xff1b;编写一个在服务器端把Markdown转换为HTML的中间件。我们开发的中间件是构建在ASP.NET Core内置的StaticFiles中间件之上&#xff0c;并且在它之前运…

Text2Sql:开启自然语言与数据库交互新时代(3030)

一、Text2Sql 简介 在当今数字化时代&#xff0c;数据处理和分析的需求日益增长。对于众多非技术专业人员而言&#xff0c;数据库操作的复杂性常常成为他们获取所需信息的障碍。而 Text2Sql 技术的出现&#xff0c;为这一问题提供了有效的解决方案。 Text2Sql&#xff0c;即文…

将Deepseek接入pycharm 进行AI编程

目录 专栏导读1、进入Deepseek开放平台创建 API key 2、调用 API代码 3、成功4、补充说明多轮对话 总结 专栏导读 &#x1f338; 欢迎来到Python办公自动化专栏—Python处理办公问题&#xff0c;解放您的双手 &#x1f3f3;️‍&#x1f308; 博客主页&#xff1a;请点击——…

【人工智能】使用Python实现图像风格迁移:理论、算法与实践

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 图像风格迁移是一种利用深度学习技术将一张图像的内容与另一张图像的风格相结合的技术。本文将深入探讨图像风格迁移的基本理论和实现方法,…

ASP.NET Core筛选器Filter

目录 什么是Filter&#xff1f; Exception Filter 实现 注意 ActionFilter 注意 案例&#xff1a;自动启用事务的筛选器 事务的使用 TransactionScopeFilter的使用 什么是Filter&#xff1f; 切面编程机制&#xff0c;在ASP.NET Core特定的位置执行我们自定义的代码。…