1,前端埋点传递用户行为信息给后端
;(function($){
//页面初始化加载函数
var init = function(){
var imgs = $(".shop .thumbnail img")
//挂载点击事件
for (i=0;i<imgs.length;i++) {
//给图片添加事件
$(imgs[i]).click(imgTracking)
}
//找到购买商品按钮
var btns =$(".shop .thumbnail button")
for (i=0;i<btns.length;i++){
$(btns[i]).click(btnTracking)
}
}
var btnTracking = function(){
// console.log("用户点击图片了")
//获取用户的id信息
var usid = $(".row .header span").attr("datasrc")
//获取用户点击商品的信息
var userinfo = $(this).attr("datasrc")
//获取当前时间的时间戳
var ts = Date.now()
// console.log("usid:"+usid+","+goodinfo+",ts:"+ts)
axios("usid:"+usid+","+userinfo+",ts:"+ts)
}
//图片埋点事件函数
var imgTracking = function(){
// console.log("用户点击图片了")
//获取用户的id信息
var usid = $(".row .header span").attr("datasrc")
//获取用户点击商品的信息
var goodinfo = $(this).attr("alt")
//获取当前时间的时间戳
var ts = Date.now()
// console.log("usid:"+usid+","+goodinfo+",ts:"+ts)
axios("usid:"+usid+","+goodinfo+",ts:"+ts)
}
//把数据传输到后端 并生成用户日志信息
var axios= function (str){
$.ajax({
type:"POST",
url:'http://localhost:9099/track',
data: {trackMsg:str},
success: function (res){
console.log(res)
}
})
}
init();
})(jQuery);
2,后端接受数据
package com.example.tracking.controller;
import com.example.tracking.service.UserActionLogService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.net.Inet4Address;
import java.net.UnknownHostException;
import java.util.Random;
@RestController
public class InitCtrl {
private Random random = new Random();
@Resource
private UserActionLogService logService;
@RequestMapping(value = "/track",method = RequestMethod.POST)
public String track(String trackMsg){
//模拟多服务器
String addr = "192.168.88."+(random.nextInt(4)+1);
logService.usrActionCache(addr,trackMsg);
return "success";
}
}
3,yml配置
spring:
application:
name: tracking
server:
port: 9099
useract:
path: d:/logs
cache: 10
iplist: 192.168.88.1,192.168.88.2,192.168.88.3,192.168.88.4
4,service层
package com.example.tracking.service;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Service
public class UserActionLogService {
static SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
static ExecutorService pools = Executors.newFixedThreadPool(4);
private static Map<String, List<String>> userMsg = new HashMap<String, List<String>>();
@Value("#{'${useract.iplist}'.split(',')}")
private List<String> addrs;
@Value("${useract.path}")
private String logPath;
@Value("${useract.cache}")
private int cache;
@PostConstruct
private void init(){
for (String add : addrs) {
userMsg.put(add,new CopyOnWriteArrayList<String>());
}
}
private void writeLog(){
//根据服务器地址写对应的用户在各个服务器上对应的日志
// System.out.println(serverIp+"----->"+msg);
// hasFileOrDirectory(logPath+"/"+serverIp);
for (int i =0;i<4;i++) {
final int pos = i;
pools.execute(() -> {
// String ip = "192.168.88."+Thread.currentThread().getName().split("-")[3];
String ip = addrs.get(pos);
// System.out.println(Thread.currentThread().getName()+":"+userMsg.get(ip));
List<String> msgs = userMsg.get(ip);
try {
//向服务器写日志文件
RandomAccessFile raf = new RandomAccessFile(logPath+"/"+ip+"/log_"+sdf.format(new Date())+".log","rw");
raf.seek(raf.length());
for (String msg : msgs) {
msg += "\n";
raf.write(msg.getBytes());
}
} catch (IOException e) {
e.printStackTrace();
}
});
}
}
//计算用户信息容器中的数据量是否达到或超过指定的阈值
public void usrActionCache(String serverIp,String msg){
//获取指定的集合并向集合中添加用户的动作行为
userMsg.get(serverIp).add("serverIp:"+serverIp+","+msg);
//计算集合中用户的数据是否到达或超过阈值 如果超过阈值就进行日志文件写入
int size = 0;
for (List<String> msgs : userMsg.values()) {
// System.out.println("===================="+msgs);
size += msgs.size();
}
if (size >= cache){
//并发写日志
writeLog();
//清楚集合中的数据
for (List<String> msgs : userMsg.values()) {
msgs.clear();
}
}
}
}