之前说过,JDK中的RMI框架在JDK1.1、JDK1.2、JDK1.5、JDK1.6+几个版本中做了较大的调整。以下我们讨论的RMI工作原理都是基于JDK1.6+版本的。3、JAVARMI工作原理通过上面的两组代码,我们大概知道了RMI框架是如何使用的。下面我们来讲解一下RMI的基本原理。本人翻阅网上的众多RMI资料基本上代码都是一大抄(甚至变量名、语法错误都一样),还有很多资料存在误导读者的情况。下图描述了整个RMI框架的几个核心概念:3-1、Registry和Stub、Skeleton的关系一定要说明,在RMIClient实施正式的RMI调用前,它必须通过LocateRegistry或者
1、概述在概述了数据描述格式的基本知识、IO通信模型的基本知识后。我们终于可以进入这个系列博文的重点:系统间通信管理。在这个章节我将通过对RMI的详细介绍,引出一个重要的系统间通信的管理规范RPC,并且继续讨论一些RPC的实现;再通过分析PRC的技术特点,引出另一种系统间通信的管理规范ESB,并介绍ESB的一些具体实现。最后我们介绍SOA:面向服务的软件架构。2、RMI基本使用RMI(RemoteMethodInvocation,远程方法调用),是JAVA早在JDK1.1中提供的JVM与JVM之间进行对象方法调用的技术框架的实现(在JDK的后续版本中,又进行了改进)。通过RMI技术,某一个本地
5-4、ESB-Client端的ActiveBrokerContext本小节开始,我们将按照前文介绍的ESB-Client的核心步骤,一点一点的给出ESB-Client端和ESB-Broker进行交互的核心代码。为了方便在ESB-Client端进行ESB-Broker的交互,我们设计了一个ActiveBrokerContext类。读者可以将这个类理解为“ESB-Broker交互上下文”,在ESB-Client端中所有和ESB-Broker的交互过程都由在这里进行控制。我们首先看一下这个类中的主要定义:packageesb.client;....../***这是一个“上下文管理器”,用于为ESB
5、BorkerServer选择在本文之前的三篇文章中,我们介绍了自行设计的ESB中间件的顶层设计、介绍了主控服务如何对多个ESB-Brokers动态节点进行日志采集和监控、还介绍了ESB-Broker节点如何进行动态路由定义的加载管理。这篇文章我们主要讨论关于ESB-Client的一些关键设计。在我们自行设计的ESB中间件中为了保证ESB服务不会成为整个软件系统的瓶颈,我们为ESB服务设计了多个ESB-BrokerServer节点共同运行的方式。多个ESB-Client的请求将按照一定的规则被分配到这些ESB-Broker节点上进行处理,并且这些ESB-Client节点将根据为它们服务的ES
4-2-3、业务层与Class文件管理zookeeper控制模块的业务相关层(封装层),负责根据ApacheCurator层分析好的事件类型、PathNode名称信息、PathNode内容信息,进行Class文件的生成。这里的关键点是,ApacheCamel有一个动态加载的限制:它只能在被创建的线程中完成Service(例如Route路由定义)的动态加载过程。ApacheCurator事件监听规则基于zookeeper原生客户端,当发生ZK事件时ApacheCurator会使用一个独立线程处理这个事件而不是在启动ApacheCurator组件的线程。所以ApacheCamel的Context上
4、BrokerServer设计那么如何赋予ESB中间件原子服务整合、服务路由编排的关键能力呢?读者当然可以自行实现ESB中间件中这两个关键模块的功能,但问题的关键是即使是一个团队负责这部分的开发工作也不可能在短时间内完成该模块的开发,而且功能完整度和模块性能也不一定能达到设计之初的要求。所以在我们自行设计的ESB中间件中,选择将原子服务整合功能和服务路由编排功能交给我们已经介绍过的ApacheCamel组件。另一方面,为了保证ESB中间件不会成为整个软件顶层设计中的性能瓶颈,ESB中间件将采用多运行节点的方式为各个业务系统服务(就是前文中提到的ESB-BrokerServer节点)。在进行设
1、概述在我开始构思这几篇关于“自己动手设计ESB中间件”的文章时,曾有好几次动过放弃的念头。原因倒不是因为对冗长的文章产生了惰性,而是ESB中所涉及到的技术知识和需要突破的设计难点实在是比较多,再冗长的几篇博文甚至无法对它们全部进行概述,另外如果在思路上稍微有一点差池就会误导读者。一个可以稳定使用的ESB中间件凝聚了一个团队很多参与者的心血,一个人肯定是无法完成这些工作的。但是笔者思索再三,还是下决心将这这即便文章完成,因为这是对本专题从第19篇文章到第39篇文章中所介绍的知识点的最好的总结。我们自己动手设计ESB中间件,不是为了让它商用,也不是为了让它可以比拟市面上某款ESB中间件,甚至不
4-2-1、LifecycleStrategyLifecycleStrategy接口按照字面的理解是一个关于Camel中元素生命周期的规则管理器,但实际上LifecycleStrategy接口的定义更确切的应该被描述成一个监听器:当Camel引用程序中发生诸如Route加载、Route移除、Service加载、Serivce移除、Context启动或者Context移除等事件时,DefaultCamelContext中已经被添加到集合“lifecycleStrategies”(java.util.List)的LifecycleStrategy对象将会做相应的事件触发。读者还应该注意到“life
3-5-2-3循环动态路由DynamicRouter动态循环路由的特点是开发人员可以通过条件表达式等方式,动态决定下一个路由位置。在下一路由位置处理完成后Exchange将被重新返回到路由判断点,并由动态循环路由再次做出新路径的判断。如此循环执行直到动态循环路由不能再找到任何一条新的路由路径为止。下图来源于官网(http://camel.apache.org/dynamic-router.html),展示了动态循环路由的工作效果:这里可以看出动态循环路由(dynamicRouter)和之前介绍的动态路由(recipientList)在工作方式上的差异。dynamicRouter一次选择只能确定
3-1-2、特殊的EndpointDirectEndpointDirect用于在两个编排好的路由间实现Exchange消息的连接,上一个路由中由最后一个元素处理完的Exchange对象,将被发送至由Direct连接的下一个路由起始位置(http://camel.apache.org/direct.html)。注意,两个被连接的路由一定要是可用的,并且存在于同一个Camel服务中。以下的例子说明了EndpointDirect的简单使用方式。packagecom.yinwenjie.test.cameltest.helloworld;importorg.apache.camel.builder.R
1、本专题主旨1-1、关于技术组件在这个专题中,我们介绍了相当数量技术组件:Flume、Kafka、ActiveMQ、Rabbitmq、Zookeeper、Thrift、Netty、DUBBO等等,还包括本文要进行介绍的ApacheCamel。有的技术组件讲得比较深入,有的技术组件则是点到为止。于是一些读者朋友发来信息向我提到,这个专题的文章感觉就像一个技术名词的大杂烩,并不清楚作者的想要通过这个专题表达什么思想。提出这个质疑的朋友不在少数,所以我觉得有必要进行一个统一的说明。这个专题的名字叫做“系统间通讯”,在这个专题中我的讲解主要是围绕自己在实际工作中所总结的理论结构。从系统间通讯最基本的
2-4、ESB与版本控制企业中的系统集成过程,存在很多非技术因素引起的变化。可能出现的情况是,某个一直能够正常使用的调用功能A,在某一天突然就不能使用了。技术团队和业务团队排查了许久才发现功能A中对某个业务系统的调用接口已经被私自更改(可能只是多传递了一个参数、或者减少了一个参数的传递)。这种情况在现实中经常出现,可能是业务部门出于私利对外屏蔽了这个接口,也可能是技术人员在改动接口时,忘记了这个接口还有外部系统进行使用。ESB中间件提供的版本管理功能可以帮助我们解决这个问题。这里说的版本管理功能,并不是像Git那样面向整个工程的版本管理,而是细化到服务接口层面的版本管理。以下示意图向读者展示了
1、概述从本篇文章开始,我们将花一到两篇的篇幅介绍ESB(企业服务总线)技术的基本概念,为读者们理清多个和ESB技术有关名词。我们还将在其中为读者阐述什么情况下应该使用ESB技术。接下来,为了加深读者对ESB技术的直观理解,我们将利用ApacheCamel一起搭建一个ESB技术的服务实现,虽然这个示例不能把目前主流的ESB服务实现中所有功能模块都保罗进来,但至少可以让读者看到ESB技术核心服务完整的工作方式。2、为什么需要ESB2-1、ESB与SOA2-1-1、SOASOA(Service-OrientedArchitecture)中文全称“面向服务的架构”。放在当下的技术环境(2015/20
5-7、解决方案三:非侵入式方案以上两种方案中为了让业务系统能够集成日志采集功能,我们或多或少需要在业务系统端编写一些代码。虽然通过一些代码结构的设计,可以减少甚至完全隔离这些代码和业务代码的耦合度,但是毕竟需要业务开发团队花费精力对这些代码进行维护,业务系统部署时业务对这些代码的配置信息做相应的调整。这里我们再为读者介绍一种非侵入式的日志采集方案。我们都知道业务系统被访问时,都会产生一些访问痕迹。同样以“浏览商品详情”这个场景为例,当访问者打开一个“商品详情”页面时(URL记为A),那么首先Nginx的access日志就会有相应的80端口的访问日志,如果“商品详情”的信息并非全静态的,那么接
5-3、解决方案二:改进半侵入式方案5-3-1、解决方法一的问题所在方案一并不是最好的半侵入式方案,却容易理解架构师的设计意图:至少做到业务级隔离。方案一最大的优点在于日志采集逻辑和业务处理逻辑彼此隔离,当业务逻辑发生变化的时候,并不会影响日志采集逻辑。但是我们能为方案一列举的问题却可以远远多于方案一的优点:需要为不同开发语言分别提供客户端API包。上文中我们介绍的示例使用JAVA语言,于是事件/日志采集系统就要提供JAVA语言的客户端API包。如果需要集成事件/日志采集系统的业务系统,都是您公司内各个业务团队开发的,那么这个问题还算不上大问题——至少您可以知道优先开发哪种语言的客户端,也知道
5、场景应用——电商平台:浏览记录收集功能事件/日志收集系统是大中型软件不得不面对的话题。目前第三方业务系统对事件/日志收集系统的集成思路主要有两大类:侵入式收集方案和非侵入式收集方案。侵入式收集方案,是指任何需要使用事件/日志收集系统的第三方系统,都需要做有针对的编码工作,这个编码工作或者是新增代码用于调用事件/日志收集系统提供的客户端API,又或者是修改已有的代码,以便适应事件/日志收集系统的调用特性。侵入式方案又分为半侵入式和全侵入式。由于第三方系统的代码结构本身存在问题,所以一旦需要集成事件/日志收集系统(或者任何其他第三方系统),就会造成业务处理过程改变。相反,由于需求变动导致的业务
4-5、Kafka原理:消费者作为ApacheKafka消息队列,它的性能指标相当一部分取决于消费者们的性能——只要消息能被快速消费掉不在Broker端形成拥堵,整个ApacheKafka就不会出现性能瓶颈问题。4-5-1、基本使用我们首先使用KafkaClientForJAVAAPI为各位读者演示一下最简单的Kafka消费者端的使用。以下示例代码可以和上文中所给出的生产者代码相对应,形成一个完整的消息创建——接收——发送过程:packagekafkaTQ;importjava.util.HashMap;importjava.util.List;importjava.util.Map;impo
4-3、复制功能我们在上文中已经讨论了Kafka使用分区的概念存储消息,一个topic可以有多个分区它们分布在整个Kafka集群的多个Broker服务节点中,并且一条消息只会按照消息生产者的要求进入topic的某一个分区。那么问题来了:如果某个分区中的消息在被消费端Pull之前,承载该分区的Broker服务节点就因为各种异常原因崩溃了,那么在这个Broker重新启动前,消费者就无法收到消息了。为了解决这个问题,ApacheKafka在V0.8+版本中加入了复制功能:让topic下的每一个分区存储到多个Broker服务节点上,并由Zookeeper统一管理它们的状态。请注意Kafka中Parti
在本月初的写作计划中,我本来只打算粗略介绍一下Kafka(同样是因为进度原因)。但是,最近有很多朋友要求我详细讲讲Kafka的设计和使用,另外两年前我在研究Kafka准备将其应用到生产环境时,由于没有仔细理解Kafka的设计结构所导致的问题最后也还没有进行交代。所以我决定即使耽误一些时间,也要将Kafka的原理和使用场景给读者详细讨论讨论。这样,也算是对两年来自己学习和使用Kafka的一个总结。4、Kafka及特性ApacheKafka最初由LinkedIn贡献,目前它是Apache下的一个顶级开源项目。ApacheKafka设计的首要目标是解决LinkedIn网站中海量的用户操作行为记录、页
1、概述目前业界有很多消息中间件可供大家选择,主要分为两类:需要付费的商业软件和开源共享的非商业软件。对于商业软件您和您的团队可以选择IBMWebSphere集成的MQ功能,也可以选择OracleWebLogic集成的MQ功能。本文首先介绍除ApacheActiveMQ以外的两款开源共享的消息中间件产品,然后列举三个实际的业务常见,为读者介绍如何在这些实际业务中使用消息中间件解决问题。2、RabbitMQ及特性RabbitMQ基于Erlang语言开发和运行。它与ApacheActiveMQ有很多相同的特性,例如RabbitMQ完整支持多种消息协议:AMQP、STOMP、MQTT、HTTP,我们
3、ActiveMQ热备方案ActiveMQ热备方案,主要保证ActiveMQ的高可用性。这种方案并不像上节中我们主要讨论的ActiveMQ高性能方案那样,同时有多个节点都处于工作状态,也就是说这种方案并不提高ActiveMQ集群的性能;而是从集群中的多个节点选择一个,让其处于工作状态,集群中其它节点则处于待命状态。当主要的工作节点由于各种异常情况停止服务时,保证处于待命的节点能够无缝接替其工作。3-1、ActiveMQ高性能方案的不足那么有的读者可能会问,既然ActiveMQ的高性能方案中多个节点同时工作,在某个节点异常的情况下也不会影响其他节点的工作。这样看来,ActiveMQ的高性能方案
1、综述通过之前的文章,我们讨论了ActiveMQ的基本使用,包括单个ActiveMQ服务节点的性能特征,关键调整参数;我们还介绍了单个ActiveMQ节点上三种不同的持久化存储方案,并讨论了这三种不同的持久化存储方案的配置和性能特点。但是这还远远不够,因为在生产环境中为了保证让我们设计的消息服务方案能够持续工作,我们还需要为消息中间件服务搭建集群环境,从而在保证消息中间件服务可靠性和处理性能。2、ActiveMQ多节点方案集群方案主要为了解决系统架构中的两个关键问题:高可用和高性能。ActiveMQ服务的高可用性是指,在ActiveMQ服务性能不变、数据不丢失的前提下,确保当系统灾难出现时A
7、ActiveMQ的持久消息存储方案前文已经讲过,当ActiveMQ接收到PERSISTENTMessage消息后就需要借助持久化方案来完成PERSISTENTMessage的存储。这个介质可以是磁盘文件系统、可以是ActiveMQ的内置数据库,还可以是某种外部提供的关系型数据库。本节笔者将向读者讲解三种ActiveMQ推荐的存储方案的配置使用。如上图2.1的步骤所示,所有PERSISTENTMessage都要执行持久化存储操作,持久化存储操作方案的性能直接影响着整个MQ服务端的PERSISTENTMessage吞吐性能。另外NON_PERSISTENTMessage虽然不会进行持久化存储,
6、ActiveMQ处理规则和优化在ActiveMQ单个服务节点的优化中,除了对ActiveMQ单个服务节点的网络IO模型进行优化外,生产者发送消息的策略和消费者处理消息的策略也关乎整个消息队列系统是否能够高效工作。请看下图所示的消息生产者和消息消费者的简要工作原理图:Producer既是消息生产者,作为一个发送消息的客户端它既可以使用同步消息发送模式,也可以使用异步的消息发送模式。另外,消息生产者在ActiveMQ服务节点产生消息堆积的情况下,也不能一味的追求发送效率。还好,这种情况下消息生产者端有完整的保证机制——SlowProducer。另外,JMS提供事务功能,所以生产者是否开启事务发
3、ActiveMQ性能优化思路上篇文章中的两节内容,主要介绍消息中间件ActiveMQ的安装和基本使用。从上篇文章给出的安装配置和示例代码来看,我们既没有修改ActivieMQ服务节点的任何配置,也没有采用任何的集群方案。这种情况只适合各位读者熟悉ActiveMQ的工作原理和基本操作,但是如果要将ActivieMQ应用在生产环境下,上文中介绍的运行方式远远没有挖掘出它的潜在性能。根据这个系列文章所陈述的中心思想,系统的性能层次包括:代码级性能、规则性能、存储性能、网络性能,以及多节点协同方法(集群方案),所以我们优化ActiveMQ的中心思路也是这样的:首先优化ActiveMQ单个节点的性能
1、前言之前我们通过两篇文章(架构设计:系统间通信(19)——MQ:消息协议(上)、架构设计:系统间通信(20)——MQ:消息协议(下))从理论层面上为大家介绍了消息协议的基本定义,并花了较大篇幅向读者介绍了三种典型的消息协议:XMPP协议、Stomp协议和AMQP协议。本小节开始,我们基于之前的知识点讲解这些协议在具体的“消息队列中间件”中是如何被我们操作的。由于本人在实际工作中经常使用ActiveMQ和RabbitMQ,所以就选取这两个“消息队列中间件”进行讲解。如果读者可以补充其他“消息队列中间件”的使用,那当然是再好不过了。2、ActiveMQ的安装和使用ActiveMQ是Apache
上篇文章中我们重点讨论了“协议”的重要性,并为各位读者介绍了Stomp协议和XMPP协议。这两种协议是消息队列中两种不同使用场景下的典型代表。本文主要接续上文的篇幅,继续讨论消息队列中另一种典型协议:AMQP协议。3-3、AMQP协议AMQP协议的全称是:AdvancedMessageQueuingProtocol(高级消息队列协议)。目前AMQP协议的版本为Version1.0,这个协议标准在2014年通过了国际标准组织(ISO)和国际电工委员会(IEC)的投票,成为了新的ISO和IEC国际化标准。目前支持AMQP的软件厂商包括:3-3-1、协议概览在网络上讲解AQMP协议的文章已经有很多了
1、概述从本文开始,我们介绍另一类型的系统间通讯及输:MQ消息队列。首先我们将讨论几种常用消息队列协议的基本原理和工作方式,包括MQTT、XMPP、Stomp、AMQP、OpenWire等。然后在这个基础上介绍两款MQ产品:ActiveMQ和RabbitMQ,它们是现在业务系统中应用广泛的消息队列软件。包括他们的安装、运行、支持协议、集群化和调用方式。当然,在这个过程中我们还会提到其他的消息队列协议(或者实现),例如微软JBossMQ、MSMQ、商业化产品WebSphereMQ、Oracle高级队列(AQ)等。我们还会讨论这些眼花缭乱的协议、软件、程序库之间的关系。随后我们会花一些篇幅,讨论现
5-2、protocol:RPC调用层如果您直接看阿里提供的DUBBO框架的技术文档,您可以看到几个关键字和几张工作图。不过您肯定是无法通过那几张图搞清楚DUBBO框架的每一层是如何进行衔接,如何进行脱耦的。在这几篇文章中,我会主要从设计思路上,从DUBBO所采用的设计模式层面上,尽可能的向读者表达DUBBO框架的设计思路。在DUBBO框架中,有一个自己的RPC协议,名字叫做dubbo(小写的)。不止如此,DUBBO框架的RPC层还支持多种RPC协议的使用(hessian、thrift、RMI),还支持webservice协议和纯http协议。那么DUBBO框架是如何确认“哪个接口使用哪一种协
2-5、设计模式:代理模式和JAVA对代理模式的支持2-5-1、典型的代理模式下面这个类图说明了“代理模式”的典型设计设计结构:典型的代理模式可用一句话进行概括:外部系统/外部模块要调用某个具体业务的实现A,不能直接进行实调用,而要通过一个代理对象进行间接的调用。典型的dialing模式中有四个角色:Subject:业务接口定义。这个业务接口定义相关实现类的行为、事件等特性。RealSubject:您可以看业务定义的真实实现。设计的原则是:无论何种情况下它并不知道自己被“代理”了。Proxy:代理身份,帮助外部系统/外部模块完成具体业务实现A的调用。Client:外部系统/外部模块。接下来我们