活动营销系统

 

一、整体架构图

二、核心业务系统介绍

2.1.接入层统一异常处理逻辑

 

2.2.邀请服务逻辑

 

2.3.权益发放服务

 

 

2.4.排行榜服务

2.4.1.榜单服务数据结构

数据结构分为两块:

  1. 配置中心数据,因为排行榜没有后台配置平台,只能将配置数据放到配置中心,具备实时更改配置的能力
  2. 数据表,主要是排行榜核心数据结构
--  配置中心信息
榜单配置信息数据:
 
榜单周期id:
 
-- 数据库表结构
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
{
    "rank_code": {
        "name": "榜单名称",
        "rank_type": "用于榜单归类",
        "rank_default": {
            "rank_alias": "default",
            "rank_biz_id": "默认榜单筛选条件:能量值",
            "rank_sub_biz_id": "none,对应过滤值"
        },
        "rank_children": [
            {
                "rank_alias": "出行能量值:consumption",
                "rank_sub_biz_id": "consumption"
            },
            {
                "rank_alias": "邀请能量值:invite",
                "rank_sub_biz_id": "invite"
            }
        ],
        "rand_period": [
            {
                "periodType": "day"
            },
            {
                "periodType": "week"
            },
            {
                "periodType": "month"
            },
            {
                "periodType": "year"
            },
            {
                "periodType": "range"
            }
        ],
        "beginTime": "开始时间",
        "endTime": "结束时间"
    }
}day:当前日期yyyy-MM-dd;
week:w-当前周第一天;
month:yyyy-MM;
year:yyyy;
rang: 开始时间-结束时间,CREATE TABLE `activity_rank_data_source_detail` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `request_id` varchar(128) NOT NULL DEFAULT '' COMMENT '唯一键',
  `entity_id` varchar(64) NOT NULL DEFAULT '' COMMENT '实体id',
  `entity_type` smallint(6) NOT NULLactivity_rank_period_count DEFAULT '0' COMMENT '实体类型,1:用户id',
  `entity_data_real_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '该数据发生的真实时间',
  `entity_data_biz_id` varchar(128) NOT NULL DEFAULT '' COMMENT '业务线,1:能量值',
  `entity_data_sub_biz_id` varchar(128) NOT NULL DEFAULT '' COMMENT '二级业务:能耗、助力',
  `entity_data_num` int(11) NOT NULL DEFAULT '0' COMMENT '数据大小',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_request_id` (`request_id`),
  KEY `idx_biz_id` (`entity_data_biz_id`,`entity_data_sub_biz_id`,`entity_id`,`entity_data_real_time`,`entity_data_num`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='活动榜单-榜单数据更新明细';
 
CREATE TABLE `activity_rank_period_count` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `rank_biz_id` varchar(128) NOT NULL DEFAULT '' COMMENT '榜单业务id',
  `rank_sub_biz_id`  varchar(128) NOT NULL DEFAULT '' COMMENT '榜单业务id',
  `rank_code`  varchar(128) NOT NULL DEFAULT ''  COMMENT '榜单code',
  `rank_name`  varchar(128) NOT NULL DEFAULT '' COMMENT '榜单名称',--待定
  `entity_id` varchar(64) NOT NULL DEFAULT '' COMMENT '实体id',
  `entity_type` smallint(6) NOT NULL DEFAULT '0' COMMENT '实体类型,1:用户id',
  `period_type` smallint(6) NOT NULL DEFAULT '0' COMMENT '周期类型,1:日、2:周、3:月,4:年、5:固定区间',
  `period_id` varchar(64) NOT NULL DEFAULT '' COMMENT '周期唯一code',
  `period_begin_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '周期开始时间,所有的周期开始-结束时间为左闭右开',
  `period_count` int(11) NOT NULL DEFAULT '0' COMMENT '周期统计数值',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_period_entity_id` (`rank_biz_id`,`period_id`,`entity_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='活动榜单-榜单周期数据统计';

  

2.4.2.榜单服务更新流程


说明:
    1. redis中会缓存一份topN的数据
      1. 更新时机
        1. 用户数据变更时,实时更新
        2. 定时从DB中加载对应的topN数据
      2. topN数据只能根据统计后的用户-周期数据进行更新。

 

redis内存数据结构:
1
2
rank_source_biz_id(榜单类型)_day(周期类型)_period_code: zset
rank_top_biz_id(榜单类型)_day(周期类型)_period_code(当前): List<String> ,user_id,能量值,排名  
数据注意事项:
  1. rank_source_xxx避免元素数量过多(目前暂时忽略,元素个数在1w以内)
  2. rank_top_xxx
    1. 并列排名的问题,topN实际元素可能是N+n (是否要做限制)

2.4.3.多维度榜单设计

zset value:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
long 类型 最大值为: 111111111111111111111111111111111111111111111111111111111111111  63
value需要包括: 排行榜值count 和 时间戳
所以我们可以根据我们业务的值来选择 使用多少bit位来表示排行榜值,和时间戳
假如我们业务内,count取值范围在0-10000, 时间戳在 2025-01-01 00:00:00~ 2026-01-01 00:00:00
那么我们可以这样设计
10000的二进制表示为: 10011100010000 14
2025-01-01 00:00:00 日期表示
毫秒级: 11001010000011101011100100000100000000000 41
秒: 1100111011101000001010100000000 31
 
2026-01-01 00:00:00 日期表示
 
毫秒级: 11001101101110101001000110011010000000000 41
秒: 1101001010101010100100010000000 31
 
所以说如果表示这一年时间,我们最多可以使用41位 ,假设我们在榜单上配置一个基准时间,例如,就是2025-01-01 00:00:00 的毫秒,
那么存储时间,就可以设置为该基准时间的相对时间,
2026-01-01 00:00:00 2025-01-01 00:00:00 之间最大时间差为:
11101010111101100010010110000000000 35
如果只精确到秒:1111000010011001110000000  25
 
这是我们就可以在一个用一个long类型数据表示这两部分数据
高位用15位表示 count ,低位用40位表示时间.
 
以 count = 1000,time = 2025-06-01 10:12:30 基准时间为:2025-01-01 00:00:00 ,精确秒来计算:
合并计算:
//偏移位数
int timeShift = 45;
Date date1 =  DateUtil.parse("2025-01-01 00:00:00", DatePattern.NORM_DATETIME_FORMAT);
Date date2 =  DateUtil.parse("2025-06-01 10:12:30", DatePattern.NORM_DATETIME_FORMAT);
long diff =Long.valueOf(( date2.getTime() -date1.getTime()) /1000);
int count = 1000;
 
long result = 0L;
result =  (result | count) << timeShift;
result = result | diff;
System.out.println("001:"+Long.toBinaryString(result));
//反解析
int count1 = (int)(result >> 45);
long diff1 = result^((count1 | 0L)<<45);
System.out.println("002:"+Long.toBinaryString(count1));
System.out.println("022:"+Long.toBinaryString((count1 | 0L) << timeShift));
System.out.println("003:"+ Long.toBinaryString(diff));
System.out.println("004:"+ Long.toBinaryString(diff1));

  

三、服务治理

 

posted @   程序员老徐  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
点击右上角即可分享
微信分享提示