企业级广告消息系统项目实战

    - 😃作者简介:前阿里淘天、现字节跳动高级 Java 开发工程师
    - 💻称 号:CSDN 博客专家✨、阿里云博客专家🌟
    - 🔍公众号:云服务小管家。免费💡的阿里云服务器☁ 和云环境直接使用
    - 💪生活:专注于后端技术分享🎓迷茫时可来瞅瞅码农轨迹🚶‍♂️
    - 📋服务:提供模拟面试和简历辅导,提供生产项目。📩内推可私信✉
    - 💬卷卷群:可以和大家一起学习,一起进步👀
    - 🔥如果感觉博主的文章还不错的话,请👍三连支持👍一下博主哦

🌟🌟🌟三连找UP免费领取阿里云服务器,可以测试本项目。

背景

本文已广告系统中的审核视频(广告素材)为例进行讲解。作为一个多租户的中台系统,上游承接着不同的租户。
在这里插入图片描述

抖音租户场景是先投后审,比如我先默认审核通过,等你真正审核的时候如果审核没通过我再把这个视频拉下线。
懂车帝场景是先审后投,只有通过的才投放。
针对这两种场景,抖音租户只需要感知审核拒绝的消息,而懂车帝租户只需要感知审核通过的消息。这里就是一个差异点。
如果租户C感知变更消息呢?如果租户D感知新建消息呢?那兼容这块代码那就屎山雕花了!!!

因此本项目解决是下游系统反向异步通知上游消息的标准化问题。
说人话:binlog消息标准化

方案设计

消息链路设计

通过将binlog消息标准化,然后发到MQ消息上,上游自行消费。通知消息与业务代码解耦。
在这里插入图片描述

层级设计

下面是一个例子,会更好理解一些。
在这里插入图片描述

  • 领域AdDomain
    DDD领域驱动设计中的领域,如果不理解可以理解成订单领域和物流领域两个区别。

  • 领域实体DomainEntity
    风控域的话审核多种类型,针对不同的类型,我这里把他区分为不同的实体,比如图片、视频、文案、落地页等等

  • 数据源DomainDataSource
    以视频为例,有一个主表,有一个附表,如果你是大宽表那就是一个主表。这里是指的真实的物理表映射。
    在这里插入图片描述

  • 领域事件DomainEvent
    在上面的物理表上衍生的事件,还是以视频审核为例。
    主表:新增视频事件、删除视频事件、审核状态变更事件
    附表:外审状态变更事件

技术选型

  • SpringBoot
  • Canal
  • MySQL
  • Guava
    本地缓存全部的配置数据,也不大
  • RocketMQ
    发送的MQ使用RocketMQ而不是Kafka,因为RocketMQ有sql-filter的能力,这样可能把过滤逻辑上抛到broker端而不是消费者。

环境搭建

🌟🌟🌟三连找UP免费领取阿里云服务器,可以测试本项目。

docker安装MySQL

首先,在本地创建一个 MySQL 配置文件,例如 my.cnf,并添加开启二进制日志的配置。

[mysqld]
log-bin=mysql-bin
binlog-format=ROW

docker启动

docker run --name mysql-86-20220702 -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -v /opt/mysql/my.cnf:/etc/mysql/my.cnf mysql:5.7

通过下面命令查看binlog

SHOW MASTER STATUS;   

安装Canal的Server端

步骤1:安装JDK

检查是否已安装

java -version

如果没有安装,请先安装OpenJDK或Oracle JDK:

sudo yum install java-1.8.0-openjdk

步骤2:安装Canal的Server端

使用wget命令下载Canal:

wget https://github.com/alibaba/canal/releases/download/canal-1.1.5/canal.deployer-1.1.5.tar.gz

然后解压下载的文件:

mkdir /usr/local/canal
tar -zxvf canal.deployer-1.1.5.tar.gz -C /usr/local/canal

步骤 3: 配置Canal

进入Canal的配置目录进行必要的配置修改:

cd /usr/local/canal/conf

编辑example/instance.properties文件来设置你的MySQL连接信息:

# 修改为你的MySQL实例地址
canal.instance.master.address=your_mysql_host:3306
# MySQL用户名和密码
canal.instance.dbUsername=root
canal.instance.dbPassword=123456

步骤 4: 启动Canal

cd /usr/local/canal
sh bin/startup.sh

启动后,你可以查看日志文件以确认Canal是否正常运行

tail -f logs/canal/canal.log

源码

https://gitee.com/cbeann/domain-message

启动后可以安装下面的进行测试:

  • 修改代码CanalListener中硬编码的IP,修改为你Canal的Server端IP

  • 把resources/sql/domain_message导入到MySQL中,
    其中【领域AdDomain】【领域实体DomainEntity】【数据源DomainDataSource】【领域消息事件DomainEvent】均在代码中加了几条数据。

  • 测试插入领域事件
    在domain_message库order表新增一条记录,领域事件在DomainEventRepository中的ORDER_NEW
    在这里插入图片描述

  • 测试修改领域事件
    在domain_message库order表修改id=1的order_status变一下,领域事件在DomainEventRepository中的ORDER_STATUS_CHANGE
    在这里插入图片描述

  • 测试删除领域事件
    在domain_message库order表删除id=1的记录,领域事件在DomainEventRepository中的ORDER_DELETE
    在这里插入图片描述

项目面试题

使用了什么设计模式

使用了责任链模式。当收到binlog消息后,第一个处理器是做过滤逻辑(黑白名单用户、无关的表消息)。
第二个处理器是封装Event,第三个处理器是发送MQ。

为什么选择RocketMQ

发送的MQ使用RocketMQ而不是Kafka,因为RocketMQ有sql-filter的能力,这样可能把过滤逻辑上抛到broker端而不是消费者。

消息如何保证不丢失

任何MQ都保证不了,加对账保证100%不丢失。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CBeann

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值