`
m635674608
  • 浏览: 5027575 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

架构设计:系统间通信之MQ:消息协议解析(上)

 
阅读更多

1、概述

从本文开始,我们介绍另一类型的系统间通讯及输:MQ消息队列。首先我们将讨论几种常用消息队列协议的基本原理和工作方式,包括MQTT、XMPP、Stomp、AMQP、OpenWire等。然后在这个基础上介绍两款MQ产品:ActiveMQ和RabbitMQ,它们是现在业务系统中应用广泛的消息队列软件。包括他们的安装、运行、支持协议、集群化和调用方式。

当然,在这个过程中我们还会提到其他的消息队列协议(或者实现),例如微软JBossMQ、MSMQ、商业化产品WebSphere MQ、Oracle高级队列(AQ)等。我们还会讨论这些眼花缭乱的协议、软件、程序库之间的关系

随后我们会花一些篇幅,讨论现在新兴的消息队列Kafka和ZeroMQ。它们的应用越来越广泛,尤其在大数据的采集方面。最后我们将使用消息队列搭建一个高性能的日志采集系统,作为实战。

2、基本概念

2-1、消息

首先有三个基本概念在开篇前我们需要进行讨论:消息、消息协议、消息队列。消息既是信息的载体 这个描述相信各位读者都能够明白。为了让消息发送者和消息接收者都能够明白消息所承载的信息(消息发送者需要知道如何构造消息;消息接收者需要知道如何解析消息),它们就需要按照一种统一的格式描述消息,这种统一的格式称之为消息协议。所以,有效的消息一定具有某一种格式;而没有格式的消息是没有意义的

而消息从发送者到接收者的方式也有两种。一种我们可以称为即时消息通讯,也就是说消息从一端发出后(消息发送者)立即就可以达到另一端(消息接收者),这种方式的具体实现就是我们已经介绍过的RPC(当然单纯的http通讯也满足这个定义);另一种方式称为延迟消息通讯,即消息从某一端发出后,首先进入一个容器进行临时存储,当达到某种条件后,再由这个容器发送给另一端。 这个容器的一种具体实现就是消息队列

2-2、知识结构

消息队列和已经介绍过的RPC相同的是:无论是RPC也好,消息队列也好他们都建立在网络IO模型基础上(我们已经介绍过多种网络IO模型)。先进的网络IO模型将赋予MQ协议优异的性能表现(当然,性能也不仅仅取决于网络IO模型)。

这里写图片描述

从上图可以看到,某一种消息通讯软件(或者叫做程序库)的实现都建立在“协议”基础上:RMI程序库建立在RMI协议上(RMI协议是Java规范协议的一部分) ,属于一种“即时消息通讯”;RabbitMQ和Qpid消息通讯软件的设计依据是AMQP协议,属于一种“延迟消息通讯”。

虽然消息协议存在“私有协议”和“开放协议”之分(是否向行业开放消息规范文档、是否允许某个组织更改协议),虽然某一个软件(程序库)不一定只支持一种协议(例如ActiveMQ实现了多种消息协议),虽然某一种协议也不一定只有一种软件(程序库)实现(例如能够支持webservice协议的程序库就有Codehaus XFire、Apache CXF、Jboss RESTEasy等),但是这并不影响“某一种消息通讯软件(或者叫做程序库)的实现都建立在“协议”基础上”的概念,反而是这个基本概念加强了。

3、消息协议

那么要理解消息队列,我们就应该从这些支持“延迟消息通讯”的消息协议开始讨论。这个小节我们首先为各位读者介绍几种使用的消息协议,他们是XMPP、Stomp和AMQP。为了承接后文我们讲解的MQ软件,这三个协议中我们又着重讲解AMQP协议。

3-1、XMPP协议

3-1-1、定义

XMPP is the Extensible Messaging and Presence Protocol, a set of open technologies for instant messaging, presence, multi-party chat, voice and video calls, collaboration, lightweight middleware, content syndication, and generalized routing of XML data.

以上内容引用自XMPP官网,这个定义已经可以清楚表明XMPP协议的用途和特性。XMPP的前身是Jabber,一个开源形式组织制定的网络即时通信协议。XMPP目前被IETF国际标准组织完成了标准化工作。

XMPP基于XML,用于IM系统的开发。国内比较流行的XMPP服务器叫做Openfire,它使用MINA作为下层的网络IO框架(不是MINA2是MINA1);国外用的比较多的XMPP服务器叫做Tigase,它的官网号称单节点可以支撑50万用户在线,集群可以支持100万用户在线:(http://projects.tigase.org/

Cluster with over 1mn online users . 500k online users on a single machine

当然如果读者所在公司需要开发IM系统,除了使用现成的XMPP服务器以外,还需要实现了XMPP协议的客户端或者开发包(以便进行扩展开发)。您可以在XMPP官网查看到XMPP官方推荐的开发包,各种语言的支持基本上都有:http://xmpp.org/software/libraries.html

笔者曾参与过某几款IM系统的开发(包括自己创业的项目),总的来说XMPP协议本身是不错的选择,但是学习起来会耗费相当的时间,并且某些XMPP客户端、服务器端或者程序库并没有这些开发团队宣传的那么稳定好用。所以如果您的公司需要进行IM系统的开发,那么创立私有的消息协议也会是一个不错的选择

3-1-2、协议通讯过程示例

为了让各位读者对XMPP协议有一个感性认识,这里我们给出一个XMPP协议处理“IM用户登录”操作的过程(XMPP的登录方式分为有用户密码和无用户密码两种方式,这里我们介绍无密码登录方式)。

XMPP协议本身细节比较丰富,这里我们只讨论登录操作,如果读者有兴趣可以下载全套的XMPP官方规范文档进行研究(http://xmpp.org/):

这里写图片描述

通过上图可以看到,XMPP协议中的xml片段。这里出现了几个XMPP协议中的关键信息,例如:

  • stream标记:通讯流标记,是指XMPP的客户端或者服务器端向对方发起的通讯请求(或者响应)。通讯流并不携带正真的内容信息,指示表明客户端和服务器端发生了一次交互。stream的属性包括:to、from、id、xml:lang、version等。

  • iq标记:iq标记是Info/Query的简称(你可以理解成查询信息请求),一般是一组的形式出现,由客户端发起查询请求,由服务器端返回查询结果。由于查询请求的类型不一样,iq标记中可以嵌入的子标记就有很多。例如,可以嵌入bind标记,表明某个用户和jid的绑定关系;可以嵌入多个item标记,表明查询得到的这个用户的好友信息(如下)。

<iq to='somenode@example.com/someresource' type='result' id='roster'>  
    <query xmlns='jabber:iq:roster'>  
        <item jid='friend1@example.com' name='someone1'/>  
        <item jid='friend2@example.com' name='someone2'/>  
    </query>  
</iq>
  • jid标记:jid(JabberID)是XMPP协议中标示,它用来标示XMPP网络中的各个XMPP实体(实体可以是某一个用户、某一个服务器、某一个聊天室),规范格式如下:
jid = [ node "@" ] domain [ "/" resource ] 
  • 还有未出现的message、presence标记:message是实体内容标记,记录了聊天的真实内容;presence标记表示了XMPP用户的服务状态(离线,在线、忙碌等)。示例如下:
<message to="somenode@example.com/someresource" type="chat"> 
    <body>helloword。。。</body> 
</message> 

3-2、Stomp协议

3-2-1、定义

Stomp协议,英文全名Streaming Text Orientated Message Protocol,中文名称为 ‘流文本定向消息协议’。是一种以纯文本为载体的协议(以文本为载体的意思是它的消息格式规范中没有类似XMPP协议那样的xml格式要求,你可以将它看作‘半结构化数据’)。目前Stomp协议有两个版本:V1.1和V1.2。

一个标准的Stomp协议包括以下部分:命令/信息关键字、头信息、文本内容。如下图所示:

这里写图片描述

以下为一段简单的协议信息示例:

CONNECT
accept-version:1.2
someparam1:value1
someparam2:value2

this is conntecon ^@

上面的示例中,我们使用了Stomp协议的CONNECT命令,它的意思为连接到Stomp代理端,并且携带了要求代理端的版本信息和两个自定义的K-V信息(请注意’^@’符号,STOMP协议中用它来表示NULL)。

Stomp协议中有两个重要的角色:STOMP客户端与任意STOMP消息代理(Broker)。如下图所示:

这里写图片描述

看了上面的示意图后有的读者可能会问:为什么称为Stomp消息代理,而不称为Stomp消息服务?因为Stomp Broker只是负责接受和存储客户端发来的消息、只是按照客户端要求的路径转发消息,只是管理客户端连接和订阅:它并不负责根据消息内容做任何业务处理。所以将它称为消息代理端更贴切。

由于Stomp协议的结构如此简单,以至于任何理解Stomp协议命令格式的技术人员都可以开发Stomp的代理端或者Stomp的客户端,并将自己满足Stomp协议的系统轻松接入另一个同样满足Stomp协议的第三方系统(例如activeMQ)

3-2-2、基本命令/返回信息

和介绍XMPP协议的方式类似,为了让读者对Stomp协议有进一步的认识,本小节我们介绍Stomp协议的基本命令和代理端返回的信息种类,并且列举一些实例进行使用讲解。

在Stomp协议中,主要有以下命令/返回信息(有的文章中也称一个完整的信息为帧)。这些命令/返回信息构成了Stomp协议的主体,并能够支持您的Stomp客户端和Stomp代理端完成连接、发送、订阅、事务、响应的整个操作过程。这些命令/返回是:

  • CONNECT/STOMP命令: 客户端通过使用CONNECT命令,连接到Stomp代理端。如果使用STOMP命令,那么Stomp代理端的版本必须是1.2。

  • CONNECTED信息:当Stomp代理端收到客户端发送来的Connect命令并且处理成功后,将向这个客户端返回CONNECTED状态信息;如果这个过程中出现任何问题,还可能返回ERROR信息

  • SEND 发送命令:客户端使用SEND命令,向某个指定位置(代理端上的一个虚拟路径)发送内容。这样在这个路径上订阅了消息事件的其它客户端,将能够收到这个消息。

  • SUBSCRIBE 订阅命令:客户端使用SUBSCRIBE订阅命令,向Stomp服务代理订阅某一个虚拟路径上的监听。这样当其它客户端使用SEND命令发送内容到这个路径上时,这个客户端就可以收到这个消息。在使用SUBSCRIBE时,有一个重要的ACK属性。这个ACK属性说明了Stomp服务代理端发送给这个客户端的消息是否需要收到一个ACK命令,才认为这个消息处理成功了。如下所示:

SUBSCRIBE
id:XXXXXXXXX
destination:/test
ack:client

^@

以上SUBSCRIBE命令信息说明,客户端订阅的虚拟位置是test。且命令信息中ack属性为client,说明当客户端收到消息时,必须向代理端发送ack命令,代理端才认为这个消息处理成功了(ack的值只有三种:auto(默认)、client和client-individual)。

  • UNSUBSCRIBE 退订命令:客户端使用这个命令,取消对某个路径上消息事件的监听。如果客户端给出的路径之前就没有被这个客户端订阅,那么这个命令执行无效。

  • MESSAGE 信息:当客户端在某个订阅的位置收到消息时,这个消息将通过MESSAGE关键字进行描述。类似以下信息就是从代理端拿到的消息描述:

MESSAGE
redelivered:true
message-id:ID:localhost-34450-1457321490460-4:24:-1:1:1
destination:/test
timestamp:1457331607873
expires:0
priority:4

2345431457331607861
  • BEGIN 开始事务命令: Stomp协议支持事务模式,在这种模式下,使用Send命令从某个客户端发出的消息,在没有使用COMMIT正式提交前,这些消息是不会真正发送给Stomp代理端的。BEGIN命令就是用于开启事务。注意,一个事务中可以有一条消息,也可以有多条消息

  • COMMIT 提交命令: 当完成事务中的信息定义后,使用该命令提交事务。只有使用COMMIT命令后,在某一个事务中的一条或者多条消息才会进入Stomp代理端的队列(订阅了事件的其它客户端才能收到这些消息)。

  • ABORT 取消/终止事务命令:很明显,这个命令用于取消/终止当前还没有执行COMMIT命令的事务。

  • ACK 确认命令:当客户端使用SUBSCRIBE命令进行订阅时,如果在SUBSCRIBE命令中制定ack属性为client,那么这个客户端在收到某条消息(id为XXXX)后,必须向Stomp代理端发送ACK命令,这样代理端才会认为消息处理成功了;如果Stomp客户端在断开连接之前都没有发送ACK命令,那么Stomp代理端将在这个客户端断开连接后,将这条消息发送给其它客户端

ACK
id:MESSAGE ID

^@

请注意head部分的id属性,传递的id属性是之前收到的MESSAGE信息的id标示。

  • NACK 不确认命令:同样是以上的SUBSCRIBE命令的状态下,如果这时Stomp客户端向Stomp代理端发送NACK信息,证明这条消息在这个客户端处理失败。Stomp代理端将会把这条消息发送给另一个客户端(无论当前的客户端是否断开连接)

  • DISCONNECT 断开命令:这个命令将断开Stomp客户端与Stomp代理端的连接。

                (接下文)

http://blog.csdn.net/yinwenjie/article/details/50698695

分享到:
评论

相关推荐

    C#注册MQ消息队列

    在IT领域,尤其是在分布式系统与微服务架构中,消息队列(Message Queue,简称MQ)作为重要的异步通信机制,其应用广泛且深入。本文将深入解析如何利用C#语言来实现与MQ消息队列的注册及通信过程,具体探讨的知识点...

    MQ最佳实践_MQ_

    在IT行业中,消息队列(Message Queue,简称MQ)是分布式系统中的重要组件,用于处理异步通信、解耦组件以及提高系统的可扩展性。本最佳实践将深入探讨MQ的关键概念、设计原则和实际应用场景,旨在帮助开发者优化其...

    MB_MQ_Tools

    MQ是企业级的消息传递系统,用于在不同的应用程序之间安全、可靠地传输数据,尤其在分布式和SOA(Service-Oriented Architecture,面向服务架构)环境中广泛应用。在SOA中,MQ扮演着服务间通信的关键角色,确保服务...

    IBM MQ System Administrator Guide

    #### 综上所述,IBM MQ System Administrator Guide是专为系统管理员设计的深度指导手册,旨在提供全面、详尽的管理技巧和最佳实践,以确保IBM MQ在复杂的企业环境中能够稳定、高效地运行。通过对本指南的学习,管理...

    websphere MQ 8.0 自带jar包

    WebSphere MQ(原名 MQSeries)是 IBM 提供的一种企业级的消息队列系统,它允许应用程序通过网络异步交换消息,提供了一种可靠且高效的数据传输机制。这种系统在分布式环境中特别有用,因为它可以处理网络故障、...

    MQ相关资料 内容齐全

    MQ的基本理念是通过消息队列实现应用间的通信,它允许应用程序在不直接互相依赖的情况下交换数据。在入门阶段,你需要理解MQ的核心概念,如消息、队列、通道和队列管理器。了解如何创建、发送、接收和管理消息是学习...

    精通 WebSphere MQ.pdf

    消息中间件是一种软件层,它作为应用之间的通信桥梁,实现异构系统间的数据交换与信息传递。WebSphere MQ是IBM开发的消息中间件产品,以其高可靠性、安全性及可扩展性在企业级应用中占据重要地位。 #### 1.2 ...

    Websphere_MQ入门教程(中文)

    - 开发人员,希望在项目中引入Websphere MQ以改善系统间的通信 - 系统管理员,负责Websphere MQ的部署、管理和维护 - IT架构师,考虑在企业架构中使用Websphere MQ作为基础组件 ### 进一步参考资料 为了深入学习...

    大型分布式网站架构设计与实践.rar

    总的来说,《大型分布式网站架构设计与实践》是一本全面解析分布式系统设计的宝典,它不仅介绍了各种核心技术,还分享了实际项目中的经验教训,对于想要提升分布式架构设计能力的IT从业者来说,具有极高的参考价值。...

    基于springcloud+Netty+MQ+mysql的分布式即时聊天系统.zip

    综上所述,构建基于SpringCloud+Netty+MQ+MySQL的分布式即时聊天系统涉及到的技术和考虑点众多,涵盖了微服务架构、实时通信、消息中间件、数据库管理等多个层面,每个环节都需要精细设计和优化,以满足即时聊天系统...

    MQ java 编程指南

    对于分布式系统的设计,书中有专门的章节讨论如何利用MQ实现微服务间的通信,包括事件驱动架构、发布/订阅模式以及点对点模型。这部分内容有助于开发者构建高可用、可扩展的应用架构。 为了确保代码的健壮性,书中...

    Ibm - Websphere Mq Using Java (v5.3), 3Rd Ed - 2004 - (By Laxxuss).pdf

    - **架构师**:设计基于 WebSphere MQ 的消息传递系统。 **1.4 连接选项** - **客户端连接**:客户端连接是指通过客户端 API 与远程队列管理器建立连接的方式。这种方式下,客户端可以直接访问远程队列管理器中的...

    websphere mq 7.0新功能介绍

    SOA 是一种设计原则,它将业务逻辑抽象为一系列独立的服务,这些服务可以通过标准化协议进行通信。Websphere MQ 7.0 通过以下特性增强了这一能力: - **服务编排**:支持服务的灵活组合,使得企业可以根据需要快速...

    MQ选型之RabbitMQ

    MQ,即消息队列(Message Queue),是一种应用程序间通信方法,通过消息的存储与转发来实现组件间的解耦。队列可以被形象地理解为一种数据结构,它遵循先进先出(FIFO)原则。消息队列作为一种软件架构模式,允许程序...

    Java监控WebSphere MQ 7.5中间件信息

    1. **WebSphere MQ架构**:WebSphere MQ采用客户端-服务器模型,由Queue Manager(队列管理器)、Queues(队列)、Channels(通道)和Message(消息)等核心组件构成。Queue Manager负责管理消息的存储和转发,...

    Websphere MQ入门教程

    在信息技术领域,IBM Websphere MQ(简称WMQ)是一种广泛使用的中间件,它提供了一种可靠的消息传递机制,确保数据在分布式系统中的安全传输。本入门教程将引导读者深入理解Websphere MQ的基础概念、工作原理以及其...

    mq-advanced-demo

    在信息技术领域,消息队列(Message Queue,简称MQ)是一种常用于系统间异步通信的技术。它允许应用程序通过发送和接收消息来相互通信,而无需直接调用彼此,从而提高了系统的可扩展性和可靠性。本示例“mq-advanced...

    MQ之ActiveMQ思维导图.zip

    **ActiveMQ 概述** ActiveMQ 是 Apache 开源组织提供的一款高效、强大的消息...通过这个“MQ之ActiveMQ思维导图”,读者可以系统地理解和掌握 ActiveMQ 的核心功能和应用场景,进一步提升在消息队列领域的专业技能。

Global site tag (gtag.js) - Google Analytics