01.ActiveMQ 源码解析之创建连接

ActiveMQ——Java连接ActiveMQ org.apache.activemq activemq-all 5.15.9 org.apache.xbean xbean-spring 3.16 消息生产者 package com.java.elasticsearch.activemq; import org.apache.activemq.ActiveMQConnectionFactory;import javax.jms.*;/** * @author Woo_home * @c.. 阅读详情

1. 环境搭建

  • 代码已经上传至 https://github.com/masteryourself/activemq.git ,分支名称是 masteryourself-activemq-5.15.9

  • producer 是 activemq-example 工程,启动类是 QueueProducer

2. 源码解析

2.1 流程预览

image

// 1. 创建 ActiveMQConnection
org.apache.activemq.ActiveMQConnectionFactory#createConnection ->
	org.apache.activemq.ActiveMQConnectionFactory#createActiveMQConnection
		
		// 1.1(*) 创建 transport,用于与 server 端进行交互
		org.apache.activemq.ActiveMQConnectionFactory#createTransport ->
			org.apache.activemq.transport.TransportFactory#connect ->
				
				// 1.1.1(*) 这里是 spi 扩展,和 dubbo 类似
				// 从 META-INF/services/org/apache/activemq/transport/tcp 文件中找到实现类【TcpTransportFactory】
				org.apache.activemq.transport.TransportFactory#findTransportFactory
				
				// 1.1.2(*) 调用 doConnect 方法,返回 Transport 对象
				org.apache.activemq.transport.TransportFactory#doConnect

					// 1.1.2.1 创建 Transport
					org.apache.activemq.transport.tcp.TcpTransportFactory#createTransport->
						// tcpTransport 里持有 socketFactory 对象,socketFactory 会创建一个 socket,所以 tcpTransport 就是操作 socket
						org.apache.activemq.transport.tcp.TcpTransportFactory#createTcpTransport

					// 1.1.2.2(*) 配置 configure,这个里面是对 Transport 做链路包装
					org.apache.activemq.transport.TransportFactory#configure

						// 1.1.2.2.1 组装一个复合的transport,这里会包装两层,一个是 IactivityMonitor.另一个是 WireFormatNegotiator
        				// WireFormatNegotiator 实现了客户端连接 broker 的时候先发送数据解析相关的协议信息,比如解析版本号,是否使用缓存等
        				// InactivityMonitor 用于实现连接成功成功后的心跳检查机制,客户端每 10s 发送一次心跳信息。服务端每 30s 读取一次心跳信息
						org.apache.activemq.transport.tcp.TcpTransportFactory#compositeConfigure

						// 1.1.2.2.2 用 MutexTransport 包装,实现写锁,表示同一时间只允许发送一个请求
						org.apache.activemq.transport.MutexTransport#<init>

						// 1.1.2.2.3 用 ResponseCorrelator 包装,用于实现异步请求
						org.apache.activemq.transport.ResponseCorrelator#<init>

		// 1.2(*) 设置 ActiveMQConnection 的属性,如 prefetchPolicy、optimizedMessageDispatch 等属性
		org.apache.activemq.ActiveMQConnectionFactory#configureConnection

		// 1.3(*) 最终会启动 TransportThreadSupport 的
		org.apache.activemq.transport.TransportFilter#start ->
			// 这里省略了一些一些包装类,最终会调用 ServiceSupport 中的 start 方法
			org.apache.activemq.util.ServiceSupport#start ->

				// 1.3.1 利用 socketFactory 创建 socket 对象(连接 activeMQ server 端)
				org.apache.activemq.transport.tcp.TcpTransport#connect

				// 1.3.2 调用 TcpTransport 中的 doStart 方法
				org.apache.activemq.transport.tcp.TcpTransport#doStart ->
					// 启动线程,runnable 对象是 【TcpTransport】,所以在 【TcpTransport】 的 run 方法中等待结果
					org.apache.activemq.transport.TransportThreadSupport#doStart

// 2. 【TcpTransport】 中的 run 方法,空壳方法,调用 doRun
org.apache.activemq.transport.tcp.TcpTransport#run ->
	// 调用 doConsume 处理
	org.apache.activemq.transport.tcp.TcpTransport#doRun

		// 2.1 从 socket 读数据,封装成 command
		org.apache.activemq.transport.tcp.TcpTransport#readCommand

		// 2.2 Transport 的包装类处理逻辑
		org.apache.activemq.transport.TransportSupport#doConsume ->
			// Transport 的包装类处理逻辑
			org.apache.activemq.transport.AbstractInactivityMonitor#onCommand ->
				// Transport 的包装类处理逻辑
				org.apache.activemq.transport.WireFormatNegotiator#onCommand ->
					// Transport 的包装类处理逻辑
					org.apache.activemq.transport.MutexTransport#onCommand ->
						// Transport 的包装类处理逻辑
						org.apache.activemq.transport.ResponseCorrelator#onCommand ->
							// ActiveMQ 在这里处理来自于 server 端的 command 命令
							org.apache.activemq.ActiveMQConnection#onCommand
2.2 流程详解
2.2.1 ActiveMQConnectionFactory#createTransport(1.1)
  • org.apache.activemq.ActiveMQConnectionFactory
   protected Transport createTransport() throws JMSException {
    try {

        // 即 tcp://192.168.89.210:61616
        URI connectBrokerUL = brokerURL;
        String scheme = brokerURL.getScheme();
        if (scheme == null) {
            throw new IOException("Transport not scheme specified: [" + brokerURL + "]");
        }
        if (scheme.equals("auto")) {
            connectBrokerUL = new URI(brokerURL.toString().replace("auto", "tcp"));
        } else if (scheme.equals("auto+ssl")) {
            connectBrokerUL = new URI(brokerURL.toString().replace("auto+ssl", "ssl"));
        } else if (scheme.equals("auto+nio")) {
            connectBrokerUL = new URI(brokerURL.toString().replace("auto+nio", "nio"));
        } else if (scheme.equals("auto+nio+ssl")) {
            connectBrokerUL = new URI(brokerURL.toString().replace("auto+nio+ssl", "nio+ssl"));
        }
        // 根据 scheme 动态构建一个 Transport
        return TransportFactory.connect(connectBrokerUL);
    } catch (Exception e) {
        throw JMSExceptionSupport.create("Could not create Transport. Reason: " + e, e);
    }
}
2.2.2 TransportFactory#findTransportFactory(1.1.1)
  • org.apache.activemq.transport.TransportFactory
public static TransportFactory findTransportFactory(URI location) throws IOException {
    String scheme = location.getScheme();
    if (scheme == null) {
        throw new IOException("Transport not scheme specified: [" + location + "]");
    }
    TransportFactory tf = TRANSPORT_FACTORYS.get(scheme);
    if (tf == null) {
        // Try to load if from a META-INF property.
        try {
            // 这里是 spi 扩展,和 dubbo 类似
            // 从 META-INF/services/org/apache/activemq/transport/tcp 文件中找到实现类【TcpTransportFactory】
            tf = (TransportFactory)TRANSPORT_FACTORY_FINDER.newInstance(scheme);
            // 放置到缓存中
            TRANSPORT_FACTORYS.put(scheme, tf);
        } catch (Throwable e) {
            throw IOExceptionSupport.create("Transport scheme NOT recognized: [" + scheme + "]", e);
        }
    }
    return tf;
}
2.2.3 TransportFactory#doConnect(1.1.2)
  • org.apache.activemq.transport.TransportFactory
public Transport doConnect(URI location) throws Exception {
    try {
        Map<String, String> options = new HashMap<String, String>(URISupport.parseParameters(location));
        if( !options.containsKey("wireFormat.host") ) {
            options.put("wireFormat.host", location.getHost());
        }
        WireFormat wf = createWireFormat(options);
        //  创建一个Transport,就是创建一个 socket连接
        Transport transport = createTransport(location, wf);
        // 配置 configure,这个里面是对 Transport 做链路包装
        Transport rc = configure(transport, wf, options);
        //remove auto
        IntrospectionSupport.extractProperties(options, "auto.");

        if (!options.isEmpty()) {
            throw new IllegalArgumentException("Invalid connect parameters: " + options);
        }
        return rc;
    } catch (URISyntaxException e) {
        throw IOExceptionSupport.create(e);
    }
}
2.2.4 TransportFactory#configure(1.1.2.2)
  • org.apache.activemq.transport.TransportFactory
public Transport configure(Transport transport, WireFormat wf, Map options) throws Exception {
    // 组装一个复合的transport,这里会包装两层,一个是 IactivityMonitor.另一个是 WireFormatNegotiator
    // WireFormatNegotiator 实现了客户端连接 broker 的时候先发送数据解析相关的协议信息,比如解析版本号,是否使用缓存等
    // InactivityMonitor 用于实现连接成功成功后的心跳检查机制,客户端每 10s 发送一次心跳信息。服务端每 30s 读取一次心跳信息
    transport = compositeConfigure(transport, wf, options);

    // 再做一层包装 MutexTransport,实现写锁,表示同一时间只允许发送一个请求
    transport = new MutexTransport(transport);
    // 包装 ResponseCorrelator,用于实现异步请求
    transport = new ResponseCorrelator(transport);

    return transport;
}
ActiveMQ——Java连接ActiveMQ,java视频聊天 } 在运行该程序之前我们需要先启动一下 ActiveMQ 访问 http://localhost:8161/admin/,点击 Queues 选项 队列中也是啥也没有 然后我们运行一下上面的程序 控制台已显示成功将消息发送到 MQ 了 http://localhost:8161/admin/queues.jsp 然后我们再次刷新 Queues 界面,已经接收到了 3 条消息 通过该界面不难发现,我们在代码中定义了一个队列名称为 queue01,该界面显示的队列名称就是我们手动设置的 Queues 阅读详情

相关推荐

分分钟搞定分布式技术专题面试——Nginx+ZK+ActiveMQ+Kafka+RabbitMQ+MongoDB+Redis!

元数据是如何保存的?在单 node 系统和多 node 构成的 cluster 系统中声明 queue、exchange ,以及进行 binding 会有什么不同?memcached 和服务器的 local cache (比如 PHP 的 的 APC 、mmap 文件等)相比,有什么优缺点?redis 内存淘汰机制(MySQL里有2000w数据,Redis中只存20w的数据,如何保证Redis中的数据都是热点数据?memcached 和 和 MySQL 的 的 query cache 相比,有什么优缺点?.

weixin_66896902的博客 425

Spring+Stomp+ActiveMq实现websocket长连接

stomp.js+spring+sockjs+activemq实现websocket长连接,使用java配置。 pom.xml(只列出除了spring基本依赖意外的依赖,spring-version为4.3.3.RELEASE): <dependency> <groupId>javax.websocket</groupId> ...

weixin_30600197的博客 400

FinRL实战:5步搞定股票量化交易策略(附Python代码)

本文详细介绍了如何使用FinRL框架,通过5个步骤构建基于深度强化学习的股票量化交易策略。内容涵盖从环境搭建、数据获取与预处理,到交易环境构建、模型训练(如PPO算法),以及策略回测评估与优化的完整流程,并提供了可运行的Python代码示例,帮助读者快速入门AI驱动的量化交易。

weixin_29062865的博客 630

ActiveMQ:Openwire,Stomp,AMQP,WebSocket,MQTT,连接代码

ActiveMQ的5种连接方式:Openwire,Stomp,AMQP,WebSocket,MQTT;里面是相关的代码。

时不时“复活”一下。 701

【寄存器模型】二、前门访问与后门访问

1.后门访问可以更好的完成前门访问能够完成的事情:后门访问不消耗仿真时间,且消耗的运行时间也远小于前门访问的运行时间。 2.后门访问可以完成前门访问不能完成的事:对于某些特定的场景,如网络通信系统中的一些只读计数器,当要验证计数器进位归零的场景时,前门访问无法完成写寄存器操作,只能通过消耗仿真时间来使计数器到达特定的计数值。而后门访问可以直接对只读寄存器赋一个初值......

carrotbanana的博客 9658

【100%通过率】2023华为od机试C卷【电脑病毒感染】Python 实现

一个局域网内有很多台电脑,分别标注为 0 ~ N-1 的数字。相连接的电脑距离不一样,所以感染时间不一样,感染时间用t 表示。其中网络内一台电脑被病毒感染,求其感染网络内所有的电脑最少需要多长时间。如果最后有电脑不会感染,则返回-1.

MISAYAONE的博客 3033

ActiveMQ的测试程序

可以将ActiveMQ理解成一个服务器。 1 . ActiveMQ 的下载和安装: 下载地址: http://activemq.apache.org/download.html 下载最新版的ActiveMQ即可。 下载后直接解压到要安装的目录即可,不需要安装过程。 2 .ActiveMQ的启动: win+R –> cmd –>跳转到安装目录的bin文件夹下面 输入activemq s

胡倩萌的博客 1121

【DeepSeek应用实践】手把手教程:用 AnythingLLM + Ollama + DeepSeek-R1 搭建本地企业知识库

在众多的技术方案中,我们选择了 AnythingLLM、Ollama 和 DeepSeek-R1 这一组合来搭建本地知识库。Ollama 作为一个轻量级的本地化大语言模型部署工具,支持多种模型,易于安装和使用,能够快速在本地运行强大的语言模型。DeepSeek-R1 是一个专为知识库问答设计的检索增强生成(RAG)模型,它结合了检索和生成的优势,能够快速从知识库中检索相关信息并生成精准答案。而 AnythingLLM 则是一个用户友好的界面工具,可以方便地连接 Ollama 和 DeepSeek-R1

寻道AI,探索AI无限可能! 2569

activeMQ消息中间件原理以及java代码实现

本文中使用到的工具和代码下载地址:https://download.csdn.net/download/qq_27184497/12080904 一、什么是消息中间件? 在介绍activeMQ之前我们先来了解下什么是消息中间件,在客户端和服务器之间进行通讯时,客户发送请求后,服务器必须正确处理完成后才能继续执行以后的步骤,而且如果服务器涉及到异常错误或者网络故障以及服务对象崩溃的情...

叶新东老师的博客 1498

【WRF工具】WRF 模型输出可视化工具 plotfmt

【WRF工具】WRF 模型输出可视化工具 plotfmt

WW、forever的博客 1292

25、量子计算:中性原子与约瑟夫森结量子比特

本文详细探讨了中性原子和约瑟夫森结两种量子比特在量子计算中的应用。中性原子量子比特利用光晶格实现量子态的操控,具有长相干时间的优势,但面临可扩展性和多量子比特操作的挑战;而约瑟夫森结量子比特基于超导技术,结合半导体制造工艺,具有低耗散和潜在的高可扩展性,但在参数控制和环境干扰方面存在难题。文章还比较了这两种方案的性能、应用场景及未来发展趋势,展望了它们在量子计算发展中的潜力与突破方向。

ol789012的博客 212

ActiveMQ笔记之ConnectionFactory以及使用SingleConnectionFactory遇到的坑

ActiveMQ笔记之ConnectionFactory以及使用SingleConnectionFactory遇到的坑

zgphacker2010的专栏 3588

从零开始做对容量规划:一文讲透 SAP Greenfield sizing 与 Quick Sizer 落地方法

摘要 SAP项目早期硬件规划面临业务细节缺失的挑战,Greenfield sizing方法通过Quick Sizer工具将业务需求转化为硬件资源需求。该方法聚焦主要负载驱动因素而非精确预测,采用标准化问卷形式输入并发用户数、业务处理量等参数,输出内存、CPU等资源需求。关键步骤包括选择正确的Quick Sizer版本、创建sizing项目、参考SAP基准测试和认证目录校准结果,最终将需求交由硬件厂商落地。该方法特别适用于缺乏历史数据的新系统部署,帮助在不确定性中建立可控的容量规划模型,避免资源浪费或性能不足

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 218

ActiveMQ——Java连接ActiveMQ(点对点)

无论是哪家公司,都很重视Spring框架技术,重视基础,所以千万别小看任何知识。面试是一个双向选择的过程,不要抱着畏惧的心态去面试,不利于自己的发挥。同时看中的应该不止薪资,还要看你是不是真的喜欢这家公司,好了希望这篇文章对大家有帮助!本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录需要这份系统化的资料的朋友,可以点击这里获取无论是哪家公司,都很重视Spring框架技术,重视基础,所以千万别小看任何知识。

2401_84584628的博客 1095

基于生存结局(生存分析/COX回归)的中介效应分析

① 建立观察变量OVB和中介变量MVB的回归模型(注意:这里根据mediation包的介绍,需要构建的是probit模型,而不是logist回归模型,网上有很多的代码用的logistic回归,结果自己跑的时候发现报错,我在这里陷了很久;为了方便演示,我们生成了一个协变量(Age)、一个连续型观察变量(liaOVC)、一个二分类观察变量(OVB)、一个连续型中介变量(MVC)、一个二分类中介变量(MVB)以及最后的结局变量(生存时间[time],生存结局[stats])。

m0_61863309的博客 1万+

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

ActiveMQ——Java连接ActiveMQ(点对点)(2)

金三银四到了,送上一个小福利!点对点消息传递的特点如下:(1)每个消息只能有一个消费者,类似 1 对 1 的关系,好比个人快递自己领取自己的(2)消息的生产者和消费者之间 没有时间上的相关性。无论消费者在生产者发送消息的时候是否处于运行状态,消费者都可以提取消息。好比我们的发送短信,发送者发送后不见得接收者会立即收看(3)消息被消费后队列中 不会再存储,所以消费者 不会消费到已经被消费掉的消息创建 Maven 工程关于怎么创建 Maven 工程这里就不详细讲解了,不会的朋友网上找一下。

2401_84584628的博客 1156

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

ActiveMQ——Java连接ActiveMQ,高级java面试题spring

5.15.9 org.apache.xbean xbean-spring 3.16 消息生产者 package com.java.elasticsearch.activemq; import org.apache.activemq.ActiveMQConnectionFactory;import javax.jms.*;/** * @author Woo_home * @create by 2020/5/2 21

m0_63102527的博客 188

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Java最全ActiveMQ——Java连接ActiveMQ(点对点)(1),跳槽大厂必看

文章中涉及到的知识点我都已经整理成了资料,录制了视频供大家下载学习,诚意满满,希望可以帮助在这个行业发展的朋友,在论坛博客等地方少花些时间找资料,把有限的时间,真正花在学习上,所以我把这些资料,分享出来。相信对于已经工作和遇到技术瓶颈的朋友们,在这份资料中一定都有你需要的内容。本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录需要这份系统化的资料的朋友,可以点击这里获取// 创建会话// 两个参数,第一个叫事务 / 第二个叫签收。

2301_82243979的博客 991

ActiveMQ——Java连接ActiveMQ(点对点)(1)

终极手撕架构师的学习笔记:分布式+微服务+开源框架+性能优化本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录需要这份系统化的资料的朋友,可以点击这里获取3.16消息生产者/***/// 定义 MQ 连接地址// 定义队列名称// 创建连接工厂// 通过连接工厂,获得连接 Connection// 创建会话// 两个参数,第一个叫事务 / 第二个叫签收// 创建目的地(具体是队列还是主题 Topic)

2401_84584628的博客 823

2024年Java最全ActiveMQ——Java连接ActiveMQ(点对点)(2),java面试常问

本文从基础到高级再到实战,由浅入深,把MySQL讲的清清楚楚,明明白白,这应该是我目前为止看到过最好的有关MySQL的学习笔记了,我相信如果你把这份笔记认真看完后,无论是工作中碰到的问题还是被面试官问到的问题都能迎刃而解!MySQL50道高频面试题整理:本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录需要这份系统化的资料的朋友,可以点击这里获取。

2401_84689725的博客 1202

activemq的重发策略参数配置

activemq为保证消息的可靠性,引入重发机制。 触发重发的情况: 1.在使用事务的Session中,调用rollback()方法; 2.在使用事务的Session中,调用commit()方法之前就关闭了Session; 3.在Session中使用CLIENT_ACKNOWLEDGE签收模式或者INDIVIDUAL_ACKNOWLEDGE模式,并且调...

tigerJGG的博客 1427

ActiveMQ学习笔记(九)—— 异步投递

ActiveMQ支持两种消息投递方式:同步投递和异步投递。消息投递指的是消息生产者端将消息发送到消息服务器(即Broker)的过程,若采用同步投递的方式,则生产者端每次向消息服务器发送消息时都需要同步地等待消息服务器给予消息发送成功与否的回执,这一定程度上可能会引起消息生产者的阻塞,影响消息发送的效率;采用异步投递的方式则不会有这个问题,因此ActiveMQ默认采用异步投递的方式。使用异步投递的方...

q42368773的博客 518

zipkin 源码分析01 源码结构

benchmarks 测试 zipkin 默认使用zipkin2 codec : 编解码器 internal : 编码器,writer,reader storage: 存储实现 zipkin的收集器 : 支持activemq,kafka和rabbitmq zipkin-junit: 单元测试 zipkin-lens : 前端UI实现 zipkin-server : ...

郭传志的博客 323

MySQL【实践 01】Linux 环境 MySQL 数据库备份 shell 脚本(脚本源码及说明+定时任务配置+数据库恢复测试

什么是ActiveMQ?ActiveMQ服务器宕机怎么办?丢消息怎么办?持久化消息非常慢怎么办?消息的不均匀消费怎么办?死信队列怎么办?ActiveMQ中的消息重发时间间隔和重发次数吗?

2401_84692253的博客 1432

塞班java软件下载,附项目源码

01 分布式限流:Nginx+ZooKeeper 1.1 分布式限流之Nginx 请解释一下什么是 Nginx? 请列举 x Nginx 的一些特性。 请列举 x Nginx 和 和 Apache 之间的不同点 请解释 x Nginx 如何处理 P HTTP 请求。 在 x Nginx 中,如何使用未定义的服务器名称来阻止处理请求? 使用 “ 反向代理服务器 ” 请列举 x Nginx 服务器的最佳用途。 请解释 x Nginx 服务器上的 r Master 和 和 r Wo

m0_57771583的博客 882

一文详解:直击HashTable的源码,面试总结

前言 作为一个典型的分布式项目,Kubernetes 的部署一直以来都是挡在初学者前面的一只“拦路虎”。尤其是在 Kubernetes 项目发布初期,它的部署完全要依靠一堆由社区维护的脚本。 其实,Kubernetes 作为一个 Golang 项目,已经免去了很多类似于 Python 项目要安装语言级别依赖的麻烦。但是,除了将各个组件编译成二进制文件外,用户还要负责为这些二进制文件编写对应的配置文件、配置自启动脚本,以及为 kube-apiserver 配置授权文件等等诸多运维工作。 这几年,在跟朋友探讨

m0_56711468的博客 131
上一篇: 01.分布式之序列化
下一篇: 02.ActiveMQ 源码解析之发送消息
masteryourself
博客等级 码龄9年 13粉丝 48原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值