导航:首页 > 源码编译 > rocketmq主从同步数据源码

rocketmq主从同步数据源码

发布时间:2022-09-01 01:43:48

⑴ rocketmq的9876端口可以改吗

⑵ RocketMQ的事务消息

RocketMQ的事务消息,是指发送消息事件和其他事件需要同时成功或同时失败。比如银行转账,A银行的某账户要转一万元到B银行的某账户。A银行发送“B银行账户增加一万元”这个消息,要和“从A银行账户扣除一万元”这个操作同时成功或者同时失败。
RocketMQ采用两阶段提交的方式实现事务消息,TransactionMQProcer处理上面情况的流程是,先发一个“准备从B银行账户增加一万元”的消息,发送成功后做从A银行账户扣除一万元的操作,根据操作结果是否成功,确定之前的“准备从B银行账户增加一万元”的消息是做commit还是rollback,具体流程如下:
1)发送方向RocketMQ发送“待确认”消息。
2)RocketMQ将收到的“待确认”消息持久化成功后,向发送方回复消息已经发送成功,此时第一阶段消息发送完成。
3)发送方开始执行本地事件逻辑。
4)发送方根据本地事件执行结果向RocketMQ发送二次确认(Commit或是Rollback)消息,RocketMQ收到Commit状态则将第一阶段消息标记为可投递,订阅方将能够收到该消息;收到Rollback状态则删除第一阶段的消息,订阅方接收不到该消息。
5)如果出现异常情况,步骤4)提交的二次确认最终未到达RocketMQ,服务器在经过固定时间段后将对“待确认”消息发起回查请求。
6)发送方收到消息回查请求后(如果发送一阶段消息的Procer不能工作,回查请求将被发送到和Procer在同一个Group里的其他Procer),通过检查对应消息的本地事件执行结果返回Commit或Roolback状态。
7)RocketMQ收到回查请求后,按照步骤4)的逻辑处理。

上面的逻辑似乎很好地实现了事务消息功能,它也是RocketMQ之前的版本实现事务消息的逻辑。
但是因为RocketMQ依赖将数据顺序写到磁盘这个特征来提高性能,步骤4)却需要更改第一阶段消息的状态,这样会造成磁盘Catch的脏页过多,降低系统的性能。所以RocketMQ在4.x的版本中将这部分功能去除。系统中的一些上层Class都还在,用户可以根据实际需求实现自己的事务功能。
客户端有三个类来支持用户实现事务消息,
第一个类是LocalTransaction-Executer,用来实例化步骤3)的逻辑,根据情况返回LocalTransactionState.ROLLBACK_MESSAGE或者
LocalTransactionState.COMMIT_MESSAGE状态。
第二个类是TransactionMQProcer,它的用法和DefaultMQProcer类似,要通过它启动一个Procer并发消息,但是比DefaultMQProcer多设置本地事务处理函数和回查状态函数。
第三个类是TransactionCheckListener,实现步骤5)中MQ服务器的回查请求,返回LocalTransactionState.ROLLBACK_MESSAGE或者LocalTransactionState.COMMIT_MESSAGE

上图说明了事务消息的大致方案,其中分为两个流程:正常事务消息的发送及提交、事务消息的补偿流程。
1.事务消息发送及提交:
(1) 发送消息(half消息)。
(2) 服务端响应消息写入结果。
(3) 根据发送结果执行本地事务(如果写入失败,此时half消息对业务不可见,本地逻辑不执行)。
(4) 根据本地事务状态执行Commit或者Rollback(Commit操作生成消息索引,消息对消费者可见)。
2.补偿流程:
(1) 对没有Commit/Rollback的事务消息(pending状态的消息),从服务端发起一次“回查”。
(2) Procer收到回查消息,检查回查消息对应的本地事务的状态。
(3) 根据本地事务状态,重新Commit或者Rollback。
其中,补偿阶段用于解决消息Commit或者Rollback发生超时或者失败的情况。

在RocketMQ事务消息的主要流程中,一阶段的消息如何对用户不可见。其中,事务消息相对普通消息最大的特点就是一阶段发送的消息对用户是不可见的。那么,如何做到写入消息但是对用户不可见呢?RocketMQ事务消息的做法是:如果消息是half消息,将备份原消息的主题与消息消费队列,然后改变主题为RMQ_SYS_TRANS_HALF_TOPIC。由于消费组未订阅该主题,故消费端无法消费half类型的消息。然后二阶段会显示执行提交或者回滚half消息(逻辑删除)。当然,为了防止二阶段操作失败,RocketMQ会开启一个定时任务,从Topic为RMQ_SYS_TRANS_HALF_TOPIC中拉取消息进行消费,根据生产者组获取一个服务提供者发送回查事务状态请求,根据事务状态来决定是提交或回滚消息。
在RocketMQ中,消息在服务端的存储结构如下,每条消息都会有对应的索引信息,Consumer通 过ConsumeQueue这个二级索引来读取消息实体内容,其流程如下:

RocketMQ的具体实现策略是:写入的如果事务消息,对消息的Topic和Queue等属性进行替换,同时将原来的Topic和Queue信息存储到消息的属性中,正因为消息主题被替换,故消息并不会转发到该原主题的消息消费队列,消费者无法感知消息的存在,不会消费。其实改变消息主题是RocketMQ的常用“套路”,回想一下延时消息的实现机制。RMQ_SYS_TRANS_HALF_TOPIC

在完成一阶段写入一条对用户不可见的消息后,二阶段如果是Commit操作,则需要让消息对用户可见;如果是Rollback则需要撤销一阶段的消息。先说Rollback的情况。对于Rollback,本身一阶段的消息对用户是不可见的,其实不需要真正撤销消息(实际上RocketMQ也无法去真正的删除一条消息,因为是顺序写文件的)。但是区别于这条消息没有确定状态(Pending状态,事务悬而未决),需要一个操作来标识这条消息的最终状态。RocketMQ事务消息方案中引入了Op消息的概念,用Op消息标识事务消息已经确定的状态(Commit或者Rollback)。如果一条事务消息没有对应的Op消息,说明这个事务的状态还无法确定(可能是二阶段失败了)。引入Op消息后,事务消息无论是Commit或者Rollback都会记录一个Op操作。Commit相对于Rollback只是在写入Op消息前创建Half消息的索引。

RocketMQ将Op消息写入到全局一个特定的Topic中通过源码中的方法—
TransactionalMessageUtil.buildOpTopic();这个Topic是一个内部的Topic(像Half消息的Topic一样),不会被用户消费。Op消息的内容为对应的Half消息的存储的Offset,这样通过Op消息能索引到Half消息进行后续的回查操作。

在执行二阶段Commit操作时,需要构建出Half消息的索引。一阶段的Half消息由于是写到一个特殊的Topic,所以二阶段构建索引时需要读取出Half消息,并将Topic和Queue替换成真正的目标的Topic和Queue,之后通过一次普通消息的写入操作来生成一条对用户可见的消息。所以RocketMQ事务消息二阶段其实是利用了一阶段存储的消息的内容,在二阶段时恢复出一条完整的普通消息,然后走一遍消息写入流程。

如果在RocketMQ事务消息的二阶段过程中失败了,例如在做Commit操作时,出现网络问题导致Commit失败,那么需要通过一定的策略使这条消息最终被Commit。RocketMQ采用了一种补偿机制,称为“回查”。Broker端对未确定状态的消息发起回查,将消息发送到对应的Procer端(同一个Group的Procer),由Procer根据消息来检查本地事务的状态,进而执行Commit或者Rollback。
Broker端通过对比Half消息和Op消息进行事务消息的回查并且推进CheckPoint(记录那些事务消息的状态是确定的)。
值得注意的是,rocketmq并不会无休止的的信息事务状态回查,默认回查15次,如果15次回查还是无法得知事务状态,rocketmq默认回滚该消息。

TxConsumer类实现

⑶ 消息队列(mq)是什么

生产者先将消息投递一个叫队列的容器中,然后再从这个容器中取出消息,最后再转发给消费者。

消息队列是 Microsoft 的消息处理技术,它在任何安装 Microsoft Windows 的计算机组合中,为任何应用程序提供消息处理和消息队列功能,无论这些计算机是否在同一个网络上或者是否同时联机。

消息队列网络是能够相互间来回发送消息的任何一组计算机。网络中的不同计算机在确保消息顺利处理的过程中扮演不同的角色。它们中有些提供路由信息以确定如何发送消息,有些保存整个网络的重要信息,而有些只是发送和接收消息。

消息队列的类型介绍:

消息队列目前主要有两种类型:POSIX消息队列以及系统V消息队列,系统V消息队列目前被大量使用。每个消息队列都有一个队列头,用结构struct msg_queue来描述。队列头中包含了该消息队列的大量信息。包括消息队列键值、用户ID、组ID、消息队列中消息数目等等。

消息队列就是一个消息的链表,可以把消息看作一个记录,具有特定的格式以及特定的优先级。对消息队列有写权限的进程可以向消息队列中按照一定的规则添加新消息;对消息队列有读权限的进程则可以从消息队列中读走消息。消息队列是随内核持续的。





⑷ rocketmq 同步双写 什么意思

rocket league 4-pack的中文翻译rocket league 4-pack火箭联赛4包-------------------------------如有疑问,可继续追问,如果满意,请采纳,谢谢。

⑸ 怎么指定rocketmq的jdk

一:RocketMQ简介RocketMQ是一款分布式、队列模型的消息中间件,具有以下特点:1.能够保证严格的消息顺序2.提供丰富的消息拉取模式3.高效的订阅者水平扩展能力4.实时的消息订阅机制5.亿级消息堆积能力二:安装RocketMQ下载源码首先我们从githup上获取RocketMQ的源码,目前最新的版本为3.5.8,下载地址为:或者wget/alibaba/RocketMQ/archive/v3.5.8.tar.gz。请注意:此时我们下载的是源码,直接解压时不能用的,所以我们需要编译之后才能使用。编译源码在进行编译源码之前我们需要安装JDK。如果你已经安装过了,请跳过这里。如果你还没有安装过JDK,请参考这篇文章(Linux环境下安装JDK)。然后我们还需要安装一下Maven。Maven的安装还是比较简单,只需要去官方上下载的安装吧,然后直接解压,再配置一下环境变量就OK。接下来我们把刚才下载来的RockeMQ的源码解压到/usr/local/rockemq-source文件夹中。在源码中有一个Install.sh。如图所示:。运行shinstall.sh。在编译完成之后,我们只要target目录下的alibaba-rocketmq这个文件夹中内容,把alibaba-rocketmq文件夹中的内容移动到/usr/local/rocketmq中。如果你不想编译的话,可以从这里下载编译之后的rocketmq。(rocketmq3.5.8)。配置环境变量接下来我们需要配置一下环境变量。在终端中输入以下命令:vi/etc/profile,在文件的末尾中添加如下两句话:exportrocketmq=/usr/local/rocketmqexportPATH=$PATH:$rocketmq/bin。接下来我们使配置的换将变量生效:source/etc/profile.三:启动RocketMQ接下来我们启动一下刚才编译的RocketMQ.在启动之前我们需要修改一下RocketMQ启动的内存大小(如果你的系统内存比较大的话,请忽略)。我们进入到/usr/local/rocketmq/bin中,在终端中输入以下命令修改mqnamesrv的内存大小:virunserver.sh.修改为如图的内容:,接下来修改broker的内存大小:virunbroker.sh:启动mqnameserver进入到/usr/local/rocketmq/bin中输入以下命令:nohupshmqnamesrv>~/logs/rocketmqlogs/namesrv.log2>&1&。注意最后的这个&不要少。启动mqbroker进入到/usr/local/rocketmq/bin中输入以下命令:nohupshmqbroker-nlocalhost:9876autoCreateTopicEnable=true>~/logs/rocketmqlogs/broker.log2>&1&。注意:localhost可以换成你刚才启动mqnamesrv的IP。autoCreateTopicEnable=true这句话不要少了。最后的&也不要少了。我们可以通过psaux|grepjava命令来查看启动的情况。到此,rocketmq的安装完毕。四:RocketMQ的小例子procer:[java]viewplainpackagecom.zkn.newlearn.rocketmq;importcom.alibaba.rocketmq.client.exception.MQBrokerException;importcom.alibaba.rocketmq.client.exception.MQClientException;importcom.alibaba.rocketmq.client.procer.DefaultMQProcer;importcom.alibaba.rocketmq.client.procer.SendResult;importcom.alibaba.rocketmq.common.message.Message;importcom.alibaba.rocketmq.remoting.exception.RemotingException;importjava.util.concurrent.TimeUnit;/***Createdbyzknon2016/10/27.*/publicclassProcerTest01{publicstaticvoidmain(String[]args){/***一个应用创建一个Procer,由应用来维护此对象,可以设置为全局对象或者单例*注意:ProcerGroupName需要由应用来保证唯一*ProcerGroup这个概念发送普通的消息时,作用不大,但是发送分布式事务消息时,比较关键,*因为服务器会回查这个Group下的任意一个Procer*/DefaultMQProcerprocer=newDefaultMQProcer("ProcerGroupName");//procer.setNamesrvAddr("192.168.180.1:9876");procer.setNamesrvAddr("192.168.180.133:9876");procer.setInstanceName("Procer");/***Procer对象在使用之前必须要调用start初始化,初始化一次即可*注意:切记不可以在每次发送消息时,都调用start方法*/try{procer.start();}catch(MQClientExceptione){e.printStackTrace();}for(inti=0;i<100;i++){try{/***下面这段代码表明一个Procer对象可以发送多个topic,多个tag的消息。*注意:send方法是同步调用,只要不抛异常就标识成功。但是发送成功也可会有多种状态,*例如消息写入Master成功,但是Slave不成功,这种情况消息属于成功,但是对于个别应用如果对消息可靠性要求极高,*需要对这种情况做处理。另外,消息可能会存在发送失败的情况,失败重试由应用来处理。*/{Messagemsg=newMessage("TopicTest1",//topic"TagA",//tag"OrderID001",//key("HelloMetaQ").getBytes());//bodySendResultsendResult=procer.send(msg);System.out.println(sendResult);}{Messagemsg=newMessage("TopicTest2","TagB","OrderID001",("HelloMetaQTagB".getBytes()));SendResultsendResult=procer.send(msg);System.out.println(sendResult);}{Messagemsg=newMessage("TopicTest3","TagC","OrderID001",("HelloMetaQTagC").getBytes());SendResultsendResult=procer.send(msg);System.out.println(sendResult);}TimeUnit.MILLISECONDS.sleep(1000);}catch(MQClientExceptione){e.printStackTrace();}catch(InterruptedExceptione){e.printStackTrace();}catch(RemotingExceptione){e.printStackTrace();}catch(MQBrokerExceptione){e.printStackTrace();}}/***应用退出时,要调用shutdown来清理资源,关闭网络连接,从MetaQ服务器上注销自己*注意:我们建议应用在JBOSS、Tomcat等容器的退出销毁方法里调用shutdown方法*/procer.shutdown();}}

⑹ rocketmq 发送失败一般怎么处理

一:RocketMQ简介
RocketMQ是一款分布式、队列模型的消息中间件,具有以下特点:

1.能够保证严格的消息顺序

2.提供丰富的消息拉取模式

3.高效的订阅者水平扩展能力

4.实时的消息订阅机制

5.亿级消息堆积能力
二:安装RocketMQ
下载源码
首先我们从githup上获取RocketMQ的源码,目前最新的版本为3.5.8,下载地址为: 或者 wget /alibaba/RocketMQ/archive/v3.5.8.tar.gz。请注意:此时我们下载的是源码,直接解压时不能用的,所以我们需要编译之后才能使用。
编译源码
在进行编译源码之前我们需要安装JDK。如果你已经安装过了,请跳过这里。如果你还没有安装过JDK,请参考这篇文章(Linux环境下安装JDK)。然后我们还需要安装一下Maven。Maven的安装还是比较简单,只需要去官方上下载的安装吧,然后直接解压,再配置一下环境变量就OK。接下来我们把刚才下载来的RockeMQ的源码解压到/usr/local/rockemq-source文件夹中。在源码中有一个Install.sh。如图所示:
。运行sh install.sh。在编译完成之后,我们只要target目录下的alibaba-rocketmq这个文件夹中内容,把alibaba-rocketmq文件夹中的内容移动到/usr/local/rocketmq中。如果你不想编译的话,可以从这里下载编译之后的rocketmq。(rocketmq3.5.8)。
配置环境变量
接下来我们需要配置一下环境变量。在终端中输入以下命令:vi /etc/profile ,在文件的末尾中添加如下两句话:export rocketmq=/usr/local/rocketmq export PATH=$PATH:$rocketmq/bin。接下来我们使配置的换将变量生效:source /etc/profile.
三:启动RocketMQ
接下来我们启动一下刚才编译的RocketMQ.在启动之前我们需要修改一下RocketMQ启动的内存大小(如果你的系统内存比较大的话,请忽略)。我们进入到/usr/local/rocketmq/bin中,在终端中输入以下命令修改mqnamesrv的内存大小:vi runserver.sh.修改为如图的内容:
,接下来修改broker的内存大小:vi runbroker.sh:

启动mqnameserver
进入到/usr/local/rocketmq/bin中输入以下命令:nohup sh mqnamesrv > ~/logs/rocketmqlogs/namesrv.log 2>&1 &。注意最后的这个 & 不要少。
启动mqbroker
进入到/usr/local/rocketmq/bin中输入以下命令:nohup sh mqbroker -n localhost:9876 autoCreateTopicEnable=true > ~/logs/rocketmqlogs/broker.log 2>&1 &。注意:localhost可以换成你刚才启动mqnamesrv的IP。autoCreateTopicEnable=true
这句话不要少了。最后的 & 也不要少了。
我们可以通过 ps aux | grep java命令来查看启动的情况。

到此,rocketmq的安装完毕。
四:RocketMQ的小例子
procer:

[java] view plain
package com.zkn.newlearn.rocketmq;

import com.alibaba.rocketmq.client.exception.MQBrokerException;
import com.alibaba.rocketmq.client.exception.MQClientException;
import com.alibaba.rocketmq.client.procer.DefaultMQProcer;
import com.alibaba.rocketmq.client.procer.SendResult;
import com.alibaba.rocketmq.common.message.Message;
import com.alibaba.rocketmq.remoting.exception.RemotingException;

import java.util.concurrent.TimeUnit;

/**
* Created by zkn on 2016/10/27.
*/
public class ProcerTest01 {

public static void main(String[] args) {

/**
* 一个应用创建一个Procer,由应用来维护此对象,可以设置为全局对象或者单例<br>
* 注意:ProcerGroupName需要由应用来保证唯一<br>
* ProcerGroup这个概念发送普通的消息时,作用不大,但是发送分布式事务消息时,比较关键,
* 因为服务器会回查这个Group下的任意一个Procer
*/
DefaultMQProcer procer = new DefaultMQProcer("ProcerGroupName");
//procer.setNamesrvAddr("192.168.180.1:9876");
procer.setNamesrvAddr("192.168.180.133:9876");
procer.setInstanceName("Procer");
/**
* Procer对象在使用之前必须要调用start初始化,初始化一次即可<br>
* 注意:切记不可以在每次发送消息时,都调用start方法
*/
try {
procer.start();
} catch (MQClientException e) {
e.printStackTrace();
}
for (int i = 0; i < 100; i++) {
try {
/**
* 下面这段代码表明一个Procer对象可以发送多个topic,多个tag的消息。
* 注意:send方法是同步调用,只要不抛异常就标识成功。但是发送成功也可会有多种状态,<br>
* 例如消息写入Master成功,但是Slave不成功,这种情况消息属于成功,但是对于个别应用如果对消息可靠性要求极高,<br>
* 需要对这种情况做处理。另外,消息可能会存在发送失败的情况,失败重试由应用来处理。
*/
{
Message msg = new Message("TopicTest1",// topic
"TagA",// tag
"OrderID001",// key
("Hello MetaQ").getBytes());// body
SendResult sendResult = procer.send(msg);
System.out.println(sendResult);
}

{
Message msg = new Message("TopicTest2",
"TagB",
"OrderID001",
("Hello MetaQ TagB".getBytes()));

SendResult sendResult = procer.send(msg);
System.out.println(sendResult);
}

{
Message msg = new Message("TopicTest3",
"TagC",
"OrderID001",
("Hello MetaQ TagC").getBytes());

SendResult sendResult = procer.send(msg);

System.out.println(sendResult);
}

TimeUnit.MILLISECONDS.sleep(1000);

} catch (MQClientException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (RemotingException e) {
e.printStackTrace();
} catch (MQBrokerException e) {
e.printStackTrace();
}
}
/**
* 应用退出时,要调用shutdown来清理资源,关闭网络连接,从MetaQ服务器上注销自己
* 注意:我们建议应用在JBOSS、Tomcat等容器的退出销毁方法里调用shutdown方法
*/
procer.shutdown();
}
}

⑺ 网易传媒技术团队:消息中间件实现延迟队列的应用与实践

早期需要延迟处理的业务场景,更多的是通过定时任务扫表,然后执行满足条件的记录,具有频率高、命中低、资源消耗大的缺点。随着消息中间件的普及,延迟消息可以很好的处理这种场景,本文主要介绍延迟消息的使用场景以及基于常见的消息中间件如何实现延迟队列,最后给出了一个在网易公开课使用延迟队列的实践。

1、有效期:限时活动、拼团。。。

2、超时处理:取消超时未支付订单、超时自动确认收货。。。

4、重试:网络异常重试、打车派单、依赖条件未满足重试。。。

5、定时任务:智能设备定时启动。。。

1、RabbitMQ

1)简介:基于AMQP协议,使用Erlang编写,实现了一个Broker框架

a、Broker:接收和分发消息的代理服务器

b、Virtual Host:虚拟主机之间相互隔离,可理解为一个虚拟主机对应一个消息服务

c、Exchange:交换机,消息发送到指定虚拟机的交换机上

d、Binding:交换机与队列绑定,并通过路由策略和routingKey将消息投递到一个或多个队列中

e、Queue:存放消息的队列,FIFO,可持久化

f、Channel:信道,消费者通过信道消费消息,一个TCP连接上可同时创建成百上千个信道,作为消息隔离

2)延迟队列实现:RabbitMQ的延迟队列基于消息的存活时间TTL(Time To Live)和死信交换机DLE(Dead Letter Exchanges)实现

a、TTL:RabbitMQ支持对队列和消息各自设置存活时间,取二者中较小的值,即队列无消费者连接或消息在队列中一直未被消费的过期时间

b、DLE:过期的消息通过绑定的死信交换机,路由到指定的死信队列,消费者实际上消费的是死信队列上的消息

3)缺点:

a、配置麻烦,额外增加一个死信交换机和一个死信队列的配置

b、脆弱性,配置错误或者生产者消费者连接的队列错误都有可能造成延迟失效

2、RocketMQ

1)简介:来源于阿里,目前为Apache顶级开源项目,使用Java编写,基于长轮询的拉取方式,支持事务消息,并解决了顺序消息和海量堆积的问题

a、Broker:存放Topic并根据读取Procer的提交日志,将逻辑上的一个Topic分多个Queue存储,每个Queue上存储消息在提交日志上的位置

b、Name Server:无状态的节点,维护Topic与Broker的对应关系以及Broker的主从关系

2)延迟队列实现:RocketMQ发送延时消息时先把消息按照延迟时间段发送到指定的队列中(rocketmq把每种延迟时间段的消息都存放到同一个队列中),然后通过一个定时器进行轮训这些队列,查看消息是否到期,如果到期就把这个消息发送到指定topic的队列中

3)缺点:延迟时间粒度受限制(1s/5s/10s/30s/1m/2m/3m/4m/5m/6m/7m/8m/9m/10m/20m/30m/1h/2h)

3、Kafka

1)简介:来源于Linkedin,目前为Apache顶级开源项目,使用Scala和Java编写,基于zookeeper协调的分布式、流处理的日志系统,升级版为Jafka

2)延迟队列实现:Kafka支持延时生产、延时拉取、延时删除等,其基于时间轮和JDK的DelayQueue实现

a、时间轮(TimingWheel):是一个存储定时任务的环形队列,底层采用数组实现,数组中的每个元素可以存放一个定时任务列表

b、定时任务列表(TimerTaskList):是一个环形的双向链表,链表中的每一项表示的都是定时任务项

c、定时任务项(TimerTaskEntry):封装了真正的定时任务TimerTask

d、层级时间轮:当任务的到期时间超过了当前时间轮所表示的时间范围时,就会尝试添加到上层时间轮中,类似于钟表就是一个三级时间轮

e、JDK DelayQueue:存储TimerTaskList,并根据其expiration来推进时间轮的时间,每推进一次除执行相应任务列表外,层级时间轮也会进行相应调整

3)缺点:

a、延迟精度取决于时间格设置

b、延迟任务除由超时触发还可能被外部事件触发而执行

4、ActiveMQ

1)简介:基于JMS协议,Java编写的Apache顶级开源项目,支持点对点和发布订阅两种模式。

a、点对点(point-to-point):消息发送到指定的队列,每条消息只有一个消费者能够消费,基于拉模型

b、发布订阅(publish/subscribe):消息发送到主题Topic上,每条消息会被订阅该Topic的所有消费者各自消费,基于推模型

2)延迟队列实现:需要延迟的消息会先存储在JobStore中,通过异步线程任务JobScheler将到达投递时间的消息投递到相应队列上

a、Broker Filter:Broker中定义了一系列BrokerFilter的子类构成拦截器链,按顺序对消息进行相应处理

b、ScheleBroker:当消息中指定了延迟相关属性,并且jobId为空时,会生成调度任务存储到JobStore中,此时消息不会进入到队列

c、JobStore:基于BTree存储,key为任务执行的时间戳,value为该时间戳下需要执行的任务列表

d、JobScheler:取JobStore中最小的key执行(调度时间最早的),执行时间<=当前时间,将该任务列表依次投递到所属的队列,对于需要重复投递和投递失败的会再次存入JobStore中。

注: 此处JobScheler的执行时间间隔可动态变化,默认0.5s,有新任务时会立即执行(Object->notifyAll())并设置时间间隔为0.1s,没有新任务后,下次执行时间为最近任务的调度执行时间。

3)缺点:投递到队列失败,将消息重新存入JobStore,消息调度执行时间=系统当前时间+延迟时间,会导致消息被真实投递的时间可能为设置的延迟时间的整数倍

5、Redis

1)简介:基于Key-Value的NoSQL数据库,由于其极高的性能常被当作缓存来使用,其数据结构支持:字符串、哈希、列表、集合、有序集合

2)延迟队列实现:Redis的延迟队列基于有序集合,score为执行时间戳,value为任务实体或任务实体引用

3)缺点:

a、实现复杂,本身不支持

b、完全基于内存,延迟时间长浪费内存资源

6、消息队列对比

1、公开课延迟队列技术选型

1)业务场景:关闭超时未支付订单、限时优惠活动、拼团

2)性能要求:订单、活动、拼团 数据量可控,上述MQ均能满足要求

3)可靠性:使用ActiveMQ、RabbitMQ、RocketMQ作为延迟队列更普遍

4)可用性:ActiveMQ、RocketMQ自身支持延迟队列功能,且目前公开课业务中使用的中间件为ActiveMQ和Kafka

5)延迟时间灵活:活动的开始和结束时间比较灵活,而RocketMQ时间粒度较粗,Kafka会依赖时间格有精度缺失

结论: 最终选择ActiveMQ来作为延迟队列

2、业务场景:关闭未支付订单

1)关闭微信未支付订单

2)关闭IOS未支付订单

3、ActiveMQ使用方式

1)activemq.xml中支持调度任务

2)发送消息时,设置message的延迟属性

其中:

a、延迟处理

AMQ_SCHEDULED_DELAY:设置多长时间后,投递给消费者(毫秒)

b、重复投递

AMQ_SCHEDULED_PERIOD:重复投递时间间隔(毫秒)

AMQ_SCHEDULED_REPEAT:重复投递次数

c、指定调度计划

AMQ_SCHEDULED_CRON:corn正则表达式

4、公开课使用中进行的优化

1)可靠性:针对实际投递时间可能翻倍的问题,结合ActiveMQ的重复投递,在消费者逻辑中做幂等处理来保证延迟时间的准确性

2)可追溯性:延迟消息及消费情况做数据库冗余存储

3)易用性:业务上定义好延迟枚举类型,直接使用JmsDelayTemplate发送,无需关心数据备份和参数等细节

1、无论是基于死信队列还是基于数据先存储后投递,本质上都是将延迟待发送的消息数据与正常订阅的队列分开存储,从而降低耦合度

2、无论是检查队头消息TTL还是调度存储的延迟数据,本质上都是通过定时任务来完成的,但是定时任务的触发策略以及延迟数据的存储方式决定了不同中间件之间的性能优劣

张浩,2018年加入网易传媒,高级Java开发工程师,目前在网易公开课主要做支付财务体系、版本迭代相关的工作。

⑻ 各位大牛,从github下载的rocketmq源码,怎么导入到myeclipse中运行调试,直接导入maven项目没有目录结构

可能是版本的问题。建议重新下载安装看看,
myeclipse2017安装破解说明
注意!下载包中有myeclipse 2017 ci8 windows在线安装包下载以及离线安装包下载,附破解文件,小编建议使用离线下载包进行安装。
1、首先点击“myeclipse-2017-ci-8-online-installer-windows.exe”程序运行安装,点击“next”下一步;
2、选择“我同意”许可协议,点击“next”下一步;
3、选择安装目录,您可以自行选择,小编建议默认,点击“下一步”;
4、选择您的电脑系统32/64位,小编的是64位,点击“next”下一步;
5、正在安装,文件有点大,请等待片刻;
6、安装完成
MyEclipse2017破解版:http://www.xue51.com/soft/1207.html

阅读全文

与rocketmq主从同步数据源码相关的资料

热点内容
我的世界如何在服务器里设置货币 浏览:591
酷猫系统如何安装app 浏览:636
邮寄服务器是干什么用 浏览:159
解除电脑加密文件夹 浏览:358
androidcheckbox组 浏览:546
linux在线安装软件 浏览:823
如何设置手机安卓版 浏览:285
简历pdfword 浏览:123
锋云视频服务器网关设置 浏览:162
linux服务器如何查看网卡型号 浏览:142
加密相册误删了怎么恢复 浏览:380
安卓代练通怎么下载 浏览:518
知道域名如何查询服务器 浏览:907
方舟手游怎么才能进服务器 浏览:289
抖音算法自动爆音 浏览:24
linux修改网卡配置 浏览:913
云服务器和本地服务器数据 浏览:843
在家如何创业python 浏览:225
编译原理好课 浏览:718
python中实数的表示 浏览:372