项目总结.

文章目录

  • 1.DDD结构基础
  • 2. 抽奖领域
  • 3. 发奖领域
  • 4.活动领域
  • 5. 支撑领域
  • 应用层编排

1.DDD结构基础

  1. 包含:
    接口层、应用层、领域层、基础层;通用包、接口层、接口定义。
    接口层:实现RPC接口定义,引入应用层服务,封装具体的接口。
    应用层:逻辑包装、编排、任务,领域事件的发布和订阅。
    领域层:封装具体的业务功能的实现,它们是聚合、充血的

    • model,用于提供vo、req、res 和 aggregates 聚合对象
    • repository,提供仓储服务,其实也就是对Mysql、Redis等数据的统一包装
    • service,是具体的业务逻辑实现,对外提供接口
      基础层:数据库、Redis、ES
      通用包:通用的对象、常量、枚举、异常
      接口定义:描述RPC接口文件,用于打包后外部引入pom配置
  2. 为什么要定义RPC接口层:
    因为使用 RPC 框架的时候,需要对外提供描述接口信息的Jar包让外部调用方引入,所以RPC 需要暴露出来,而 DDD 的系统结构又比较耦合,所以进行了模块化的分离。

  3. 知识总览
    在这里插入图片描述
    表信息包括:活动表、奖品表、策略表、规则表、用户参与表、中奖信息表等

在这里插入图片描述
在这里插入图片描述

  1. Dubbo怎么用:
    提供方这里打包成jar包,调用方这里引入pom,用注解@reference注入,就可以调用了。

2. 抽奖领域

口述:抽奖这个领域是可以独立配置和使用的领域模块,没有引入活动id,可以满足不同业务场景的灵活调用,使用了策略模式根据传入的策略选择不同的抽奖算法。比如单体概率、整体概率
划分了两张表,策略配置表和策略明细表,来满足不同业务场景的灵活的调用,比如说:有些业务场景直接进行抽奖反馈中奖信息发送给用户,但还有一些场景用户下单支付才满足抽奖条件,对应的奖品是需要延时到账的,避免用户在下单后又进行退单,这样造成了刷单的风险。

  1. 策略配置表和策略明细表,它们的关系是1v n。

  2. 两种抽奖策略算法
    单项概率抽奖和整体概率抽奖:为了配合不同的玩法,当1个奖品被抽空了以后,那么再抽奖时,是剩余的奖品总概率均匀分配,还是保持剩余奖品的中奖概率

  3. 抽奖算法实现:
    单体概率:采用的斐波那契散列算法,散列效果比hashmap更好,O(1)复
    杂度下完成
    总体概率:随机0-1值,看一下这个随机的概率在哪个奖品区间,表示中哪个奖
    在这里插入图片描述

  4. 模板模式处理抽奖流程
    使用模板的设计模式,规范抽奖的执行流程,包括:校验抽奖策略有没有初始化(单体概率的话需要初始化,使用斐波那契算法来初始化概率数组)、获取不在抽奖范围内的奖品(库存为空、风控、临时调整)、执行抽奖(策略模式:根据传入的策略选择不同的实现,执行抽奖拿到奖品id,扣减库存{使用redis分布式锁,有更好的并发性})、包装中奖结果。

3. 发奖领域

有四种奖品发放的方式,1:文字描述、2:兑换码、3:优惠券、4:实物奖品,使用简单工厂,将全部发奖方式放入map中(@PostConstruct完成初始化),在发奖时根据查到的奖品的类型到工厂取对应的发奖方式。

4.活动领域

活动创建、活动状态处理、用户领取活动

  • 活动创建:创建活动涉及到多张表(活动信息、奖品信息、策略信息、策略明细),要在一个事务下进行落库。
  • 活动状态的处理:活动状态的处理用到了状态模式进行处理,活动状态包括(1编辑、2提审、3撤审、4通过、5运行(审核通过后worker扫描状态)、6拒绝、7关闭、8开启),在抽象类中定义了所有状态流转的抽象方法,子类也就是所有的状态类重写里面的方法,它们各自都有自己的状态的改变逻辑,比如说编辑状态可以变为提审状态、可以变为撤审、关闭状态,那只有这些可变的状态才会进入DB,进行活动状态的修改,不可转变的状态就不会进入,定义好这些状态类后,将它们放入map中,在对外提供的接口中,根据当前状态在map中拿到对应的状态类,就实现了状态的改变。
  • 用户领取活动:使用模板模式,抽象类定义模板,模板流程包括:1. 查看有没有未执行抽奖的活动,有的话说明用户已经领取了活动但是抽奖失败(user_take_activity 用户领取活动记录表state = 0,领取了但抽奖过程失败的,可以直接返回领取结果继续抽奖) 2. 活动的校验(日期、库存、状态)、扣减活动库存、添加用户领取信息(扣减个人已参与次数、添加用户的领取信息)、封装结果(返回策略id,用于后续抽奖)。扣减个人已参与次数(用户参与次数表)和添加用户的领取信息(用户参与记录表)是要保证事务性的,为了保证在多个DAO上使用路由并且保证事务不失效这里采用的是比较简单的方法:吧切换路由的操作放在事务开始前,事务也采用编程式事务。
    • 易错点:扣减库存与添加用户领取信息是在两个库中,按道理来说扣减活动库存失败了因为恢复掉用户的领取信息,这里的话采用redis扣减库存,不能保证完全恢复正确,其实类似于超卖,不能让用户多领取,可以接受一个活动没用户领取。

5. 支撑领域

包括:ID的生成、分库分表、vo2dto方法、Redis

  1. ID生成:使用策略模式将三种生成ID的算法统一包装,由调用方决定使用那种生成ID的策略,ID可以用在订单号、策略ID、活动id,包括雪花算法(hutool)、日期算法(仅支持很小的调用量,用于生成活动配置类编号,保证全局唯一)、随机算法
  2. 分库分表:使用EnvironmentAware 解析配置,在自动配置类中创建数据源,在aop切面的拦截中,拦截需要分库分表的方法,分库分表的逻辑是类似于hashMap,将路由字段进过扰动函数计算出索引,再折算到具体的库表,当然这部分东西也不一定放在切面中,可以做成一个bean,可以配合编程式事务,分库数、分表数存到ThreadLocal中,用于传递在方法调用过程中可以提取到索引信息。
    Mybatis 拦截器处理分表,通过拦截 SQL 语句动态修改添加分表信息,再设置回 Mybatis 执行 SQL 中,分表这部分主要就是在表后加入分表索引来确定是哪个表。

应用层编排

功能:调用领域服务功能,编排抽奖过程,包括:对于活动的领取、抽奖的操作、中奖结果的保存、处理发奖。
首先查一下有没有领取了活动但是执行抽奖失败的活动单,有的话拿到这个活动对应的策略id,再由该策略经过不同的概率算法计算出获奖的信息,再保存中奖的结果:保存的时候要同时修改两张表:用户领取活动记录表(state改为1)和用户奖品表。使用编程式事务控制。
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

日期问题 刷题笔记

思路 枚举 19600101 到20591231这个区间的数 获得年月日 判断是否合法 如果合法 关于题目给出的日期 有三种可能 年/月/日 日/月/年 月/日/年 判断 是否和题目给出的日期符合 如果符合 输出 闰年{ 1.被4整除不被100整除 2.被400整除} 补位写法“%02d" 如果不…

【C语言步行梯】自定义函数、函数递归详谈

🎯每日努力一点点,技术进步看得见 🏠专栏介绍:【C语言步行梯】专栏用于介绍C语言相关内容,每篇文章将通过图片代码片段网络相关题目的方式编写,欢迎订阅~~ 文章目录 什么是函数库函数自定义函数函数执行示例…

STM32 ADC数模转换器

单片机学习! 目录 文章目录 前言 一、ADC简介 1.1 ADC名称 1.2 ADC功能 1.3 分辨率与转换时间 1.4 输入电压与转换范围 1.5 输入通道 1.6 增强功能 1.7 自动监测输入电压范围 1.8 STM32F103C8T6 ADC资源 二、逐次逼近型ADC 2.1 ADC内部结构原理图 2.2 输入通道选择 …

AI 驱动的医疗变革:迈向未来医疗新生态

直面呼啸而来的人工智能,医疗行业将首当其冲,发生翻天覆地的变化。美国心脏病学家兼基因学教授埃里克托普在《未来医疗》中预测,未来人类将拥有“健康小助手”——个人医疗数据和处理能力,还能轻松预防疾病。诸多评论家也持类似观…

Jade 处理XRD并计算半峰宽FWHM、峰面积、峰强度等数据

1.打开软件 2.导入测试的XRD数据 3.平滑数据 4.抠一下基底 5.分析具体数据 6.按住鼠标左键,在峰底部拉一条线,尽量和基底持平 7.结果就出来了,想要的都在里面,直接取值就行

数据分析-Pandas如何观测数据的中心趋势度

数据分析-Pandas如何观测数据的中心趋势度 数据分析和处理中,难免会遇到各种数据,那么数据呈现怎样的规律呢?不管金融数据,风控数据,营销数据等等,莫不如此。如何通过图示展示数据的规律? 数据…

Stable Diffusion 模型:从噪声中生成逼真图像

你好,我是郭震 简介 Stable Diffusion 模型是一种生成式模型,可以从噪声中生成逼真的图像。它由 Google AI 研究人员于 2022 年提出,并迅速成为图像生成领域的热门模型。 数学基础 Stable Diffusion模型基于一种称为扩散概率模型(Diffusion P…

16 OpenCV Laplance算子

文章目录 图像的二阶导数Laplance算子代码示例 图像的二阶导数 在二阶导数的时候,最大变化处的值为零即边缘是零值。通过二阶 导数计算,依据此理论我们可以计算图像二阶导数,提取边缘。 Laplance算子 void Laplacian( InputArray src, Output…

Java代码审计安全篇-SSRF(服务端请求伪造)漏洞

前言: 堕落了三个月,现在因为被找实习而困扰,着实自己能力不足,从今天开始 每天沉淀一点点 ,准备秋招 加油 注意: 本文章参考qax的网络安全java代码审计,记录自己的学习过程,还希望各…

【C++进阶】C++多态概念详解

C多态概念详解 一,多态概念二,多态的定义2.1 多态构成的条件2.2 什么是虚函数2.3 虚函数的重写2.3.1 虚函数重写的特例2.3.2 override和final 2.4 重载和重写(覆盖)和重定义(隐藏)的区别 三,抽象…

性能指标:QPS、TPS、系统吞吐量理解

一、QPS,每秒查询 QPS:Queries Per Second意思是“每秒查询率”,是一台服务器每秒能够相应的查询次数,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准。 互联网中,作为域名系统服务器的机器的性能经…

[leetcode~dfs]1261. 在受污染的二叉树中查找元素

给出一个满足下述规则的二叉树: root.val 0 如果 treeNode.val x 且 treeNode.left ! null,那么 treeNode.left.val 2 * x 1 如果 treeNode.val x 且 treeNode.right ! null,那么 treeNode.right.val 2 * x 2 现在这个二叉树受到「污…

02.JavaScript的运算符和语句

JavaScriptt的运算符和语句 一.运算符 算术运算符 数字是用来计算的,比如:乘法 * 、除法 / 、加法 、减法 - 等等,所以经常和算术运算符一起。 算术运算符:也叫数学运算符,主要包括加、减、乘、除、取余&#xff…

python自学7

第二章第一节面向对象 程序的格式都不一样,每个人填写的方式也有自己的习惯,比如收集个人信息,可能有人用字典字符串或者列表, 类的成员方法 类和对象 构造方法 挨个传输值太麻烦了,也没有方便点的,有&…

每日一题——LeetCode2129.将标题首字母大写

方法一 个人方法 将字符串转为数组&#xff0c;遍历数组&#xff0c;对数组的每一个元素&#xff0c;先全部转为小写&#xff0c;如果当前元素长度大于2&#xff0c;将第一个字符转为大写形式 var capitalizeTitle function(title) {titletitle.split( )for(let i0;i<tit…

linux升级gcc版本详细教程

0.前言 一般linux操作系统默认的gcc版本都比较低&#xff0c;例如centos7系统默认的gcc版本为4.8.5。gcc是从4.7版本开始支持C11的&#xff0c;4.8版本对C11新特性的编译支持还不够完善&#xff0c;因此如果需要更好的体验C11以及以上版本的新特性&#xff0c;需要升级gcc到一个…

VC6.0 新建一个C语言文件

一、新建工程 左上角 文件 --> 新建 --> 选择“一个空工程” 点击“完成”&#xff0c;再点击“确定” 二、新建源文件 左上角 文件 --> 新建 --> 点击“确定” 三、输入代码 #include<stdio.h> int main() {printf("Hello World!\n&q…

Vulnhub靶机:Kioptrix_Level1

一、介绍 运行环境&#xff1a;Virtualbox 攻击机&#xff1a;kali&#xff08;192.168.56.101&#xff09; 靶机&#xff1a;Kioptrix_Level1&#xff08;192.168.56.105&#xff09; 目标&#xff1a;获取靶机root权限和flag 靶机下载地址&#xff1a;https://www.vulnh…

GIS学习笔记(四):GIS数据可视化综合(矢量数据)

矢量数据 arcgis的主要可视化工具&#xff1a;属性 符号系统 符号系统 按类别 这里不会涉及到数字的大小因素&#xff0c;只是按照字符的分类去做可视化 “唯一值”的含义 “建筑年代”字段共有10个年份&#xff0c;一个年份也许有多个数据( eg.1990年的建筑有20个)&…

MySQL 事务的原理以及长事务的预防和处置

transaction_isolation 隔离级别 读未提交 读提交 视图是在每个 SQL 语句开始执行的时候创建的 可重复读 视图是在事务启动时创建的&#xff0c;整个事务存在期间都用这个视图 串行化…