分析activeMq

activeMq 启动报错:

https://blog.youkuaiyun.com/wenghaoduan/article/details/51295388

 

消息怎么保证顺序性,以及消息发送后,但是接收方宕机了,消息怎么保证能重复发送。

即:MQ,如何做到消息必达  https://blog.youkuaiyun.com/babylovewei/article/details/80825946

顺序性的保证在 后面学习 rocketMq时 研究。

 

DCL模型

定时补偿+幂等消费
推拉结合
Event-Sourcing和MQ,实现RPC式分布式事务

 

java中,回调函数的使用

见网址: https://blog.youkuaiyun.com/u010211479/article/details/51490152

https://blog.youkuaiyun.com/jiahao1186/article/details/81988866

 

写一个基于 activeMq 的分布式事务项目:

以用户注册场景为例,需求是新用户注册之后 给该用户现在一条积分记录。 假设用户有服务和积分两个服务,用户服务使用数据库db1, 积分服务使用数据库db2. 服务调用者只需要使用用户新增服务, 由服务内部 既保证db1 新增用户记录, db2新增积分记录。 这是一个分布式问题。

通过 本地表 加上 消息队列的模式来解决这个问题。

 

两个需要考虑的意外场景:

第一:用户服务在保存用户记录后 没来得及给消息队列发消息就 宕机了,得保证新增用户记录后 一定有消息发送到消息队列。

第二:积分服务接收到消息后 没来得及保存积分记录就宕机了,得保证重启系统后,不丢失积分记录。

 

一共四张表:其实是通过事件表和新增用户记录的db1 的本地数据库事务的绑定 以及 事件表和新增积分记录的db2 的本地数据库事务的绑定 来达到 事务一致性。

CREATE TABLE `t_user` (
  `id` varchar(50) NOT NULL,
  `user_name` varchar(100) DEFAULT NULL COMMENT '用户名',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


DROP TABLE IF EXISTS `t_event`;

CREATE TABLE `t_event` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `type` varchar(30) DEFAULT NULL COMMENT '事件类型',
  `process` varchar(30) DEFAULT NULL COMMENT '表示事件进行到了哪个环节',
  `content` text COMMENT '事件包含的内容',
  `create_time` datetime DEFAULT NULL,
  `update_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
;

 


CREATE TABLE `t_point` (
  `id` varchar(50) NOT NULL,
  `user_id` varchar(50) DEFAULT NULL COMMENT '关联的用户ID',
  `amount` int(11) DEFAULT NULL COMMENT '积分金额',
  PRIMARY KEY (`id`)
) ENGINE=Inno DB DEFAULT CHARSET=utf8
;


DROP TABLE IF EXISTS `t_event`;

CREATE TABLE `t_event` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `type` varchar(30) DEFAULT NULL COMMENT '事件类型',
  `process` varchar(30) DEFAULT NULL COMMENT '表示事件进行到了哪个环节',
  `content` text COMMENT '事件包含的内容',
  `create_time` datetime DEFAULT NULL,
  `update_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
;

 

整个的操作图 如下:

 

操作图描述如下:

db1:用户表t_user, 事件表t_event , 

db2:积分表t_point , 事件表t_event  。

 

第一步:用户服务在接受 到请求之后再 t_user 创建一条用户记录,并在t_event新增一条process为NEW的事件记录, 同时要创建的积分数据 以JSON字符串的形式 保存到 db1的t_event的content中, 提交事务。

第二步:在用户系统中,开启一个定时任务 查询db1的t_event表中 process为NEW的记录, 一旦有记录,则向消息队列发送消息, 消息内容就是第一步保存在 db1的t_event的content中的数据; 消息发送成功后,把process改为PUBLISHED,提交事务。

第三步:积分系统 接收到消息后,在db2的t_event表中 新增一条process为 PUBLISHED的记录, content保存接收到的消息内容, 保存t_event成功后返回,提交事务。

第四步:在积分系统中 开始定时任务, 轮询db2的t_event表 中 所有 proesss为 PUBLISHED的记录, 拿到表记录后将 content字段内容 转化成积分对象,保存积分记录, 保存成功后,修改t_event的process的 PROCESSED, 提交事务。

结束。

 

该方案 基本上能保证两个数据源db1和db2的一致性, 但是没有考虑mq的稳定性, 以及逻辑设计的比较复杂。

 

后面rocketMq 有更好的一致性方案。

 

代码地址:

git@github.com:tuyf/activeMq.git

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值