ActiveMQ源码架构解析第一节(转)
工作四年已久,也快到了而立之年,本人也酷爱技术,总是想找一些途径来提升自己,想着温故而知新所以就写起了博客,然而写博客这个想法也是酝酿了很久,近期也看到了有很多人在问关于ActiveMQ的相关问题,有幸接触ActiveMQ从今天开始我会定期总结一些关于ActiveMQ的相关知识,本篇重点是先分析ActiveMQ的架构以及设计模式等相关知识,然后在说如何更好的使用,让ActiveMQ发挥最好的性能,欢迎大家跟帖讨论,有错误的地方还请大家不吝雅正,小方在此谢过!
第一篇文章我们先从hello world写起,下面是使用java代码调用activemq的api发送一条消息。
public class test {
public static void main(String[] args) throws Exception {
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
"tcp://localhost:61616");
Connection connection = connectionFactory.createConnection();
connection.start();
Session session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = session.createProducer(session
.createQueue("testQueue"));
Message message = session.createTextMessage("hello everybody!");
producer.send(message);
producer.close();
session.close();
connection.close();
}
}
下面来分析发送消息的几个步骤,如下:
1、创建ActiveMQConnectionFactory,入参是url,指定schema以及要连接的ip和端口号,其次是创建ActiveMQConnection,tcp协议交互肯定是要使用Socket类,所以说明下ActiveMQConnection->Transport->Socket的关系,Transport是对Socket的封装,而ActiveMQConnection则是对Transport的封装,如下图所示:
2、创建ActiveMQConnection,因为上图已经说明ActiveMQConnection和Transport是组合关系,所以创建ActiveMQConnection时首先要创建Transport,因为ActiveMQ的交互方式分为Tcp、Udp以及HTTP协议,ActiveMQ使用了非常经典的简单工厂设计模式,使用这个模式的好处是工厂可以根据uri的schema头来动态创建相应的TransportFactory工厂,例如用户输入tcp://localhost:61616,ObjectFactory则可以获取到schema是tcp然后来实例化TcpTransportFactory,然后在调用TcpTransportFactory工厂来生产TcpTransport对象,简单工厂模式如下图,我是把2个工厂画到了一起: 创建完TcpTransport还不够,因为TcpTransport只实现了发送和接受消息,还需要做一些封装来实现相应的业务处理,说到封装这里使用到了包装设计模式,也叫装饰者模式,jdk的java.io输入输出流也有使用,类图如下:
1、1、MutexTransportFilter类实现了对每个请求的同步锁,同一时间只允许发送一个请求,如果有第二个请求需要等待第一个请求发送完毕才可继续发送。
2、2、WireFormatNegotiator类实现了在客户端连接broker的时候先发送数据解析相关的协议信息,例如解析版本号,是否使用缓存等信息。
3、3、InactivityMonitor类实现了连接成功后启动心跳检查机制,客户端每10秒发送一次心跳信息,服务端每30秒读一次心跳信息,如果没有读到则会断开连接,心跳检测是相互的,客户端也会每30秒读取服务端发送来的心跳信息,如果没有读到也一样会断开连接。
4、4、ResponseCorrelator类实现了异步请求但需要获取响应信息否则就会阻塞等待功能。
创建ActiveMQConnection的时序图如下:
客户端调用createConnection()方法,通过TcpTransportFactory获取到TcpTransport对象,得到TcpTransport对象后,TcpTransportFactory又调用自己的configure方法对TcpTransport进行了包装,代码如下:
public Transport configure(Transport transport, WireFormat wf, Map options) throws Exception {
transport = compositeConfigure(transport, wf, options);
transport = new MutexTransport(transport);
transport = new ResponseCorrelator(transport);
return transport;
}
这就是包装设计模式的使用,当调用transport.request()发送消息时,时序图如下:
每次transport调用request方法时都会先判断next是否为空,如果不为空则先调用next.request(),当然在调用之前和之后都会加入相应的逻辑,包装设计模式的好处就是当我不想启动心跳检测功能时则可以非常简单的实现,只需要不为WireFormatNegotiator设置next属性为InactivityMonitor即可,获取加入其它功能不需要修改原来的设计只需要新增一个类即可,充分的体现了设计模式的开放封闭原则以及单一职责原则,设计模式在ActiveMQ中可以说是使用的淋漓尽致,恰到好处。
创建完ActiveMQConnection之后就是创建ActiveMQSession以及ActiveMQMessageProducer了,这两个对象的创建就比较简单了没什么可说的,当然在创建这些对象的时候客户端会发送相应的信息给服务端,本节主要讲解连接的建立。信息的交互以及Message的发送就留到下一节在说了,第一次写这么长的博文,可能有的地方讲的思路不清晰,还请大家多多指正,谢谢大家,睡觉了,明天还要加班!
http://www.iteye.com/topic/1137523
ActiveMQ源码架构解析第一节(转)的更多相关文章
- 深入解析Underscore.js源码架构
Underscore.js是很有名的一个工具库,我也经常用他来处理对象,数组等,本文会深入解析Underscore源码架构,跟大家一起学习下他源码的亮点,然后模仿他写一个简单的架子来加深理解.他的源码 ...
- 使用CEF(三)— 从CEF官方Demo源码入手解析CEF架构与CefApp、CefClient对象
在上文<使用CEF(2)- 基于VS2019编写一个简单CEF样例>中,我们介绍了如何编写一个CEF的样例,在文章中提供了一些代码清单,在这些代码清单中提到了一些CEF的定义的类,例如Ce ...
- Retrofit源码设计模式解析(下)
本文将接着<Retrofit源码设计模式解析(上)>,继续分享以下设计模式在Retrofit中的应用: 适配器模式 策略模式 观察者模式 单例模式 原型模式 享元模式 一.适配器模式 在上 ...
- mybatis 3.x源码深度解析与最佳实践(最完整原创)
mybatis 3.x源码深度解析与最佳实践 1 环境准备 1.1 mybatis介绍以及框架源码的学习目标 1.2 本系列源码解析的方式 1.3 环境搭建 1.4 从Hello World开始 2 ...
- 《淘宝数据库OceanBase SQL编译器部分 源码阅读--解析SQL语法树》
淘宝数据库OceanBase SQL编译器部分 源码阅读--解析SQL语法树 曾经的学渣 2014-06-05 18:38:00 浏览1455 云数据库Oceanbase OceanBase是 ...
- Spring框架之AOP源码完全解析
Spring框架之AOP源码完全解析 Spring可以说是Java企业开发里最重要的技术.Spring两大核心IOC(Inversion of Control控制反转)和AOP(Aspect Orie ...
- Spring框架之jms源码完全解析
Spring框架之jms源码完全解析 我们在前两篇文章中介绍了Spring两大核心IOC(Inversion of Control控制反转)和AOP(Aspect Oriented Programmi ...
- Thrift之代码生成器Compiler原理及源码详细解析1
我的新浪微博:http://weibo.com/freshairbrucewoo. 欢迎大家相互交流,共同提高技术. 又很久没有写博客了,最近忙着研究GlusterFS,本来周末打算写几篇博客的,但是 ...
- spring源码深度解析— IOC 之 容器的基本实现
概述 上一篇我们搭建完Spring源码阅读环境,spring源码深度解析—Spring的整体架构和环境搭建 这篇我们开始真正的阅读Spring的源码,分析spring的源码之前我们先来简单回顾下spr ...
随机推荐
- Linux的grep命令详解
简介 grep (global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它 ...
- javascript 学习资料网址一览
1.http://www.runoob.com/ 2.https://developer.mozilla.org/zh-CN/ 3.http://www.imooc.com/ 视频类
- Eclipse中提高Android SDK Manager下载速度方法
在Windows-System32-drivers-ect目录下找到hosts文件 打开hosts文件(用记事本打开就可以),在文件以下填上一下内容: 203.208.46.146 www.googl ...
- Java设计模式---外观模式
外观模式(Facade) 外观模式的意图是:为子系统提供一个接口,便于它的使用. 解释: 简单的说,外观模式就是封装多个上层应用需要的方法,使得上层调用变得简单,为上层提供简单的接口,是设计模式中 ...
- Effective C++_笔记_条款05_了解C++默认编写并调用哪些函数
(整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 直接上代码: 1: class Empty{}; 如果你写了这样 ...
- UpdateWindow API函数的作用很明显
待续 摘自<Delphi深度历险>
- 研究一下FBrush,它是从TWinControl才有的属性(可能是因为需要句柄)——发现{$R *.dfm}在运行期执行,而且很有深意,读到属性后赋值还会触发事件,这些无法在VCL代码里直接看到
定义和创建: TWinControl = class(TControl) private FBrush: TBrush; end; constructor TWinControl.Create(AOw ...
- Usaco 1.3.2 修理牛棚(Barn Repair)
Barn Repair 题意:在一个夜黑风高,下着暴风雨的夜晚,农民约翰的牛棚的屋顶.门被吹飞了. 好在许多牛正在度假,所以牛棚没有住满. 剩下的牛一个紧挨着另一个被排成一行来过夜. 有些牛棚里有 ...
- Oracle Tablespace Transportation
前提:进行表空间传输需要用户有SYSDBA的系统权限,被移动的表空间是自包含的表空间,不应有依赖于表空间外部对象的对象存在.确定是否自包含可使用系统包DBMS_TTS中的TRANSPORT_SET_C ...
- 5350.support
3G6200N3G6200NL3G300MAIR3GIIALL02393GALL0256NALL5002ALL5003ARGUS_ATP52B,ASL26555AWM002EVBAWAPN2403BC ...