上文中,我们对TCC-Transaction的事务提交阶段主流程进行了详细的解析。上文遗留了一个问题:

如果在事务执行过程中出现了down机、停电、网络异常等情况,事务一致性就无法得到保证,此时应该怎么做?

这个问题在TCC-Transaction框架中是通过定时任务+状态机方式实现的,这种方式也是我们日常开发中经常使用的一种策略。本文,我们对事务恢复主逻辑进行分析,使TCC-Transaction源码解析形成一个闭环。

Read More

TCC分布式事务解决方案在开源界的主要实现为Byte-TCC、TCC-Transaction等。其中笔者了解较多并且业界使用率较高的为TCC-Transaction这一实现。

本文,我将带领读者对TCC-Transaction这一分布式事务框架进行一次源码解析,提高自己的阅读源码的能力,也希望能够对读者深入了解TCC-Transaction有所帮助。

源码下载

源码地址为 https://github.com/changmingxie/tcc-transaction,我们关注最新版本1.2.x。

源码下载后导入IDEA中,项目目录结构如下图:

代码结构

Read More

Spring提供了应用程序事件特性为开发者提供了事件发布和接收事件的能力,它基于观察者模式实现,对于提升应用逻辑的松耦合很有意义。

本文就如何使用Spring事件机制进行较为详细的总结。

Spring事件概述

  • 每一个Spring事件都需要继承ApplicationEvent的类,ApplicationEvent又继承自java.util.EventObject
  • Spring中的任何bean都能够通过实现ApplicationListener接口来监听事件;这里的泛型T就是上面提到的继承了ApplicationEvent的类
  • SpringContext会对实现ApplicationListener接口的任意bean进行自动注册
  • 发布事件是通过ApplicationEventPublisher.publishEvent方法实现的。应用中一般通过ApplicationContext进行事件发布,ApplicationContext实现了ApplicationEventPublisher接口
  • 另一种发布事件的方式是bean实现ApplicationContextAware接口,拿到ApplicationContext实例从而实现事件发布

Read More

我们接着对RocketMQ的事务消息的存储阶段源码进行解析。

事务消息正式发送阶段

首先接着上文,介绍一下事务消息正式发送阶段。

在DefaultMQProducerlmpl.sendKernelImpl方法中设置消息类型为事务消息:

final String tranMsg = msg.getProperty(MessageConst.PROPERTY_TRANSACTION_PREPARED);
if (tranMsg != null && Boolean.parseBoolean(tranMsg)) {
    sysFlag |= MessageSysFlag.TRANSACTION_PREPARED_TYPE;
}

如果消息类型的确是事务消息,则设置sysFlag为事务消息标识== 0x1 << 2。方便broker对消息进行识别。

Read More

  • 开源rocketmq-java客户端sdk使用方法
  • 开源rocketmq-java客户端sdk使用场景解读
  • 混合云场景案例解析
  • 下一站:测试/线上一体化

开源rocketmq-java客户端sdk使用方法

目前通过RocketMQ开源客户端可以访问阿里云RocketMQ的 普通消息、顺序消息、延时/定时消息、事务消息,基本覆盖了云上MQ的主流场景。

我们接着讲解一下如何通过开源SDK使用云上RocketMQ。

本部分的配置项,生产者、消费者应用都需要添加。

我们通过代码案例讲解一下如何使用RocketMQ开源客户端的访问云上的MQ,进行消息发送与消费。

Read More

我们继续对消息消费流程的源码进行解析。

本文主要针对push模式下的消息拉取流程进行解析。我们重点分析集群消费模式,对于广播模式其实很好理解,每个消费者都需要拉取主题下面的所有消费队列的消息。

在集群消费模式下,同一个消费者组内包含了多个消费者实例,同一个topic下存在多个消费队列。对于单个消费者组,其内部维护了一个线程池进行消息消费,这部分内容可以移步 跟我学RocketMQ之消息消费源码解析(2)

之前我们已经研究了消费者的初始化流程,在启动MQClientInstance过程中,启动了一个消息拉取线程PullMessageService进行消息拉取工作。

Read More

RocketMQ消费者在进行消费时,需要遵循 “订阅关系一致” 原则,关于订阅关系一致,我引用阿里云RocketMQ页面的解释,如下图:

rmq0.png

从图中可以提炼出关键词,即:

同一个消费者组订阅的topic、topic中的tag必须保持一致,否则会出现消费不到消息的情况。

举个例子:比如我们有个topic名为DEMO_TOPIC,它有两个tag,分别为tagA、tagB。用一个消费者组demo_group分别订阅tagA、tagB,这时就会出现某个tag对应的消费者消费不到消息的情况。

解决方法就是:针对不同的tag使用不同的消费者组,在上面的案例中的解决方法为:使用demo_group_A 订阅tagA,使用demo_group_B订阅tagB。

提供了解决方案,还是有些意犹未尽,那么我们就深入RocketMQ的源码,感受一下订阅关系一致的机理。

Read More

研究了一段时间框架,有点审美疲劳,今天讲点轻松的,手写一个阻塞队列,实践一把lock+condition。

“等待通知”机制

首先复习一下经典的 “等待通知”机制。

线程首先获取互斥锁,当线程要求的条件不满足时,释放互斥锁,进入等待状态;当要求的条件满足时,通知等待的线程,重新获取互斥锁 –《极客时间-Java并发编程实战》

在Java中实现 “等待通知” 机制一般有两种方式,synchronized/Lock+Condition。

Read More

Fork me on GitHub