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 ...
随机推荐
- android文件下载大小和网络不一致(偏大)
今天在写一个文件下载的程序,在网上搜索了一个抄,用来下载MP3文件. 但是发现下载的MP3文件比原来的文件要大,而且MP3中会有杂音. 在Log中加入日志后发现: 从 网络流中获取的流长度为3000 ...
- Javascript做模糊查询
<html> <head> <title>Javascript模糊查找</title> </head> <body> <l ...
- Codility上的问题 (17) PI 2012
这个题比较简单,给定一个整数数组,对每个元素,求出和它最近比它大的数的距离(下标绝对值),如果没有比它大的数,认为距离是0. 数组元素个数 N [0..50000],数组元素范围[-10^9, +10 ...
- dos批量替换当前目录后缀名
有时候有些后缀名不满足条件,就需要进行批量的替换,如果人为的去替换,那么如果量少的话还好说,量多的话一个个去替换就太傻了,今天从网络上面查找了一些批量替换的dos命令,用起来还挺好用的,就直接把代码贴 ...
- 如何编译tizen源码(图文教程)?
前一篇文章已经介绍了如何下载tizen源码,下面我将继续讲述如何编译源码. 1 下载安装gbs编译工具 tizen源码是用gbs工具进行编译的,因此我们首先得将此工具下载下来,并且设置好. 下面的Ub ...
- delpi中的RTTI初试
java中的反射机制使我们能够在运行期间获取运行期类的信息,那么在delphi中有没有这样的功能呢?答案是有,实现这种功能的机制在delphi中叫做RTTI,废话少说,先来一段demo: 1.先定义一 ...
- TCP与UDP各自特点对比
UDP和TCP是我们最常用的两种通信方式,下面就两者之间的特点做一个对比: 1.UDP主要用在实时性要求高以及对质量相对较弱的地方,如流媒体. 2.TCP既然是面向连接的,那么运行环境必然要求其保证可 ...
- cell中button怎么得到对应cell的indexpath 以及关于UITableViewCellContentView的问题
============================================================ 博文原创,转载请声明出处 电子咖啡-专注于移动互联网 ============ ...
- 手动配置S2SH三大框架报错(二)
十二月 08, 2013 9:34:39 下午 org.apache.catalina.core.AprLifecycleListener init 严重: An incompatible versi ...
- 积累的VC编程小技巧之视图
1.如何得到视图指针 [问题提出] 现在你有一个多线程的Demo,你想在多线程里处理视图指针里的函数,我们给这个函数起个名字:Put();该如何实现呢? //有两种方法可以实现你的要求: ...