架构成长篇 | 探索分析RedHat的AMQ7 — 全面功能与组件概览、部署架构模型(入门指南-上)

238 阅读18分钟

本文为稀土掘金技术社区首发签约文章,30天内禁止转载,30天后未获授权禁止转载,侵权必究!


背景介绍

Red Hat AMQ以其卓越的性能,为互联网级应用程序量身打造了快速、轻量且安全的消息传递解决方案。其核心组件AMQ Broker,凭借其多协议支持和高效的消息持久化能力,确保了消息传递的广泛兼容性与数据安全性。而AMQ互连功能,则巧妙运用AMQP协议,实现了消息传递资源在网络中的无缝分发与灵活扩展,助力企业构建更加灵活、强大的消息通信体系。

本文档深入剖析了Redhat的AMQ 7的卓越特性与核心组件架构,不仅彰显了其在消息传递领域的先进地位,还通过详尽阐述,展示了该版本所支持的一系列广泛应用的实用案例与高效设计模式。

主要功能

将AMQ组件视为工具箱中不可或缺的精密工具,它们既能够协同作战,共同构建和维护高效的消息传递应用程序,也各自具备独立担当的能力,灵活应对不同场景的需求。而AMQP,则如同工具箱中那神奇的粘合剂,以其强大的连接能力,将各个AMQ组件紧密地绑定在一起,形成一个协调统一、高效运转的整体。

在这里插入图片描述

可扩展规模的消息服务

在AMQ的赋能下,开发人员能够轻松地将客户端、代理以及独立服务编织进一个无缝衔接的消息传递生态系统中,实现数据的流畅传输与高效处理。这一生态系统以其卓越的扩展性与灵活性著称,能够轻松应对从简单到复杂、从单一应用到分布式系统的各种消息传递需求。

顶级的安全和性能机制

AMQ集成了先进的SSL/TLS加密技术,为消息传递过程构建了一道坚不可摧的安全防线,确保数据在传输过程中的机密性、完整性和抗篡改性。同时,它还支持可扩展的SASL身份验证机制,为不同场景下的用户认证需求提供了灵活多变的解决方案,进一步增强了系统的安全性与可靠性。

广泛的平台和语言支持

AMQ展现出了非凡的跨平台与跨语言互操作性,它如同一座桥梁,无缝连接了多样化的应用程序组件,使得无论这些组件采用何种编程语言或运行于何种操作系统之上,都能实现高效、流畅的通信。从C、C++到Java、JavaScript,再到Python、Ruby以及.NET等广泛应用的编程语言,AMQ均提供了全面的支持,确保了技术栈的多样性与灵活性。

专注于标准标准和协议

AMQ深度整合了Java JMS(Java Message Service)的API规范,不仅完美实现了JMS 1.1版本的全部功能,更前瞻性地兼容了JMS 2.0的先进特性,为Java开发者提供了一套丰富、标准且易于使用的消息传递接口。这一集成不仅简化了Java应用程序与消息系统之间的集成过程,还确保了消息传递的可靠性与高效性。

集中管理和管控机制

借助AMQ的集中化管理特性,您能够享受到前所未有的管理便捷性。通过统一的管理界面,您可以轻松实现对所有AMQ组件的集中监控、配置与优化,无需再为分散在多个界面的管理任务而烦恼。这一设计不仅简化了管理流程,还提高了管理效率,让您能够更专注于业务本身的发展。

组件概述

Red Hat的AMQ解决方案是一套精心设计的消息传递生态系统,其核心组件包括AMQ代理、AMQ互连、AMQ在线以及AMQ客户端。这些组件紧密协作,共同编织了一张高效、可靠的网络通信网,为分布式应用程序的顺畅运行提供了坚实的支撑。 在这里插入图片描述

AMQ Broker

AMQ Broker,作为一款功能全面且面向消息的中间件代理,凭借其卓越的架构设计,为企业级应用提供了强大的消息传递与处理能力。它集成了高级的寻址与排队机制,确保了消息能够准确无误地送达目标地址,同时支持快速的消息持久化,保障了数据的安全性与可靠性。

AMQ InterConnect

AMQInterconnect以其卓越的消息路由能力,在启用AMQP协议的各类端点之间构建了一个灵活、高效的通信桥梁。这一创新设计不仅涵盖了客户端、代理以及独立服务等多元化角色,还实现了消息传递的全方位覆盖。当客户端通过单一连接接入AMQInterconnect路由器网络时,它们便拥有了与网络中任意其他端点进行无缝消息交换的能力。

AMQInterconnect还具备高度的可扩展性与可配置性,能够轻松应对系统规模的增长与业务需求的变化。通过简单的配置调整或扩展节点,即可实现系统性能与容量的提升,确保消息传递系统的稳定运行与持续发展

AMQInterconnect的路由机制采用了先进的算法与策略,能够智能地根据消息的目的地、优先级、安全性等因素,选择最优的传输路径,确保消息能够准确、快速地送达目标端点。同时,它还支持多种消息传递模式,包括点对点、发布/订阅等,满足了不同应用场景下的消息传递需求。

AMQ Online

AMQ Online是一个构建于OpenShift平台之上的创新系统,它巧妙地将消息传递功能转化为一种高效的托管服务。这一平台赋予了管理员前所未有的灵活性,使他们能够在云端或企业内部环境中轻松部署并管理云原生的多租户消息传递服务。它的集中化控制台设计,使得多个开发团队能够共享并使用统一的代理和队列资源,而无需各自承担繁琐的安装、配置、部署、日常维护及软件修补工作。

AMQ Clients

AMQ客户端套件是一套精心设计的组件集合,涵盖了AMQP 1.0协议与JMS(Java Message Service)兼容的客户端、适配器及丰富库资源。此套件不仅全面支持JMS 2.0标准,还创新性地引入了前沿的事件驱动型API,旨在无缝融入并强化现有应用程序的集成能力。

AMQP客户端

客户端库(AMQ C++、AMQ JavaScript、AMQ JMS (Java)、AMQ .NET、AMQ Python、AMQ Ruby)通常是为了与ActiveMQ这样的消息中间件进行交互而设计的。

GitHub - apache/activemq: Mirror of Apache ActiveMQ

ActiveMQ是一个开源的消息代理和集成模式服务器,它支持多种传输协议,包括AMQP、STOMP、MQTT、OpenWire等,使得不同的客户端能够以不同的编程语言和框架与之通信。下面是对每个客户端库的分析:

在这里插入图片描述

AMQ C++
  • 用途:为C++开发者提供了一种与ActiveMQ交互的方式。
  • 特点:允许C++应用程序发送和接收消息,支持ActiveMQ的高级功能,如事务性会话、持久化消息等。
  • 适用场景:当需要在C++环境中实现消息驱动的应用或集成时,AMQ C++是一个很好的选择。
AMQ C++的案例代码

一个简单的C++客户端示例,该客户端将连接到ActiveMQ代理,发送一条消息,并尝试接收消息。

#include <activemq/core/ActiveMQConnectionFactory.h>  
#include <activemq/util/Config.h>  
#include <cms/ConnectionFactory.h>  
#include <cms/Destination.h>  
#include <cms/MessageConsumer.h>  
#include <cms/MessageProducer.h>  
#include <cms/Session.h>  
#include <cms/TextMessage.h>  
  
#include <iostream>  
  
using namespace std;  
using namespace activemq;  
using namespace activemq::core;  
using namespace cms;  
using namespace decaf::lang;  
  
int main() {  
    // 初始化ActiveMQ-CPP库  
    activemq::library::ActiveMQCPP::initializeLibrary();  
  
    // 创建连接工厂  
    auto_ptr<ConnectionFactory> connectionFactory(  
        ActiveMQConnectionFactory::createConnectionFactory("tcp://localhost:61616"));  
  
    // 创建连接  
    auto_ptr<Connection> connection(connectionFactory->createConnection());  
    connection->start();  
  
    // 创建会话  
    auto_ptr<Session> session(connection->createSession(Session::AUTO_ACKNOWLEDGE));  
  
    // 创建目标(队列或主题)  
    auto_ptr<Destination> destination(session->createQueue("TEST.QUEUE"));  
  
    // 创建消息生产者  
    auto_ptr<MessageProducer> producer(session->createProducer(destination.get()));  
  
    // 创建并发送消息  
    auto_ptr<TextMessage> message(session->createTextMessage("Hello ActiveMQ!"));  
    producer->send(message.get());  
  
    // (可选)创建消息消费者  
    // 注意:在这个例子中,我们不会等待或接收消息,但你可以根据需要设置  
    // auto_ptr<MessageConsumer> consumer(session->createConsumer(destination.get()));  
    // auto_ptr<Message> receivedMessage(consumer->receive(1000)); // 等待1秒  
  
    // 清理资源  
    if (connection.get() != nullptr) {  
        connection->close();  
    }  
  
    // 关闭ActiveMQ-CPP库  
    activemq::library::ActiveMQCPP::shutdownLibrary();  
  
    return 0;  
}
AMQ JavaScript
  • 用途:为JavaScript开发者提供与ActiveMQ交互的能力,特别是在浏览器或Node.js环境中。
  • 特点:可能基于WebSocket或HTTP协议与ActiveMQ通信,使得Web应用能够实时接收和发送消息。
  • 适用场景:在Web应用中实现实时通知、聊天功能或与后端系统集成的场景。

使用stompjs库与ActiveMQ进行通信的JavaScript客户端示例。这个示例假设ActiveMQ已经配置为支持STOMP协议,并且你正在一个支持WebSocket的浏览器环境中运行此代码(例如,ActiveMQ 5.x及更高版本通常支持通过WebSocket的STOMP)。

AMQ JavaScript的案例代码

首先,你需要在你的HTML文件中包含stompjs库。

<html lang="en">  
<head>  
    <meta charset="UTF-8">  
    <title>ActiveMQ STOMP Client</title>  
    <script src="https://cdn.jsdelivr.net/npm/stompjs/lib/stomp.min.js"></script>  
    <script>  
        function connect() {  
            var socket = new SockJS('/stomp'); // 假设ActiveMQ配置了WebSocket代理在/stomp路径  
            stompClient = Stomp.over(socket);  
            stompClient.connect({}, function (frame) {  
                console.log('Connected: ' + frame);  
                stompClient.subscribe('/queue/test', function (message) {  
                    showOutput(message.body);  
                });  
            });  
        }  
        function disconnect() {  
            if (stompClient !== null) {  
                stompClient.disconnect();  
            }  
            console.log("Disconnected");  
        }  
        function send() {  
            stompClient.send("/queue/test", {}, "Hello, ActiveMQ!");  
        }  
        function showOutput(message) {  
            var output = document.getElementById('output');  
            output.innerHTML = output.innerHTML + "<br>" + message;  
        }  
        // 可以在页面加载完成后自动连接(可选)  
        // window.onload = function () {  
        //     connect();  
        // };
    </script>  
</head>  
<body>  
    <h1>ActiveMQ STOMP Client Example</h1>  
    <button onclick="connect()">Connect</button>  
    <button onclick="send()">Send Message</button>  
    <button onclick="disconnect()">Disconnect</button>  
    <div id="output"></div>  
</body>  
</html>
AMQ JMS (Java)
  • 用途:Java消息服务(JMS)API的ActiveMQ实现,为Java应用提供消息传递服务。
  • 特点:支持JMS的所有标准功能,如发布/订阅模型、点对点模型、事务性会话等。
  • 适用场景:Java EE应用中的消息传递,或任何需要高可靠性、高可用性消息传递的Java应用。
AMQ JMS (Java)的案例代码

下面是一个使用Java JMS API与ActiveMQ代理通信的客户端示例。这个示例将展示如何连接到ActiveMQ代理,发送一条消息到队列,并可选地接收并打印队列中的消息。

Maven配置依赖

首先,确保你的项目中包含了ActiveMQ的JMS客户端库。如果你使用的是Maven,可以在pom.xml中添加以下依赖:

<dependencies>  
    <!-- ActiveMQ JMS Client -->  
    <dependency>  
        <groupId>org.apache.activemq</groupId>  
        <artifactId>activemq-jms-pool</artifactId>  
        <version>5.16.3</version> <!-- 请使用适合你项目的版本 -->  
    </dependency>  
    <!-- 如果你需要Spring集成,还可以添加Spring JMS和ActiveMQ Spring Integration的依赖 -->  
</dependencies>

注意,activemq-jms-pool是一个包含ActiveMQ JMS客户端和连接池的库。如果你不需要连接池,可以只包含activemq-jms-client。但是,activemq-jms-pool通常更方便,因为它提供了连接池的支持。

JMS客户端示例
import javax.jms.ConnectionFactory;  
import javax.jms.Destination;  
import javax.jms.JMSException;  
import javax.jms.Message;  
import javax.jms.MessageConsumer;  
import javax.jms.MessageProducer;  
import javax.jms.Session;  
import javax.jms.TextMessage;  
  
import org.apache.activemq.ActiveMQConnectionFactory;  
  
public class JmsClientExample {  
  
    public static void main(String[] args) {  
        // 创建连接工厂  
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");  
  
        // 创建连接  
        try (Connection connection = connectionFactory.createConnection()) {  
            connection.start();  
  
            // 创建会话  
            try (Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE)) {  
  
                // 创建目标(队列)  
                Destination destination = session.createQueue("TEST.QUEUE");  
  
                // 创建消息生产者  
                MessageProducer producer = session.createProducer(destination);  
  
                // 创建并发送消息  
                TextMessage message = session.createTextMessage("Hello, ActiveMQ JMS!");  
                producer.send(message);  
  
                // 创建消息消费者并接收消息  
                MessageConsumer consumer = session.createConsumer(destination);  
                // 阻塞接收一个消息)
                // Message receivedMessage = consumer.receive(1000); // 等待1秒  
                // if (receivedMessage != null) {  
                //     System.out.println("Received: " + ((TextMessage) receivedMessage).getText());  
                // }  
            }  
        } catch (JMSException e) {  
            e.printStackTrace();  
        }  
    }  
}

注意,若应用场景需求是等待并接收来自队列的消息,那么实施策略应当调整为将消息消费逻辑置于独立线程中执行,或者采用阻塞式接收方法以确保消息能够被有效捕获并处理。

JMS客户端

AMQ客户端库为不同编程语言的开发者提供了与ActiveMQ消息中间件交互的能力,使得他们可以在各自的开发环境中轻松实现消息传递和集成功能。选择合适的客户端库取决于项目的具体需求、使用的编程语言以及现有的技术栈。

在这里插入图片描述

ActiveMQ JMS with AMQP 1.0 Integration

ActiveMQ, 作为一款领先的开源消息中间件,不仅支持其原生的OpenWire协议,还广泛集成了AMQP(Advanced Message Queuing Protocol)1.0标准,为用户提供更为灵活和互操作性的消息传输机制。

通过AMQP 1.0集成,ActiveMQ JMS客户端能够无缝连接到遵循AMQP协议的任何消息代理,实现跨平台、跨语言的消息交换,极大地增强了系统的可扩展性和兼容性。

AMQ Core Protocol for JMS

AMQ Core Protocol,作为ActiveMQ的核心消息传输协议,为JMS(Java Message Service)应用提供了高效、可靠的消息传递能力。这一协议是ActiveMQ独有的,经过精心设计和优化,以确保消息的高吞吐量、低延迟以及卓越的容错性能。

JMS应用通过AMQ Core Protocol能够充分利用ActiveMQ提供的丰富特性,如消息持久化、事务支持、选择器(Selectors)等,构建出健壮、可扩展的企业级消息系统。

AMQ OpenWire JMS Implementation

OpenWire,作为ActiveMQ的默认消息传输协议,同样为JMS应用提供了坚实的支持。它是一种高效的二进制协议,专为ActiveMQ设计,以实现快速、可靠的消息传递。

OpenWire协议不仅支持JMS标准定义的所有功能,还通过一系列优化措施,如消息压缩、批处理发送等,进一步提升了消息传输的性能和效率。

适配器/开发库

在这里插入图片描述

AMQ Spring Boot Starter

下面是一个使用AMQ Spring Boot Starter来创建客户端的代码示例。由于Spring Boot Starter通常封装了与ActiveMQ的连接配置和JMS模板的自动配置,你可以非常简洁地实现消息的生产和消费。

Maven配置
<dependencies>  
    <!-- Spring Boot Starter for ActiveMQ -->  
    <dependency>  
        <groupId>org.springframework.boot</groupId>  
        <artifactId>spring-boot-starter-activemq</artifactId>  
        <!-- 请使用适合你项目的版本 -->  
    </dependency>  
  
    <!-- 如果需要Spring Boot的Web支持来创建RESTful服务,可以添加以下依赖 -->  
    <dependency>  
        <groupId>org.springframework.boot</groupId>  
        <artifactId>spring-boot-starter-web</artifactId>  
    </dependency>  
  
    <!-- 其他依赖... -->  
</dependencies>

接下来,创建一个简单的Spring Boot应用来发送和接收消息。这里,我们将使用JmsTemplate来发送消息,并通过@JmsListener注解来异步接收消息。

public class JmsSender {  
  
    @Autowired  
    private JmsTemplate jmsTemplate;  
  
    // 发送消息到指定的队列  
    public void sendMessage(String destinationName, String message) {  
        jmsTemplate.convertAndSend(destinationName, message);  
    }  
}

public class MessageReceiver {  
  
    // 监听名为"testQueue"的队列中的消息  
    @JmsListener(destination = "testQueue")  
    public void receiveMessage(String message) {  
        System.out.println("Received message: " + message);  
    }  
}

组件兼容性

下表详尽展示了AMQ组件的兼容性概览,涵盖了所支持的开发语言、运行平台以及通信协议。值得注意的是,只要组件间遵循相同的协议标准,它们便能够实现无缝的跨语言、跨平台互操作性。

AMQ组件兼容性

组件语言/平台协议备注
AMQ BrokerJVMAMQP 1.0, MQTT, 开放电线, 践踏, 核心协议
AMQ InterconnectLinuxAMQP 1.0
AMQ Online-AMQP 1.0
AMQ CC++Linux, 窗口AMQP 1.0
AMQ AMQ 节点.js, 浏览器AMQP 1.0
AMQ JMSJava, JVMAMQP 1.0
AMQ .NETC#AMQP 1.0.NET 框架
AMQ PythonPythonAMQP 1.0
AMQ RubyRubyAMQP 1.0
AMQ Spring Boot StarterJava, JVMAMQP 1.0
AMQ Core ProtocolJMSJava, JVM核心协议
AMQ OpenWireJMSJava, JVMOpenWire 协议
AMQ JMS PoolJava, JVM-

这一特性确保了高度的灵活性与集成能力,比如,AMQ的Python客户端能够轻松与基于JMS(Java Message Service)的AMQ组件建立通信,即便它们运行在不同的编程语言和平台上,也能保持流畅的消息交换。

通用部署模式

Red Hat AMQ 7 展现出了极高的灵活性,支持部署于多样化的拓扑结构中,以满足不同场景下的消息传递需求。以下是利用 AMQ 组件实现的一些常见且高效的部署模式,这些模式能够助力您构建稳定、可扩展的消息中间件解决方案。

中央代理模式

中央代理模式相对容易建立和维护。它也相对稳健。路由通常是本地的,因为无论添加了多少节点,代理和客户端都总是在彼此的一个网络跳中。这种模式也被称为轮毂和辐条,中间代理作为轮毂,客户作为辐条。 在这里插入图片描述 对于小规模或测试环境,您可以选择将 Red Hat AMQ 7 部署为单一实例。这种模式简化了配置与管理流程,是快速验证消息传递功能的理想选择。唯一的关键元素是中心代理节点。您的维护工作的重点是保持这个代理对其客户可用。

路由消息模式

在涉及消息路由至远程目标时,传统的代理机制往往采取先将消息暂存至本地队列,再行转发的策略。然而,在追求实时交互的应用场景中,如即时请求与响应系统,这种存储与转发的模式可能引入不必要的延迟与成本,因为代理的介入增加了消息处理的复杂性和资源消耗。 在这里插入图片描述

路由消息传递

AMQ 提供了一种更为高效灵活的解决方案——利用路由器直接替代传统代理的角色。AMQ路由器摒弃了代理的存储环节,转而采用一种无状态的、即时传输的方式处理消息。它充当了一个轻量级、高效的通信桥梁,直接在消息的发送方与接收方之间建立连接,实现了消息的无缝、低延迟传递。

主从复制模式

为了确保代理服务的持续可用性和稳定性,强烈建议实施高可用性(HA)策略,通过构建主从复制对来设立冗余备份组。具体而言,您应当考虑在至少两个独立的节点上部署成对的主从代理架构,以此形成一个高效的故障转移机制。

在这里插入图片描述

在正常操作条件下,每个节点上的一个主代理是活动的,它可以是物理服务器或虚拟机。如果一个节点发生故障,则另一个节点上的从属节点将接管。结果是驻留在同一健康节点上的两个活动代理。

主从架构网络集群

通过部署主从对,您可以扩展此类备份组的整个网络。这种类型的较大的部署对于在许多代理之间分发消息处理负载非常有用。下图中的代理网络由分布在8个节点上的8个主从组组成。

在这里插入图片描述

此部署模式独具匠心,它不仅为当前所有处于活跃工作状态的主代理即时配备了热备份解决方案,实现了无缝切换与即时恢复,而且从根本上大幅提升了系统的容错机制与韧性。

负载均衡器+路由模型

在一个负载均衡器后面部署两个路由器为单个数据中心的部署提供了高可用性、可恢复弹性和更高的可伸缩性。端点可以连接到一个由负载均衡器支持的已知URL。接下来,负载均衡器将传入的连接在路由器之间传播,从而分发连接和消息传递负载。如果其中一个路由器发生故障,连接到它的端点将重新连接到剩余的活动路由器。

在这里插入图片描述

为了实现更大的可伸缩性,您可以使用更多的路由器,例如3个或4个。每个路由器都可以直接连接到所有其他的路由器上。

基于数据隔离的路由模型

在此部署架构中,路由器网络扮演着至关重要的角色,它构建了一道坚固的防线,不仅为外界客户机与内部企业应用程序代理之间的交互提供了安全保障,还实现了两者之间的有效隔离,从而显著增强了系统整体的防护层级与数据隔离性。

在这里插入图片描述

部署中的连接的安全性与用于外部客户端的安全性是分开的。例如,部署可能使用私有证书颁发机构(CA)进行内部安全,向每个路由器颁发x.509证书和代理进行身份验证,尽管外部用户可能使用不同的公共CA。

注意,为了安全起见,从企业到DMZ总是建立在企业和内部隔离网络之间的路由器间连接。因此,不允许从外部连接到企业。然而,AMQP协议可以在建立连接后实现双向通信。

跨数据中心中的路由模型

可以在跨越多个位置的AMQ组件的部署中使用更复杂的拓扑结构。例如,可以在四个位置中分别部署一对负载平衡的路由器。可以在中心包括一个主干路由器,以提供所有位置之间的冗余连接。下图是一个跨越多个位置的部署示例

在这里插入图片描述