在 ActiveMQ 中,broker 集中管理持久的、临时的 queue 和 topic。

public class BrokerFilter implements Broker {
// 省略其他代码
protected final Broker next;
}

最终的 Broker 链是这样的:

StatisticsBroker -> TransactionBroker -> CompositeDestinationBroker -> AdvisoryBroker -> ManagedRegionBroker

创建Broker 链:

// org.apache.activemq.broker.BrokerService
protected Broker createBroker() throws Exception {
// 创建 RegionBroker
regionBroker = createRegionBroker();
// 添加拦截器
Broker broker = addInterceptors(regionBroker);
// Add a filter that will stop access to the broker once stopped
broker = new MutableBrokerFilter(broker) {
Broker old; @Override
public void stop() throws Exception {
old = this.next.getAndSet(new ErrorBroker("Broker has been stopped: " + this) {
// Just ignore additional stop actions.
@Override
public void stop() throws Exception {
}
});
old.stop();
} @Override
public void start() throws Exception {
if (forceStart && old != null) {
this.next.set(old);
}
getNext().start();
}
};
return broker;
}

创建 RegionBroker:

protected Broker createRegionBroker(DestinationInterceptor destinationInterceptor) throws IOException {
RegionBroker regionBroker;
if (isUseJmx()) {
try {
regionBroker = new ManagedRegionBroker(this, getManagementContext(), getBrokerObjectName(),
getTaskRunnerFactory(), getConsumerSystemUsage(), destinationFactory, destinationInterceptor,getScheduler(),getExecutor());
} catch(MalformedObjectNameException me){
LOG.warn("Cannot create ManagedRegionBroker due " + me.getMessage(), me);
throw new IOException(me);
}
} else {
regionBroker = new RegionBroker(this, getTaskRunnerFactory(), getConsumerSystemUsage(), destinationFactory,
destinationInterceptor,getScheduler(),getExecutor());
}
destinationFactory.setRegionBroker(regionBroker);
regionBroker.setKeepDurableSubsActive(keepDurableSubsActive);
regionBroker.setBrokerName(getBrokerName());
regionBroker.getDestinationStatistics().setEnabled(enableStatistics);
regionBroker.setAllowTempAutoCreationOnSend(isAllowTempAutoCreationOnSend());
if (brokerId != null) {
regionBroker.setBrokerId(brokerId);
}
return regionBroker;
}

为RegionBroker添加BrokerFilter:

protected Broker addInterceptors(Broker broker) throws Exception {
if (isSchedulerSupport()) {
SchedulerBroker sb = new SchedulerBroker(this, broker, getJobSchedulerStore());
if (isUseJmx()) {
JobSchedulerViewMBean view = new JobSchedulerView(sb.getJobScheduler());
try {
ObjectName objectName = BrokerMBeanSupport.createJobSchedulerServiceName(getBrokerObjectName());
AnnotatedMBean.registerMBean(getManagementContext(), view, objectName);
this.adminView.setJMSJobScheduler(objectName);
} catch (Throwable e) {
throw IOExceptionSupport.create("JobScheduler could not be registered in JMX: "
+ e.getMessage(), e);
}
}
broker = sb;
}
if (isUseJmx()) {
HealthViewMBean statusView = new HealthView((ManagedRegionBroker)getRegionBroker());
try {
ObjectName objectName = BrokerMBeanSupport.createHealthServiceName(getBrokerObjectName());
AnnotatedMBean.registerMBean(getManagementContext(), statusView, objectName);
} catch (Throwable e) {
throw IOExceptionSupport.create("Status MBean could not be registered in JMX: "
+ e.getMessage(), e);
}
}
if (isAdvisorySupport()) {
broker = new AdvisoryBroker(broker);
}
broker = new CompositeDestinationBroker(broker);
broker = new TransactionBroker(broker, getPersistenceAdapter().createTransactionStore());
if (isPopulateJMSXUserID()) {
UserIDBroker userIDBroker = new UserIDBroker(broker);
userIDBroker.setUseAuthenticatePrincipal(isUseAuthenticatedPrincipalForJMSXUserID());
broker = userIDBroker;
}
if (isMonitorConnectionSplits()) {
broker = new ConnectionSplitBroker(broker);
}
if (plugins != null) {
for (int i = 0; i < plugins.length; i++) {
BrokerPlugin plugin = plugins[i];
broker = plugin.installPlugin(broker);
}
}
return broker;
}

我们创建的topic和queue都记录在ManagedRegionBroker这个类中:

public class ManagedRegionBroker extends RegionBroker {
private static final Logger LOG = LoggerFactory.getLogger(ManagedRegionBroker.class);
private final ManagementContext managementContext;
private final ObjectName brokerObjectName;
private final Map<ObjectName, DestinationView> topics
= new ConcurrentHashMap<ObjectName, DestinationView>();
private final Map<ObjectName, DestinationView> queues
= new ConcurrentHashMap<ObjectName, DestinationView>();
private final Map<ObjectName, DestinationView> temporaryQueues
= new ConcurrentHashMap<ObjectName, DestinationView>();
private final Map<ObjectName, DestinationView> temporaryTopics
= new ConcurrentHashMap<ObjectName, DestinationView>();
private final Map<ObjectName, SubscriptionView> queueSubscribers
= new ConcurrentHashMap<ObjectName, SubscriptionView>();
private final Map<ObjectName, SubscriptionView> topicSubscribers
= new ConcurrentHashMap<ObjectName, SubscriptionView>();
private final Map<ObjectName, SubscriptionView> durableTopicSubscribers
= new ConcurrentHashMap<ObjectName, SubscriptionView>();
private final Map<ObjectName, SubscriptionView> inactiveDurableTopicSubscribers
= new ConcurrentHashMap<ObjectName, SubscriptionView>();
private final Map<ObjectName, SubscriptionView> temporaryQueueSubscribers
= new ConcurrentHashMap<ObjectName, SubscriptionView>();
private final Map<ObjectName, SubscriptionView> temporaryTopicSubscribers
= new ConcurrentHashMap<ObjectName, SubscriptionView>();
private final Map<ObjectName, ProducerView> queueProducers
= new ConcurrentHashMap<ObjectName, ProducerView>();
private final Map<ObjectName, ProducerView> topicProducers
= new ConcurrentHashMap<ObjectName, ProducerView>();
private final Map<ObjectName, ProducerView> temporaryQueueProducers
= new ConcurrentHashMap<ObjectName, ProducerView>();
private final Map<ObjectName, ProducerView> temporaryTopicProducers
= new ConcurrentHashMap<ObjectName, ProducerView>();
private final Map<ObjectName, ProducerView> dynamicDestinationProducers
= new ConcurrentHashMap<ObjectName, ProducerView>();
private final Map<SubscriptionKey, ObjectName> subscriptionKeys
= new ConcurrentHashMap<SubscriptionKey, ObjectName>();
private final Map<Subscription, ObjectName> subscriptionMap
= new ConcurrentHashMap<Subscription, ObjectName>();
private final Set<ObjectName> registeredMBeans
= new CopyOnWriteArraySet<ObjectName>();
/* This is the first broker in the broker interceptor chain. */
private Broker contextBroker;
}

ActiveMQ broker解析的更多相关文章

  1. ActiveMQ broker 集群, 静态发现和动态发现

    下载 activemq 压缩包解压后,conf 目录下有各种示例配置文件,红线标出的是静态发现和动态发现的配置. 1. 静态配置 启动3个 broker,端口分别为61616,61618,61620, ...

  2. ActiveMQ broker和客户端之间的确认

    生产者发送消息:producer ---------> broker broker返回确认:broker ---------> producer 生产者发送同步消息,broker会返回Re ...

  3. ActiveMQ broker 非持久化queue消息的入队、出队和应答

    消息入队:Queue.doMessageSend 消息分发:Queue.doActualDispatch 消息发送:TransportConnection.dispatch broker收到consu ...

  4. ActiveMQ中Broker的应用与启动方式

    Broker:英语有代理的意思,在activemq中,Broker就相当于一个Activemq实例. 1. 命令行启动实例: 1.activemq start使用默认的activemq.xml启动 E ...

  5. ActiveMQ producer不断发送消息,会导致broker内存耗尽吗?

    http://activemq.apache.org/my-producer-blocks.html 回答了这个问题: ActiveMQ 5.x 支持Message Cursors,它默认把消息从内存 ...

  6. ActiveMQ学习笔记(5)----Broker的启动方式

    Broker:相当于一个ActiveMQ服务器实例,在实际的开发中我们可以启动多个Broker. 命令行启动参数示例如下: 1. activemq start 使用默认的activemq.xml来启动 ...

  7. C++ activemq CMS 学习笔记.

    很早前就仓促的接触过activemq,但当时太赶时间.后面发现activemq 需要了解的东西实在是太多了. 关于activemq 一直想起一遍文章.但也一直缺少自己的见解.或许是网上这些文章太多了. ...

  8. 消息中间件--ActiveMQ&JMS消息服务

    ### 消息中间件 ### ---------- **消息中间件** 1. 消息中间件的概述 2. 消息中间件的应用场景 * 异步处理 * 应用解耦 * 流量削峰 * 消息通信   --------- ...

  9. 基于zookeeper的activemq的主从集群配置

    项目,要用到消息队列,这里采用activemq,相对使用简单点.这里重点是环境部署. 0. 服务器环境 RedHat710.90.7.210.90.7.1010.90.2.102 1. 下载安装zoo ...

随机推荐

  1. 2. mysql 语句

    基础语句 创建表 DROP TABLE IF EXISTS student;CREATE TABLE student ( id ) NOT NULL AUTO_INCREMENT, sname ) N ...

  2. mail命令

    mail命令是命令行的电子邮件发送和接收工具.操作的界面不像elm或pine那么容易使用,但功能非常完整. 语法 mail(选项)(参数) 选项 -b<地址>:指定密件副本的收信人地址: ...

  3. JaveWeb 公司项目(7)----- 通过JS动态生成DIV

    Web网页项目的数据表格功能已经大体完成,下面是另一个主要功能,在线视频的显示 目前我做的项目是渔政监控方面,在之前C#的版本中已经实现了摄像头的在线监控,用的海康封装好的SDK,目前需要做的工作是在 ...

  4. Oracle(order by)

    传统数据查询只会按照设置的主键排列.如果现在对制定的列进行排序的操作,那么就必须通过 ORDER BY 子句控制. 排序语法: SELECT [DISTINCT] * | 列名称 [AS] 列别名, ...

  5. python web.py操作mysql数据库,实现对数据库的增删改查操作

    使用web.py框架,实现对mysql数据库的增删改查操作: 该示例代码中连接的是本地数据库testdb,user表,表结构比较简单,只有两个字段:mobile和passwd,类型均为字符型 实际应用 ...

  6. Discrete Log Algorithms :Baby-step giant-step 【二】

    import gmpy2 def discreteLog(g,p,a): #离散对数,求 g^x=a mod p中的x table={} sq=gmpy2.isqrt(p-1) m=gmpy2.add ...

  7. leecode第一百零四题(二叉树的最大深度)

    /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode ...

  8. Go语言学习之7 接口实例、终端文件读写、异常处理

    本节主要内容: 1. 终端读写2. 文件读写3. 命令行参数4. Json5. 自定义错误 1. 终端读写 操作终端相关文件句柄常量    os.Stdin:标准输入    os.Stdout:标准输 ...

  9. 国外(英文)——WPF较好的奇葩问题解决网站

    https://stackoverflow.com/questions/6415908/c-sharp-wpf-datagrid-vertical-scroll

  10. 20181014xlVBA获取小题零分名单

    Sub GetZeroName() Dim Dic As Object Const SUBJECT = "科目名称" Dim Key As String Dim OneKey Di ...