作者:admin
最后编辑:2024-12-11 15:48:04
范例场景描述
订单相关的数据指标是非常多的,如果单个统计组不容易满足所有需求,可拆分成多个统计组分开实现。在系统中统计组是一个虚拟的、轻量级概念,合理拆分统计组有利于数据接入、便于指标管理维护和程序运算。
本文选择两类常见的订单指标进行阐述:一是订单金额、下单用户数相关统计(范例移动端订单数据统计),二是订单状态相关统计(范例订单状态数据统计)。
假如我们有如下数据需求:
订单量:
1、每10分钟_总订单量
2、每10分钟_各商户_订单量
3、每10分钟_各省份_订单量
4、每10分钟_各城市_订单量
5、每小时_总订单量
6、每天_总订单量
7、每天_各商户_订单量
8、每天_各省份_订单量
9、每天_各城市_订单量
10、每天_各价格区间_订单量
交易金额:
1、每10分钟_总成交金额
2、每10分钟_各商户_成交金额top100
3、每10分钟_各省份_成交金额
4、每10分钟_各城市_成交金额
5、每小时_总成交金额
6、每小时_各商户_成交金额
7、每天_总成交金额
8、每天_各商户_成交金额
9、每天_各省份_成交金额
10、每天_各城市_成交金额
下单用户数:
1、每10分钟_下单用户数
2、每10分钟_各商户_下单用户数
3、每10分钟_各省份_下单用户数
4、每10分钟_各城市_下单用户数
5、每小时_下单用户数
6、每天_下单用户数
7、每天_各商户_下单用户数
8、每天_各省份_下单用户数
9、每天_各城市_下单用户数
10、每天_各价格区间_下单用户数
定义元数据
字段 | 字段类型 | 描述 | |
---|---|---|---|
userId | string | 用户ID | |
orderId | string | 订单ID | |
province | string | 用户所在省份 | |
city | string | 用户所在城市 | |
dealerId | string | 商户ID | |
amount | number | 订单金额 |
消息上报时机
在用户支付成功后上报原始消息数据。
配置统计项
Template:<stat-item title="每10分钟_总订单量" stat="count()" />
TimeParam:10-minute
Template:<stat-item title="每10分钟_各商户_订单量" stat="count()" dimens="dealerId" />
TimeParam:10-minute
Template:<stat-item title="每10分钟_各省份_订单量" stat="count()" dimens="province" />
TimeParam:10-minute
Template:<stat-item title="每10分钟_各城市_订单量" stat="count()" dimens="province;city" />
TimeParam:10-minute
Template:<stat-item title="每天_总订单量" stat="count()" />
TimeParam:1-day
Template:<stat-item title="每天_各商户_订单量" stat="count()" dimens="dealerId" />
TimeParam:1-day
Template:<stat-item title="每天_各价格区间_订单量" stat="count()" dimens="section(amount,'50,100,200,500,1000')" />
TimeParam:1-day
Template:<stat-item title="每10分钟_交易金额" stat="sum(amount)" />
TimeParam:10-minute
Template:<stat-item title="每天_各城市_交易金额" stat="sum(amount)" dimens="province;city" />
TimeParam:1-day
Template:<stat-item title="每10分钟_下单用户数" stat="bitcount(userId)" />
TimeParam:10-minute
Template:<stat-item title="每天_总下单用户数" stat="bitcount(userId)" />
TimeParam:1-day
Template:<stat-item title="每天_各价格区间_下单用户数" stat="bitcount(userId)" dimens="section(amount,'50,100,200,500,1000')" />
TimeParam:1-day
Template:<stat-item title="每天_各省份_下单用户数" stat="bitcount(userId)" dimens="province"/>
TimeParam:1-day
模拟数据接入
private static final String userId_RandomId = RandomID.id(10);
private static final String dealerId_RandomId = RandomID.id(5);
private static final AreaSource areaSource = AreaSource.getInstance();
private static final String[] sceneArray = new String[]{"游戏","娱乐","电商","外卖","餐饮","教育","医疗"};
@Test
public void orderStatTest() throws Exception {
//连接RPC模块注册中心,集群版本默认为RPC部署(lighthouse-ice)的前两个节点(一主一从),单机版本只使用一个节点即可。
LightHouse.init("10.206.7.15:4061,10.206.7.5:4061");
for(int i=0;i<1000;i++){
HashMap<String,Object> paramMap = new HashMap<>();
paramMap.put("userId",userId_RandomId +"_" + ThreadLocalRandom.current().nextLong(100L));
String cityStr = areaSource.randomCity(",");
String [] cityArray = cityStr.split(",");
paramMap.put("province",cityArray[0]);
paramMap.put("city",cityArray[1]);
paramMap.put("dealerId",dealerId_RandomId + "_" + ThreadLocalRandom.current().nextInt(50));
paramMap.put("scene",sceneArray[ThreadLocalRandom.current().nextInt(7)]);
double amount = ThreadLocalRandom.current().nextDouble(1,9999);
paramMap.put("amount",String.format("%.2f", amount));
paramMap.put("orderId","order_"+i);
//参数1对应统计组token,参数2对应统计组秘钥,参数3是消息事件的13位时间戳 。
LightHouse.stat("Gjd:order_stat","AZ6ReXXskkRQuzcq33urcwWwPhpMqp1n",paramMap,System.currentTimeMillis());
}
//注意:stat方法为异步发送,如果进程直接退出可能会导致部分消息没有发送出去,所以这里加一个sleep。
Thread.sleep(10 * 1000);
System.out.println("send ok!");
}
查看统计结果
注意事项
- 如果使用单元测试发送完统计消息后进程直接退出,请务必加一个Thread.sleep(10 * 1000),否则部分内存中的消息可能没有发送出去而影响统计结果。
- 系统内置的监控功能(集群监控和首页报表)都是基于系统处理消息的时间戳,与原始消息指定的时间戳不同,所以两者的统计结果不完全一致。比如:调用SDK的stat方法上报消息时,如果指定的是昨天的时间戳,则对应统计指标的值都是计算在昨天的统计周期内,但集群监控的统计周期是当前时间。