- 博客(39)
- 收藏
- 关注
原创 ActiveMQ源码分析之消息确认
ActiveMQ中消息只有在被Broker确认之后才能认为被成功消费。消息的成功消费通常包括三个阶段:1、客户端接收消息,2、客户端处理消息,3、Broker确认消息。其中第2阶段和第3阶段的顺序根据客户端接收消息的方式而定。如果客户端采用receive的方式接收,则阶段2和阶段3是异步执行的,也就是说用户在真正处理消息之时,Broker可能已经确认完了。客户端如果采用listener的方式,则客...
2019-08-11 02:19:46
661
1
原创 ActiveMQ源码分析之Queue消费者
ActiveMQ中有两种消费模式,Queue(点对点)和Topic (发布/订阅),存储模式也分为非持久化和持久化。由于使用非持久化存储消息只会存储在内存中,容易造成消息丢失,实际生产环境中使用较少,因此重点介绍持久化下Queue消费。Queue模式下,允许同时有多个消费者,但是一条消息只会被其中一个消费者消费一次,ActiveMQ是如何实现这种机制的呢?我们先从Broker获取消费者需要的消...
2019-08-05 00:58:49
564
1
原创 ActiveMQ源码分析之KahaDB索引存储
前一篇我们分析完了KahaDB消息的存储机制,接下来将分析KahaDB的索引存储机制,跟索引存储相关的文件有*.data,*.redo,*.free。当Broker接收到Producer发送的消息数据之后将会将消息存储起来,而当Producer发送提交事务命令的时候,Broker会为刚才保存的消息生成对应的索引,存储在KahaDB中,以提升消息读取的效率。Broker接收到的事务信息如下:...
2019-05-04 23:04:43
635
原创 ActiveMQ源码分析之KahaDB消息存储
KahaDB是ActiveMQ从版本5.4之后的默认消息存储引擎,消息存储机制是消息中间件最重要的核心部件和性能提升点。KahaDB的存储主要分为索引存储和消息存储部分。KahaDB的索引是B+树,而其最基础的存储机制则是基于“随机存取文件”设计的。相对于连续存储的文件来说这种方式比较耗时,但是设计思路比较简单。相对的,Kahadb的消息即数据存储机制则是基于“连续存储”文件设计的,这种存...
2019-05-04 17:30:04
818
原创 ActiveMQ源码分析之Producer与Broker交互
AMQ生产者和Broker交互完整流程如下图。该图完整的描述了Producer发送消息时和Broker的整个交互流程。由于该过程交互较多,可以将整个流程分为三个部分。1、第一部分为Producer和Broker建立连接,包括发送WireFormatInfo,ConnectionInfo,ConsumerInfo,SessionInfo,ProducerInfo等信息。2、第二部...
2019-05-01 23:15:27
526
原创 ActiveMQ源码分析之Producer接收消息
ActiveMQ有三种消息发送方式,同步(syncSendPacket)、异步(asyncSendPacket)、单向(doOnewaySend)同步:发送者发送消息给Broker,同步等待,当前线程会阻塞,直到Broker返回应答信息。异步:发送者发送消息给Broker,消息发送线程不阻塞,继续执行下面的逻辑。由其他线程处理Broker返回的应答信息。单向:发送者发送消息给Broke...
2019-04-12 23:25:33
409
原创 ActiveMQ源码分析之Producer发送消息
AMQ源码分析基于5.15.6版本,先来段Producer连接Broker的demo。public class Sender { private static final int SEND_NUMBER = 1; public static void main(String[] args) { ConnectionFactory connectionFa...
2019-04-07 23:28:54
548
原创 ActiveMQ源码分析之开篇
时间如白驹过隙,一眨眼的功夫距离上次写博客的时间已经过去两年多了。为了回馈广大顾客,决定将最近整理的东西分享给大家,哈哈哈。虽然年龄已经不小,但还是要保持年轻,乐观的心态。最近将ActiveMQ源码涉猎了下,虽然这款MQ中间件年龄已经比较大了,而且市面上也出现了很多更优秀的MQ产品,如kafka,RocketMQ,RabbitMQ等。但是仍然有较多厂商在使用ActiveMQ,而且关于AMQ(以下A...
2019-04-07 18:22:44
252
原创 mina源码阅读之编码与解码
TCP是一个流协议,所谓流协议就是没有界限的一串数据,数据之间并没有分界线,它会根据TCP缓冲区的实际大小进行包的划分,那么业务上的一个完整包可能会被TCP拆成多个包进行发送,也有可能把多个小的包封装成一个大包进行发送,这时候就可能发生拆包与粘包。对于接收端来说,由于数据并没有界限,接收端不知道到底什么时候数据算是读取完,也只能根据缓冲区的大小来进行包的划分,此时接收端也可能会发生拆包与粘包。 针
2016-09-22 23:29:32
656
原创 mina源码阅读之过滤器
mina中的过滤器用IoFilter接口表示,默认实现类为IoFilterAdapter,IoFilter中包含了一个NextFilter接口,用于指向下一个过滤器,并且接口中定义的方法名与IoFilter接口中的一致。如果要实现自定义的过滤器,只需实现IoFilter接口即可,如果只是关注其中某几个方法,可以继承IoFilterAdapter类,重写相应的方法。注意,如果想让自定义的过滤器执行完之
2016-09-18 21:51:18
801
原创 mina源码学习之IoSession
Acceptor线程接收到客户端的请求之后就会调用processHandles方法处理请求。 private void processHandles(Iterator<H> handles) throws Exception { while (handles.hasNext()) { H handle = handles.next();
2016-09-08 21:45:31
820
原创 mina源码学习之接收线程
创建完接收器IoAcceptor之后,紧接着就是启动服务端的监听,准备接受客户端的请求。启动监听的入口是IoAcceptor接口的bind方法,方法的实现在AbstractIoAcceptor类中,具体的逻辑处理是AbstractPollingIoAcceptor类的bindInternal方法。我们重点看下bindInternal方法中调用startupAcceptor方法启动接收请求线程的过程。
2016-09-07 11:02:41
531
原创 mina源码学习之创建IoAcceptor
mina服务端通信概括起来有如下几个过程,1、创建服务端接收器对象IoAcceptor。2、绑定相应的接口并启动接收请求的线程。3、接收到请求后读取socket信息并调用过滤器解析socket信息。5、处理请求并将处理结果使用异步的方式写回客户端。 那么我们先来看看mina创建接收器对象的过程。在mina框架中,接收器对象用IoAcceptor接口表示,其TCP协议实现类为NioSocketAc
2016-09-05 22:02:23
670
原创 mina源码学习
Apache mina是一个网络通信应用框架,它主要是对基于TCP/IP,UDP/IP协议栈的通信框架。使用mina框架可以快速开发高性能,高扩展的网络通信应用,mina提供了事件驱动,异步操作的编程模型。mina框架有1.x和2.x两个版本,此处阅读的是2.x版本,在阅读源码之前需要掌握I/O,NIO,Socket,多线程及java并发库相关的内容。 mina同时提供了网络通信服务端和客户端的封
2016-09-05 16:22:58
411
原创 Tomcat源码阅读之Cookie和Session
Http协议是一种无状态协的请求/响应协议。服务器处理来自客户端的请求,然后向客户端回送一条响应。Web服务器几乎没有什么信息可以用来判断是哪个客户端发送的请求,也无法记录来访客户端的请求序列。 Cookie的作用就是识别不同的客户端,实现持久会话。Cookie的基本思想就是让浏览器持有一组服务器特有的信息,每次访问服务器时都将这些信息提供给它。 接下来我们看看Cookie是如何工作的。客户端第
2016-08-31 14:01:39
900
原创 Tomcat源码阅读之处理请求
web开发中我们常见的请求类型有三种: 1、页面跳转请求。 2、ajax请求。3、请求静态资源,如图片,css文件等。那么我们以最常用的页面跳转请求为例看看Tomcat的处理流程。Tomcat处理请求的逻辑主要在StandardWrapperValve类的invoke方法中。 接收到页面跳转请求之后,Tomcat首先会创建JspServlet实例,但是该实例在Context容器启动的时候就已经被创
2016-08-28 21:26:21
614
原创 Tomcat源码阅读之请求过程
Tomcat接收到请求之后便进行解析请求的工作。解析Http请求是个非常复杂的过程,比如解析请求头,解析请求行,解析参数等过程都比较复杂。对解析Http请求过程感兴趣的同学可以结合Http协议相关的资料深入研究。 Http请求解析完的数据会填充到request对象中,注意是org.apache.coyote.Request类型的对象。这个类是Tomcat内部使用的描述请求的信息类,作用就是在服务器
2016-08-25 22:45:28
368
原创 Tomcat源码阅读之Connector启动
Tomcat的主要功能简单概括起来就是接收请求,处理请求,返回结果,而接收请求和返回结果的过程都需要Connector组件参与。那么我们以Http/1.1对应的连接器为例,看下Connector组件启动过程的源码。Connector组件启动的主要逻辑在JIoEndpoint类的start方法中。public void start() throws Exception {
2016-08-22 23:31:03
341
原创 Tomcat源码阅读之过滤器
过滤器是web开发中常用的组件,可以通过web.xml中的和标签来配置过滤器的相关信息。过滤器的功能有点类似Servlet,但是使用起来更加灵活。在Tomcat中,跟过滤器相关的接口主要有三个:Filter,FilterChain和FilterConfig。 其中Filter接口是web开发中比较常用的一个接口,只要通过实现这个接口,就可以实现自定义的过滤器。Filter接口中定义了三个方法:pu
2016-08-21 20:56:06
792
原创 Tomcat源码阅读之Context启动
Tomcat中一个web应用程序对应一个Context容器,Context容器启动的主要逻辑在StandardContext类的start方法中。 start方法中首先会执行init方法,Context容器对应的监听器是ContextConfig,产生的init事件交由ContextConfig的init方法处理: 1、读取conf/context.xml配置文件,并解析它。 2、读取/con
2016-08-21 14:10:25
734
原创 Tomcat源码阅读之Host启动
Engine容器在启动过程中调用StandardHost类的start方法启动Host容器。 Host容器启动流程和Engine容器大同小异,标准实现类的start方法中注册JMX服务,然后调用父类ContainerBase的start方法启动子容器和产生相应的事件。Engine容器启动过程对事件的处理都较为简单,而Host容器启动过程对于start事件的处理逻辑则比较复杂,那么接下来看看Hos
2016-08-17 22:20:42
739
原创 Tomcat源码阅读之Engine启动过程
Tomcat的Start过程有两条主线,第一条启动Container组件,另一条启动Connector组件。public void start() throws LifecycleException { 。 。 。 略
2016-08-16 21:59:55
465
原创 Tomcat源码阅读之初始化连接器组件
Server组件初始化之后,接着就该初始化Service组件。public void initialize() throws LifecycleException { initialized = true; 。 。 。
2016-08-14 14:37:03
687
原创 Tomcat源码阅读之初始化Server组件
组件实例化完之后,便进入到了组件的初始化过程,进行initialize操作,注意这里的初始化跟前面的实例化是两个不同的操作。 首先初始化扥是Server组件。public void initialize() throws LifecycleException { lifecycle.fireLifecycleEvent(INIT_EVENT, nul
2016-08-08 22:10:19
417
原创 Tomcat源码阅读之实例化Container
Container组件在Tomcat中代表容器组件,其对应的接口名称为Container,所有的Servlet容器都必须要实现这个接口。实例化Container组件,也就是实例化Tomcat的四个Servlet容器,分别是Engine,Host,Context,Wrapper。对应的接口分别是Engine,Host,Context,Wrapper,都继承自Container接口,标准实现类分别为S
2016-08-06 21:59:53
468
原创 Tomcat源码阅读之Load过程
tomcat的load过程是从Bootstrap类的load方法开始的。load方法通过反射调用Catalina类的load方法。整个load过程主要有两条主线,一条主线是利用Digester的方式实例化容器组件,另一条主线是根据容器组件等级关系,进行逐级初始化。容器组件等级请查看tomcat组成图。 那么首先阅读Digester实例化容器组件部分的源码。protected Digest
2016-08-01 21:07:07
458
原创 Tomcat源码阅读之Init过程
Tomcat启动过程相当复杂,总结起来大概分为三个阶段,分别是初始化(Init)过程,加载(load)过程和启动(start)过程。先来分析下初始化的过程。程序的入口是Bootstrap类的main方法。
2016-07-07 22:18:00
908
原创 Tomcat源码阅读
Tomcat是一款非常优秀的servlet容器或者说是服务器,相信很多人都能非常熟练的使用它。但是对于技术有基情的人是不会仅仅停留在熟练使用的阶段的。为了不只当一个熟练工,那么我们就要去研究它运行的原理。研究运行原理最好的办法当然就是去阅读tomcat的源码。当然,阅读源码必须得讲究方式方法了,每个人的理解方式不同,阅读的方法也就不一样了。比如把tomcat拆分成不同的组件,一个一个的剖析,这是最
2016-06-25 15:20:30
1387
原创 Aop源码分析之如何实现功能增强
Aop的核心原理概括起来就是代理和拦截。代理对象生成之后,当我们调用目标对象被代理的方法时,就会触发拦截器的拦截功能,从而实现增强目标对象功能的作用。拦截器对目标对象方法进行拦截的方式是回调,比如使用Jdk动态代理生成的对象都会实现InvocationHandler接口,那么就需要在回调invoke方法中实现拦截,即增强,同理如果使用Cglib的方式生成代理对象,那么实现拦截功能的就是回调方法就是i
2016-05-10 22:48:00
718
原创 Aop源码分析之生成代理对象
Java中生成代理对象有两种方式,一种是Jdk原生的动态代理,另一种就是利用Cglib。Jdk原生的动态代理只能实现对接口的代理,无法实现对Class类的代理,因此Spring中引入Cglib来实现Class类的动态代理。 Aop中代理对象是在ProxyFactoryBean类的getSingletonInstance方法中生成的。 进入createAopProxy方法。createAopP
2016-05-08 16:04:36
1074
原创 AOP源码分析之初始化通知器链
因为配置了Aop的缘故,所以getBean获取的实例也不再是本身的实例对象,而是代理对象。那么我们来看下这个代理对象生成的过程。 根据Aop配置文件的内容,先找到org.springframework.aop.framework.ProxyFactoryBean这个类。ProxyFactoryBean类实现了FactoryBean接口,所以是个FactoryBean。FactoryBean中有
2016-05-04 23:44:33
603
原创 Spring实现AOP源码分析
Aop又叫面向切面编程,它的作用就是管理分散在整个应用中的变动。这句话理解起来有点抽象,举个例子,比如我想在多个方法中加一些打印日志,看下这些方法耗时如何,这些日志信息就是程序中的变动,而且是分散在各个不同的方法中的。如果我一个一个方法中去加日志信息的话,方法数量少的情况还可以勉强维护,如果数量多的话,维护起来就比较头疼了。这个时候我们就可以使用Aop来统一管理这些日志信息,后期的维护也就相对轻松的
2016-03-20 17:55:02
1529
原创 Spring依赖注入源码分析
Bean已经实例化,接下来便是依赖注入。 回到AbstractAutowireCapableBeanFactory类的populateBean方法。 方法中,先从RootBeanDefinition中获取属性值,这些属性保存的内容是配置文件解析完之后的值,将配置文件解析成BenDefinition的过程,前面有专门的文章描述。对属性进行注入的实现在applyPropertyVa
2016-03-13 17:13:19
3713
1
原创 依赖注入之Bean的实例化
上一篇分析到了通过递归的方式获取Bean的所有依赖,接下来就该实例化Bean了。 对于实例化Bean,Spring提供了两种方式,一种是Jdk的反射功能,还有一种就是Cglib。这两种实例化的方式的区别是什么呢? 依赖注入的起点是getBean方法,然后会调用createBean方法来实现这个过程。 进入createBean方法 resolveBeanClass方法判断需要创建的
2016-03-12 12:47:21
2449
1
原创 依赖注入之Bean实例化前的准备
IOC容器虽然已经构造好,但现在的容器只是一个壳,对象间的依赖关系还未进行填充。那么接下来便分析填充依赖关系的过程,即依赖注入。依赖注入主要有两个过程,一个是实例化Bean,另一个是将依赖关系注入到Bean中。 依赖注入的入口是我们熟悉的getBean方法。 AbstractBeanFactory的doGetBean方法是具体实现依赖注入的地方 方法中的代码较多
2016-03-08 22:51:40
2965
原创 IOC容器构造之注册BeanDefinition源码分析
解析完配置文件,接下来便是BeanDefinition的注册了。为了不至于每次用到配置信息的时候都去解析一遍配置文件,我们需要将解析结果保存起来。而保存解析结果这个过程就是BeanDefinition的注册。既然是保存,那就需要一个保存的容器,这个容器就是HashMap。于是BeanDefinition的注册就变成了将解析之后的BeanDefinition信息保存在HashMap中这样一个操作。具体
2016-03-06 17:21:07
924
原创 IOC容器构造之加载和解析配置文件
资源文件的定位已分析完,接下来便是加载和解析配置文件。如果资源文件都已经定位到了,加载配置文件这一步也就算完成了。那么本篇文章的重点就是解析配置文件了。这个解析有两层的解析关系。第一层的解析是按照正常的XML文件的解析方式来解析配置文件。第二层的解析是在第一层解析的基础上,按照Spring的Bean的配置规则再来解析一次。 意思就是说配置文件中关于Bean的配置项,在经过第二层的解析之后,就会被映
2016-03-05 22:51:58
1288
原创 IOC容器构造之资源文件定位源码分析
接着上一篇顺藤摸瓜,Spring版本3.2.16,代码调试工具Eclipse,没有可直接导入Eclipse源码的同志可在下方留言,寡人免费赠送一份。接下来以ApplicationContext容器系列为例,通过分析ApplicationContext的实现来分析资源定位的相关源码。 ApplicationContext是一个接口,它的主要实现有两个,FileSystemXmlApplication
2016-02-28 19:14:10
865
1
原创 Spring源码学习
不知不觉已经工作快两年,期间也阅读过些许源代码,无奈未进行系统的归纳和总结,过一段时间就忘的一干二净。记得有个前辈说过,人类对于一些无序的东西很容易就忘了,现在看来很是有道理,于是便想借用博客的方式再学习一次。学习源码的过程是坎坷的,主要是因为源码的代码量都很大,没有一个清晰的目标和一个主要的学习线路,很容易就会钻进代码的森林里面找不到北,这里看一点,那里看一点,零零散散连不成一条完整的线,其结果就
2016-02-28 12:29:45
676
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人