4.3 Connecting to ActiveMQ over the network
4.3 通过网络连接到ActiveMQ
The most common usage scenario is to run ActiveMQ as a standalone Java application.
This implies that clients (producer and consumer applications) will use some of the
network protocols to access the broker’s destinations. In this section, we’ll describe
available network protocols you can use to achieve client-to-broker communication.
在所有的应用场景中,最常见的是将ActiveMQ作为一个单独的Java应用程序来运行.这就是说,客户端
(消息生产者和消费者)需要使用一些网络协议一般连接到代理目的地.本节中,我们将介绍可用于实现
客户端到代理之间通信的网络协议.
We’ll start with default TCP connector, which is most widely used and provides optimal
performance. Next we’ll dig into the NIO connector, which also uses TCP network
protocol underneath, but additionally provides a bit better scalability than TCP connector
since it uses the NIO Java API. The UDP network protocol is often used on the
internet, so UDP connector is next on our list. UDP protocol introduces some performance
advantages, sacrificing reliability compared to the TCP protocol.
TCP连接器是默认的连接器,应用最广泛并且提供最好的性能,我们从讨论TCP连接开始.接下来深入了解NIO连接器,
NIO连接器在底层也是使用TCP协议,但相比TCP协议具有更好的可伸缩性,因为NIO协议使用了NIO的Java API.
UDP协议常用于因特网,所以之后我们接着讨论UDP连接器.UDP协议相比TCP协议,因为牺牲了一些可靠性而获得了一些
性能提升.
The same applies to appropriate ActiveMQ connectors, so a UDP connector can offer some performance
advantages over the TCP connector, but it’s still not often used because of
the unreliability it introduces (as explained in more detail later). The SSL connector
can be used to establish a secure connection to the broker, and finally we’ll show you
how to communicate with the broker using HTTP. Of course, in every section we’ll
discuss the pros and cons of every protocol. Therefore, you may want to consider
reading just the subsections that interest you at the moment and then move along to
other chapters. Table 4.1 contains a summarization of the connectors with a brief
description.
这些协议的相关特性同样适用于相应的ActiveMQ连接器,因此UDP连接器相比TCP连机器可以提供一些
性能提升,但是UDP协议仍然不常用,因为牺牲了一些可靠性(后面将介绍一些相关细节).SSL连接器可以
建立到代理的安全连接,最后我们将介绍如何使用HTTP协议与代理通信.当然,在每个章节中我们都会
讨论使用不同协议的各种连接器的优缺点.因此,你可以只阅读你感兴趣的章节,然后直接跳到其他章.
表格4.1是各种连接器特性的简要概述.
Now, let’s start with the default TCP protocol.
现在让我们从默认的TCP协议开始
Table 4.1 Summary of network protocols used for client-broker communication
Protocol Description
协议 描述
TCP Default network protocol for most use cases.
TCP协议 大多数应用场景中使用的默认网络协议
NIO Consider NIO protocol if you need to provide better scalability for connections from producers
and consumers to the broker.
NIO协议 当消息生产者和消费者到代理的连接,需要有更好的可扩展性时可以使用NIO协议.
UDP Consider UDP protocol when you need to deal with the firewall between clients and the
broker.
UDP协议 当客户端和代理之间的连接需要穿越防火墙时,可以使用UDP协议.
SSL Consider SSL when you want to secure communication between clients and the broker.
SSL协议 当客户端和代理之间需要安全连接时,可以使用SSL协议.
HTTP(S) Consider HTTP(S) when you need to deal with the firewall between clients and the broker.
HTTP(S) 当客户端和代理之间的连接需要穿越防火墙时,可以也使用HTTP(S)协议.
VM Although not a network protocol per se, consider VM protocol when your broker and clients
communicate with a broker that is embedded in the same Java Virtual Machine (JVM).
VM协议 虽然VM本身不是一个网络协议, 但是当客户端和代理在同一个Java虚拟机(VM)中运行时,他们之间需要通信
时,可以使用VM协议.
4.3.1 Transmission Control Protocol (TCP)
4.3.1 传输控制协议(TCP)
Transmission Control Protocol (TCP) is today probably as important to humans as electricity.
As one of the fundamental internet protocols, we use it for almost all of our
online communication. It’s used as an underlying network protocol for a wide range
of internet services such as email and the web, for example.
如今,传输控制协议对于人类的重要性堪比电能.作为因特网的一个基础协议,传输控制协议几乎已被用于所有的
在线通讯中.传输控制协议作为底层协议用于在整个因特网服务中,比如email服务和网页服务.
Hopefully you are already familiar with the basics of TCP, but let’s start our discussion
of TCP by quoting from the specification, RFC 793 (http://mng.bz/Bns2):
The Transmission Control Protocol (TCP) is intended for use as a highly reliable host-to-host
protocol between hosts in packet-switched computer communication networks, and in
interconnected systems of such networks.
很幸运,TCP协议的基础知识,你已经很了解了,所以让我从讨论TCP协议的一段规范(RFC 793 (http://mng.bz/Bns2))开始:
TCP协议是一种主机间的高可用的通信协议,该协议使用数据包交换数据实现主机网络间通信,同时该协议也适用于
于和此类主机网络类似的网络系统通信.
Since the broker and client applications are network hosts trying to communicate in a
reliable manner, it’s easy to see why TCP is an ideal network protocol for a JMS implementation.
So it shouldn’t come as a surprise that the TCP transport connector is the
most frequently used ActiveMQ connector.
考虑到代理和客户端都是网络主机,它们尝试以一种可靠的方式实现彼此间通信.
因而,TCP协议自然而然的成为JMS实现中一种理想的通信协议.
这样,TCP传输连接器作为ActiveMQ连接器中最常用的连接器也就不足为怪了.
Before exchanging messages over the network, we need to serialize them to a suitable
form. Messages must be serialized in and out of a byte sequence to be sent over
the wire using what’s known as a wire protocol. The default wire protocol used in
ActiveMQ is called OpenWire. The protocol specification can be found on the
ActiveMQ website (http://mng.bz/u2eT). The OpenWire protocol isn’t specific to
the TCP network transport and can be used with other network protocols. Its main
purpose is to be efficient and allow fast exchange of messages over the network.
Furthermore,a standardized and open protocol such as OpenWire allows native
ActiveMQ clients to be developed for various programming environments. This topic
and a description of other wire level protocols available for ActiveMQ are covered in
chapter 9.
通过网络交换消息之前,我们需要将消息序列化成一种合适的格式.ActiveMQ的消息必须被序列化成字节
序列,以便通过线协议发送.ActiveMQ中默认的线协议是OpenWire.可以从(http://mng.bz/u2eT)查看
该线协议规范.OpenWire协议并非用于TCP网络传输,同时也可以用于其他的网络协议中.使用OpenWire协议
的主要目的是提高传输效率以及允许消息在网络中高速交换.并且,类似于OpenWire的这种标准的开放协议
允许在多种编程环境中使用原生的ActiveMQ客户端.第九章中将详细讨论该主题以及ActiveMQ可用的其他"线协议".
As we’ve seen in previous sections, a default broker configuration starts the TCP
transport listening for client connections on port 61616. The TCP connector URI uses
the following syntax:
tcp://hostname:port?key=value&key=value
Please note that the bold portion of the URI denotes the required part. Any key/value
pairs to the right of the question mark are optional and separated by an ampersand.
We won’t discuss all transport options for appropriate protocols in this section or
the sections that follow. This kind of material is best presented via the online reference
pages. An up-to-date reference for the TCP connector can be found on the
ActiveMQ website (http://mng.bz/ngU2).
在前面章节中,我们已经看到,使用默认的配置,代理将启动TCP传输连接在61616端口监听客户端连接.
TCP连接器的URI语法如下:
tcp://hostname:port?key=value&key=value
请注意tcp://hostname:port部分是必须的,而问号后面的键值对都是可选的,键值对之间通过&符号分割.
在本节以后后面章节中,我们不打算讨论每种连接协议的所有选项,这部分的相关材料在线文档中有
详细说明,ActiveMQ网站中http://mng.bz/ngU2页面是最新的TCP连接器的在线文档.
The following configuration snippet provides an example of using the TCP connector
in the ActiveMQ configuration file:
下面的代码片段是ActiveMQ配置文件中使用TCP配置连接器的一个示例:
<transportConnectors>
<transportConnector name="tcp" uri="tcp://localhost:61616?trace=true"/>
</transportConnectors>
Note that the trace option has been added to the transport connector URI. This
option instructs the broker to log all commands sent over this connector and can be
helpful for debugging purposes. We have it here as an example of a transport tuning
feature using a transport option. For more information on using the trace option for
debugging, see chapter 14.
注意,上面的URI配置中使用了trace参数.这个参数配置为true,说明代理会为每个发送到代理的命令记录日志,
这样对调试很有用.使用trace参数作为一个例子,说明了如何通过URI参数调整传输连接器的行为.
更多的使用trace参数调试的内容请看第十四章内容.
IMPORTANT After changing the configuration file, ActiveMQ must be
restarted for the changes to take effect.
The previous section outlined the use of this protocol in the client applications to
connect to the broker. Just for reference, the following example shows how to run the
consumer using the TCP transport connector:
重要: 在修改了配置文件后,必须重启ActiveMQ以便修改能够生效.
前面章节中说明的客户端如何使用TCP协议连接到代理.下面的命令(仅供参考)说明了如何使用TCP传输连接器
运行consumer类.
$ mvn exec:java -Dexec.mainClass=org.apache.activemq.book.ch4.Consumer -Dexec.args="tcp://localhost:61616 CSCO ORCL"
...
ORCL 65.71 65.78 up
ORCL 66.07 66.14 up
ORCL 65.93 65.99 down
CSCO 23.30 23.33 up
...
Some of the benefits of the TCP transport connector include the following:
Efficiency—Since this connector uses the OpenWire protocol to convert messages
to a stream of bytes (and back), it’s very efficient in terms of network
usage and performance.
Availability—TCP is one of the most widespread network protocols and has been
supported in Java from the early days, so it’s almost certainly supported on your
platform of choice.
Reliability—The TCP protocol ensures that messages won’t be lost on the network
(due to glitches, for example).
下面是TCP传输连接器的一些优点:
高效性 - 因为TCP连接器使用OpenWire协议将消息转换成字节流(同时也使用OpenWire协议将字节流转换为消息),
所以,网络应用性能十分高效.
高可用性 - TCP协议是应用最为广泛的网络协议,并且Java刚出现时就支持该协议,所以你选择的平台几乎一定支持
该协议.
高可靠性 - TCP协议保证网络中传输的消息不会丢失(比如,使用TCP协议,不会因干扰而造成消息丢失).
Now let’s explore some alternatives to the TCP transport connector.
下面将探讨TCP连接器之外的其他连接器.
4.3.2 New I/O API protocol (NIO)
4.3.2 基于新I/O API的协议
The New I/O (NIO) API was introduced in Java SE 1.4 to supplement the existing (standard)
I/O API used in Java until then. Despite the prefix new in its name, NIO was never
meant to be a replacement for the traditional Java I/O API. Its purpose was to provide
an alternative approach to network programming and access to some low-level I/O
operations of modern operating systems. The most prominent features of NIO are
selectors and nonblocking I/O programming, allowing developers to use the same
resources to handle more network clients and generally heavier loads on their servers.
From a client perspective, the NIO transport connector is practically the same as the
standard TCP connector, in terms of its use of TCP as the underlying network protocol
and OpenWire as the message serialization protocol. The only difference is under the
covers with the implementation of the transport, where the NIO transport connector
is implemented using the NIO API. This makes the NIO transport connector more suitable
in situations where
Java SE 1.4中引入了新I/O API(以下简称NIO),作为之前Java已有的I/O API的补充.尽管被冠以"新"这个前缀,NIO并不是
Java传统I/O API 的替代品.NIO的出现旨在为Java网络编程和现代操作系统底层操作提供一种新方法.
NIO最突出的特性莫过于选择器和非阻塞的I/O编程,
因此允许开发者使用相同的资源服务于更多的网络客户端,并使服务器可以承受更大的负载.
You have a large number of clients you want to connect to the broker—Generally, the
number of clients that can connect to the broker is limited by the number of
threads supported by the operating system. Since the NIO connector
implementation starts fewer threads per client than the TCP connector, you
should consider using NIO in case TCP doesn’t meet your needs.
You have a heavy network traffic to the broker—Again, the NIO connector generally
offers better performance than the TCP connector (in terms of using less
resources on the broker side), so you can consider using it when you find that
the TCP connector doesn’t meet your needs.
从客户端的角度来看,使用NIO传输连接器和使用标准的TCP连接器一样,因为NIO传输连接器底层也是使用TCP协议,
同样也是使用OpenWire作为消息序列化协议.NIO传输连接器和TCP连接器的唯一区别是连接器的实现方式,
NIO连接器使用NIO API实现,因此NIO传输连接器适用于下面两种情况:
(1)连接到代理的客户端的数量巨大(当然,能连接到代理的客户端的数量还受到操作系统的支持的最大线程数限制)
NIO连接器为每个客户端连接启动的线程较少,因而你可以考虑使用NIO连接器以防TCP不能满足需求.
(2)连接到代理的网络传输十分拥堵.这种情况下,NIO连接器相对于TCP连接器也可以提供更好的性能(因为在代理端,
NIO连接器使用更少的资源).
At this point it’s important to note that performance tuning of ActiveMQ isn’t just
related to choosing the right connector. Many other aspects of ActiveMQ can be
tuned, including the use of a network of brokers topology (see chapter 10) and setting
various options for brokers, producers, and consumers (see chapter 13).
这里,有必要说明的是,ActiveMQ性能调优绝不仅限于选择正确的连接器. ActiveMQ还有很多其他
性能相关的参数可以调整,包括代理所在网络的拓扑结构(参见第10章)以及代理,消息生产者和
消息消费者的各种参数(参见第13章).
The URI syntax for the NIO connector is practically the same as that of the TCP
connector URI syntax. The only difference is the use of the nio scheme instead of tcp,
as shown:
nio://hostname:port?key=value
Now take a look at the configuration snippet. The NIO part is in bold.
Listing 4.3 Configuring the NIO transport connector
<transportConnectors>
<transportConnector name="tcp" uri="tcp://localhost:61616?trace=true" />
<transportConnector name="nio" uri="nio:localhost:61618?trace=true" />
</transportConnectors>
NIO连接器的URI语法和TCP连接器的URI语法基本上是相同的,唯一的区别是NIO连接器
使用nio主题替代tcp主题,例如:
nio://hostname:port?key=value
情况下面的配置代码片段:
Listing 4.3 Configuring the NIO transport connector
<transportConnectors>
<transportConnector name="tcp" uri="tcp://localhost:61616?trace=true" />
<transportConnector name="nio" uri="nio:localhost:61618?trace=true" />
</transportConnectors>
Now run the stock portfolio example, but this time you’ll connect the publisher and
consumer using different transport connectors. As figure 4.3 shows, the publisher will
send messages using the NIO transport connector, whereas the consumer will receive
those messages using the TCP transport connector.
现在,可以再次运行stock portfolio这个例子,但是这次我们将使用不同的传输连机器,以便连接publisher
和consumer.如图4.3所示,publisher将使用NIO传输连接器发送消息,而consumer接受消息时,使用TCP传输
连接器.
To achieve this, the stock portfolio publisher should be run using the following
command:
$ mvn exec:java -Dexec.mainClass=org.apache.activemq.book.ch4.Publisher -Dexec.args="nio://localhost:61618 CSCO ORCL"
...
Sending: {price=65.713356601409, stock=JAVA, offer=65.779069958011, up=true}
on destination: topic://STOCKS.JAVA
Sending: {price=66.071605671946, stock=JAVA, offer=66.137677277617, up=true}
on destination: topic://STOCKS.JAVA
Sending: {price=65.929035001620, stock=JAVA, offer=65.994964036622, up=false}
on destination: topic://STOCKS.JAVA
...
Note that the nio scheme is used in the connection URI to specify the NIO connector.
The consumer should use the TCP connector as shown below:
$ mvn exec:java -Dexec.mainClass=org.apache.activemq.book.ch4.Consumer -Dexec.args="tcp://localhost:61616 CSCO ORCL"
...
ORCL 65.71 65.78 up
ORCL 66.07 66.14 up
ORCL 65.93 65.99 down
CSCO 23.30 23.33 up
...
After both the consumer and producer are started, you’ll notice that messages are
exchanged between applications as expected. The fact that they are using different
connectors to communicate with the broker plays no role in this exchange.
为此,需要使用下面的命令来运行stock portfolio的publisher:
$ mvn exec:java -Dexec.mainClass=org.apache.activemq.book.ch4.Publisher -Dexec.args="nio://localhost:61618 CSCO ORCL"
...
Sending: {price=65.713356601409, stock=JAVA, offer=65.779069958011, up=true} on destination: topic://STOCKS.JAVA
Sending: {price=66.071605671946, stock=JAVA, offer=66.137677277617, up=true} on destination: topic://STOCKS.JAVA
Sending: {price=65.929035001620, stock=JAVA, offer=65.994964036622, up=false} on destination: topic://STOCKS.JAVA
...
注意,传输连接器的URI中使用了nio主题,consumer应该使用TCP连接器,命令如下:
$ mvn exec:java -Dexec.mainClass=org.apache.activemq.book.ch4.Consumer -Dexec.args="tcp://localhost:61616 CSCO ORCL"
...
ORCL 65.71 65.78 up
ORCL 66.07 66.14 up
ORCL 65.93 65.99 down
CSCO 23.30 23.33 up
...
当consumer和producer都启动以后,应用程序之间会按照预期的那样交换消息.它们使用不同传输连接器
与代理进行通讯,却不会影响消息交换.
4.3.3 User Datagram Protocol (UDP)
4.3.3 用户数据报协议
User Datagram Protocol (UDP) along with TCP make up the core of internet protocols.
The purpose of these two protocols is identical—to send and receive data packets
(datagrams) over the network. But there are two main differences between them:
TCP is a stream-oriented protocol, which means that the order of data packets is
guaranteed. There’s no chance for data packets to be duplicated or arrive out
of order. UDP, on the other hand, doesn’t guarantee packet ordering, so a
receiver can expect data packets to be duplicated or arrive out of order.
TCP also guarantees reliability of packet delivery, meaning that packets won’t be lost
during the transport. This is ensured by maintaining an active connection
between the sender and receiver. On the contrary, UDP is a connectionless protocol,
so it can’t make such guarantees.
用户数据报协议和TCP协议都是因特网的核心协议.二者都用于网络中发送和接收消息,但它们之间
也有非常多的区别:
TCP协议是面向流的协议,这个是指TCP协议保证数据包的顺序不会改变.因此,数据包不会重复,
并且会按顺序到达目标.而UDP协议不保证数据包的顺序,因此接受方可能会受到重复的或次序
错乱的数据包.
TCP协议还保证消息分发的可靠性,这就意味着消息在传输过程中不会丢失.这样可以保持消息
发送方和接收方直接的活动连接.与之相反,UDP协议是无连接协议,不能保证消息发送方和接收
方之间的连接.
As a result of these differences, TCP is used in applications that require reliability
(such as email), whereas UDP usually finds it place in applications that require fast
data transfers and can handle occasional packet loss (such as VoIP or online gaming).
You can use the UDP protocol to connect to ActiveMQ by using the UDP transport
connector. The URI syntax of this connector is pretty much the same as for the TCP
connector. The only difference is the use of the udp scheme, as shown in the following
snippet:
udp://hostname:port?key=value
The complete reference of the UDP protocol can be found at the ActiveMQ website
(http://mng.bz/1i4g).
鉴于二者之间的差异,TCP协议适用于对可靠性有要求的应用(比如email),而UDP协议适用于对消息快速传输
有要求的应用,UDP协议还可以处理偶然性的消息丢失(比如VoIP或者在线游戏).使用UDP传输连接器就可以采用
UDP协议连接到ActiveMQ.UDP连接器的URI语法基本上和TCP连接器的URI的一样,两者之间唯一的区别是UPD连接器的
URI需要使用upd主题,配置代码片段如下:
udp://hostname:port?key=value
关于UPD协议完整的规范请访问ActiveMQ的站点(http://mng.bz/1i4g).
Comparing the TCP and UDP transports.
比较TCP连接器和 UDP连接器
When considering the TCP and the UDP transports, questions arise that compare
these two protocols. When should you use the UDP transport instead of the TCP
transport? There are basically two such situations where the UDP transport offers an
advantage:
The broker is located behind a firewall that you don’t control and you can
access it only over UDP ports.
You’re using time-sensitive messages and you want to eliminate network transport
delay as much as possible.
But there are also a couple of pitfalls regarding the UDP connector:
Since UDP is unreliable, you can end up losing some of the messages, so your
application should know how to deal with this situation.
Network packets transmitted between clients and brokers aren’t just messages,
but can also contain so-called control commands. If some of these
control commands are lost due to UDP unreliability, the JMS connection
could be endangered.
当比较TCP连接器和 UDP连接器时,问题转换为比较TCP和UDP这两个协议.什么使用应该使用UDP连接器
代替TCP连接器?大体上说,在下面两种情况下,应该使用UDP连接器:
(1)你要连接的代理在一个防火墙内,而你没有这个防火墙的控制器,你只能通过UDP端口连接到代理.
(2)你使用的时效性敏感的消息,你需要尽可能的减少消息在网络传输中的延迟.
考虑到UDP协议是不可靠协议,使用UPD连接器也有一些缺陷:
(1)因为UPD协议是不可靠的,所以有些消息可能会丢失,因而你的应用程序需要能够处理这种消息丢失问题.
(2)客户端和代理之间传输的网络数据包不仅仅是消息,有些数据包还包含了所谓的控制命令.如果这些控制命令
因为UDP协议的不可靠性而丢失,JMS连接可能会遭到破坏.
Now let’s configure ActiveMQ to use both TCP and UDP transports on different ports.
现在,让我们配置ActiveMQ,以便在不同的端口使用TCP和UDP传输连接器.
Here’s an example of such a configuration; the UDP part is in bold:
下面是配置UDP连接器的代码片段:
<transportConnectors>
<transportConnector name="tcp" uri="tcp://localhost:61616?trace=true"/>
<transportConnector name="udp" uri="udp://localhost:61618?trace=true" />
</transportConnectors>
Note that there are two separate transport connectors on different ports.
注意,上面的代码片段在不同的端口各配置了一个连接器.
To run a stock portfolio publisher using the UDP protocol, use the following
command:
$ mvn exec:java -Dexec.mainClass=org.apache.activemq.book.ch4.Publisher -Dexec.args="udp://localhost:61618 CSCO ORCL"
...
Sending: {price=65.713356601409, stock=JAVA, offer=65.779069958011, up=true} on destination: topic://STOCKS.JAVA
Sending: {price=66.071605671946, stock=JAVA, offer=66.137677277617, up=true} on destination: topic://STOCKS.JAVA
Sending: {price=65.929035001620, stock=JAVA, offer=65.994964036622, up=false} on destination: topic://STOCKS.JAVA
...
The consumer can be run using the TCP protocol with the following command:
$ mvn exec:java -Dexec.mainClass=org.apache.activemq.book.ch4.Consumer -Dexec.args="tcp://localhost:61616 CSCO ORCL"
...
ORCL 65.71 65.78 up
ORCL 66.07 66.14 up
ORCL 65.93 65.99 down
CSCO 23.30 23.33 up
...
As expected, the behavior of the overall system is the same as it was in the original
example when only the TCP transport connector was used. This is due to the fact
that the reliability of a local network is typically very good and there is generally no
packet loss.
使用UDP协议运行stock portfolio的publisher,可使用下面的命令:
$ mvn exec:java -Dexec.mainClass=org.apache.activemq.book.ch4.Publisher -Dexec.args="udp://localhost:61618 CSCO ORCL"
...
Sending: {price=65.713356601409, stock=JAVA, offer=65.779069958011, up=true} on destination: topic://STOCKS.JAVA
Sending: {price=66.071605671946, stock=JAVA, offer=66.137677277617, up=true} on destination: topic://STOCKS.JAVA
Sending: {price=65.929035001620, stock=JAVA, offer=65.994964036622, up=false} on destination: topic://STOCKS.JAVA
...
使用TCP协议运行consumer,可使用下面的命令:
$ mvn exec:java -Dexec.mainClass=org.apache.activemq.book.ch4.Consumer -Dexec.args="tcp://localhost:61616 CSCO ORCL"
...
ORCL 65.71 65.78 up
ORCL 66.07 66.14 up
ORCL 65.93 65.99 down
CSCO 23.30 23.33 up
...
正如预期的那样,实例中整个系统的运行情况跟原来使用TCP传输连接器时一样.这是因为本地网络的可靠行很好,因而使用UDP协议基本上也不会
有数据丢失.
4.3.4 Secure Sockets Layer Protocol (SSL)
4.3.4 安全套接层(SSL)
Imagine yourself in a situation where you need to expose the broker over an unsecured
network and you need data privacy. The same requirement emerged when the
web outgrew its academic roots and was considered for corporate usage. Sending
plain data over TCP became unacceptable, and a solution had to be found. The solution
for secure data transfers was the Secure Sockets Layer (SSL), a protocol designed to
transmit encrypted data over the TCP network protocol. It uses a pair of keys (one private
and one public) to ensure a secure communication channel. ActiveMQ provides
the SSL transport connector, which adds an SSL layer over the TCP communication channel,
providing encrypted communication between brokers and clients. As always with
SSL, keys and certificates are involved in configuring it, so this section is longer, as
we’ll dig into this configuration in detail.
想象一个场景:你的代理(broker)暴露在一个不安全的网络中,但是你的数据传输却需要保密.
类似的需求有:web应用已超过期学术定义的范围,需要考虑企业级的应用.通过TCP协议发送裸数据
不可接受,这个问题需要一个解决方案:使用安全套接字(SSL)协议进行安全数据传输,
设计该协议正式为了进行基于TCP网络的加密数据数据传输.该协议使用一对密钥(一个公钥和一个私钥)
来保证安全的通信通道.ActiveMQ提供SSL传输连接器,该连接器在TCP通信信道之上附加SSL层,为客户端
和代理之间的通信提供加密支持.涉及到SSL的配置,就需要配置密钥和证书,所以这个章节会有点长,因为
我们将深入讨论各种配置细节.
The URI syntax for this protocol is
ssl://hostname:port?key=value
Since the SSL transport is based on the TCP transport, configuration options are the
same. More information for using the SSL connector is available on the ActiveMQ website
(http://mng.bz/s8I2).
ActiveMQ uses the Java Secure Socket Extension (JSSE) to implement its SSL functionality.
Since its detailed description is out of the scope of this book, please refer to the
online information for JSSE (http://mng.bz/7TYe) before proceeding to the rest of
this section.
使用SSL协议时,连接器的URI的语法为:ssl://hostname:port?key=value.因为SSL传输是基于TCP传输的,所以
两者URI配置中的参数是相同的.有关SSL连接器的更多信息科参阅ActiveMQ网站(http://mng.bz/s8I2).
ActiveMQ使用Java安全套接字扩展(Java Secure Socket Extension (JSSE))来实现SSL的功能.考虑到JSSE的
实现细节已经超过本书的范围,JSSE相关信息请参阅以下在线信息(http://mng.bz/7TYe),然后再继续本节
其余的内容.
To configure the ActiveMQ broker to use the SSL transport, the first thing to do is
configure the ActiveMQ SSL transport.
Change the <transportConnectors> element in the ${ACTIVEMQ_HOME}/conf/activemq.xml file as shown:
<transportConnectors>
<transportConnector name="ssl" uri="ssl://localhost:61617?trace=true" />
</transportConnectors>
But the SSL transport needs a few more items in order to work properly. Such
required items include SSL certificates for successful SSL communication. Basically,
JSSE defines two types of files for storing keys and certificates. The first are so-called
keystores, which hold your own private certificates with their corresponding private
keys. Trusted certificates of other entities (applications) are stored in truststores. To
actually get the SSL transport working properly, the additional required items are discussed
in detail in the next two sections.
For more information on configuring SSL, see chapter 6.
要使用SSL传输配置ActiveMQ代理,第一步要做的工作是配置ActiveMQ的SSL传输:将${ACTIVEMQ_HOME}/conf/activemq.xml文件中的
<transportConnectors>元素修改成下面的样子:
<transportConnectors>
<transportConnector name="ssl" uri="ssl://localhost:61617?trace=true" />
</transportConnectors>
除此之外,SSL传输连接器还需要做一些额外配置以便连接器能正常工作.这些额外的排至包括:SSL通信所需的证书.
通常,JSSE定义了两种格式的文件用来存储密钥和证书.第一种是所谓的密钥仓库(keystore),用来保存私有证书及其相应的私钥.
其他实体(应用程序)的可信的证书存储在可信的密钥仓库中(truststore).下面两个小节详细讨论了SSL传输连接器
正常工作所需的其他额外配置.
更多关于配置SSL的信息,请看第6章内容.
Now that you understand all the necessary elements needed for successful SSL
communication, it’s time to connect to the secured transport. First, you’ll connect to
the broker that’s secured with its default certificate. Next, you’ll walk through the procedure
for creating your own certificates and running a broker and clients with them.
既然你已经了解SSL通信所需的所有相关配置,现在是时候连接到安全的传输连接器了.
首先,你会连接到一个使用默认证书以保证连接安全的代理;接下来,你会创建自己的证书,
然后在代理和客户端中使用这个证书.
USING SSL
使用SSL
First a small experiment to see what happens when you try to connect to a broker
using SSL and without providing any other SSL-related parameters. Connecting the
stock portfolio consumer by changing the transport to use SSL without creating the
proper stores will cause errors. Here’s an example of simply changing the transport:
$ mvn exec:java -Dexec.mainClass=org.apache.activemq.book.ch4.Consumer -Dexec.args="ssl://localhost:61617 CSCO ORCL"
首先,做一个小实验:如果使用SSL连接到一个代理之前没有提供SSL相关的参数会发生什么.修改传输连接器的URI,使用SSL
连接stock portfolio实例中的consumer,如果在连接之前没有配置相应的密钥仓库(store),这种连接会报错.
下面是一个例子,这里仅仅修改了传输连接器的URI(URI配置成ssl)
Without creating and denoting the proper keystore and truststore, you can expect to
see the following exceptions:
没有创建和配置相关的keystore和truststore,你将看到下面的异常信息:
WARNING: Async exception with no exception listener:
javax.net.ssl.SSLHandshakeException:
sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target
javax.net.ssl.SSLHandshakeException:
sun.security.validator.ValidatorException:
PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target
Also, in the broker’s log you’ll see the following error:
ERROR TransportConnector
- Could not accept connection : Received fatal alert: certificate_unknown
These errors mean that the SSL connection couldn’t be established. This is a generic
error all clients will receive when trying to connect to the untrusted broker (without
the proper keystore and truststore).
这些错误表示不能创建SSL连接.这是客户端尝试使用SSL连接到不可信代理(没有配置相关的keystore和truststore)
时发生的常规错误.
When using JSSE, you must provide some SSL parameters using the appropriate system
properties. In order to successfully connect to the broker via SSL, we must provide
the keystore, the keystore password, and the truststore to be used. This is accomplished
using the following system properties:
javax.net.ssl.keyStore—Defines which keystore the client should use
javax.net.ssl.keyStorePassword—Defines an appropriate password for the keystore
javax.net.ssl.trustStore—Defines an appropriate truststore the client should use
使用JSSE之前,一些使用配套的系的属性的SSL参数必须要提供.为了成功的通过SSL连接到代理,
我们必须提供keystore,keystore秒吗以及truststore,可以通过下面的系统属性来提供这些必须的参数:
javax.net.ssl.keyStore—定义客户端使用的key仓库.
javax.net.ssl.keyStorePassword—定义客户端的key仓库密码
javax.net.ssl.trustStore—定义客户端使用的受信的key仓库
Now take a look at the following example of starting the stock portfolio publisher
using the default client certificate stores distributed with ActiveMQ:
现在看看下面这个命令,使用ActiveMQ默认的客户端证书来运行stock portfolio实例中的publisher.
$ mvn -Djavax.net.ssl.keyStore=${ACTIVEMQ_HOME}/conf/client.ks -Djavax.net.ssl.keyStorePassword=password -Djavax.net.ssl.trustStore=${ACTIVEMQ_HOME}/conf/client.ts exec:java -Dexec.mainClass=org.apache.activemq.book.ch4.Publisher -Dexec.args="ssl://localhost:61617 CSCO ORCL"
...
Sending: {price=65.713356601409, stock=JAVA, offer=65.779069958011, up=true} on destination: topic://STOCKS.JAVA
Sending: {price=66.071605671946, stock=JAVA, offer=66.137677277617, up=true} on destination: topic://STOCKS.JAVA
Sending: {price=65.929035001620, stock=JAVA, offer=65.994964036622, up=false} on destination: topic://STOCKS.JAVA
...
Note the use of the JSSE system properties in bold. These properties provide the necessary
keystore, keystore password, and truststore. After providing these necessary SSL related
parameters, the publisher will connect successfully to the broker as intended
without error. Of course, if the client isn’t located on the same computer as your broker,
you’ll need to copy these files and adapt the paths appropriately.
JSSE用到的系统参数使用粗体字标示.这些系统属性提供了JSSE必须的keystore,keystore密码和
truststore.提供了这些SSL必须的属性后,publisher可以成功的连接到代理.当然,就客户端和代理不在
同一台机器上,你需要从代理所在的机器上拷贝这些文件然后放到客户端所在机器的相应的目录中.
Similarly, the consumer can be run using the following command:
类似的,可以使用下面的命令运行consumer:
$ mvn \
-Djavax.net.ssl.keyStore=${ACTIVEMQ_HOME}/conf/client.ks \
-Djavax.net.ssl.keyStorePassword=password \
-Djavax.net.ssl.trustStore=${ACTIVEMQ_HOME}/conf/client.ts \
exec:java -Dexec.mainClass=org.apache.activemq.book.ch4.Consumer \
-Dexec.args="ssl://localhost:61617 CSCO ORCL"
...
ORCL 65.71 65.78 up
ORCL 66.07 66.14 up
ORCL 65.93 65.99 down
CSCO 23.30 23.33 up
...
Again, note the use of the JSSE system properties in bold. Now both clients can communicate
with the broker using the encrypted network channels provided by the SSL
transport connector.
同样,JSSE所需的系统属性用粗体字显示.现在,两个客户端都可以通过SSL提供的加密信道和代理通信了.
Working with the default certificate, keystore, and truststore is okay for development
purposes, but for a production system, it’s highly recommended that you create
and use your own certificates. You can even disable ciphers that you may not be using.
In most cases, you’ll need to purchase an appropriate SSL certificate from the trusted
certificate authority.
在开发时使用默认的证书keystore和truststore是可以的,但是对于生产环境来说,强烈建议使用自己的证书.
你甚至可以禁用可能用不到的密码.大多数情况下,你需要从受信的证书机构购买SSL证书.
CREATING YOUR OWN SSL RESOURCES
创建你自己的SSL资源
For development purposes, you’ll want to create your own self-signed certificates. The
rest of this section will lead you through the process of creating and sharing selfsigned
certificates. For that purpose the keytool will be used—the command-line tool
for managing keystores that’s distributed with Java.
开发时,你需要创建自签名的证书.本小节的其他部分将指引你创建和分发自签名的证书.
为此,需要使用随JDK一同发布的命令行工具keytool来管理keystore.
First, you must create a keystore and a certificate for the broker. Here’s an example
of this using the keytool that comes with the JDK:
首先,你需要为代理创建一个keystore和certificate.
下面是使用随JDK一同发布的命令行工具keytool创建keystore和证书的命令:
$ keytool -genkey -alias broker -keyalg RSA -keystore mybroker.ks
Enter keystore password: test123
What is your first and last name?
[Unknown]: Dejan Bosanac
What is the name of your organizational unit?
[Unknown]: Chapter 4
What is the name of your organization?
[Unknown]: ActiveMQ in Action
What is the name of your City or Locality?
[Unknown]: Belgrade
What is the name of your State or Province?
[Unknown]:
What is the two-letter country code for this unit?
[Unknown]: RS
Is CN=Dejan Bosanac, OU=Chapter 3, O=ActiveMQ in Action,
L=Belgrade, ST=Unknown, C=RS correct?
[no]: yes
Enter key password for <broker>
(RETURN if same as keystore password):
The keytool application prompts you to enter certificate data and create a keystore
with the certificate in it. In this case we’ve created a keystore file named mybroker.ks
with the password test123.
keytool工具提示你输入证书相关的日期然后创建包含证书的keystore.这样,我们完成了创建一个文件名为
mybroker.ks,密码为test123的keystore.
The next step is to export this certificate from the keystore, so it can be shared with
the broker’s clients. This is done using the following command:
接下来,需要从keystore中导出证书,以便该证书可以与代理的客户端共享.可以使用下面的命令导出证书:
$ keytool -export -alias broker -keystore mybroker.ks -file mybroker_cert
Enter keystore password: test123
Certificate stored in file <mybroker_cert>
This step creates a file named mybroker_cert, containing a broker certificate.
Now you must create a client keystore with the appropriate certificate using a command
similar to the one that was used previously to create the broker’s keystore:
上面的步骤创建了一个名称为mybroker_cert的证书文件,包含代理中使用的证书.现在你必须使用这个证书创建
一个客户端的keystore,使用类似于前面创建broker的keystore时使用的命令:
$ keytool -genkey -alias client -keyalg RSA -keystore myclient.ks
What is your first and last name?
[Unknown]: Dejan Bosanac
What is the name of your organizational unit?
[Unknown]: Chapter 4
What is the name of your organization?
[Unknown]: ActiveMQ in Action
What is the name of your City or Locality?
[Unknown]: Belgrade
What is the name of your State or Province?
[Unknown]:
What is the two-letter country code for this unit?
[Unknown]: RS
Is CN=Dejan Bosanac, OU=Chapter 3, O=ActiveMQ in Action,
L=Belgrade, ST=Unknown, C=RS correct?
[no]: yes
Enter key password for <client>
(RETURN if same as keystore password):
The result of this command is the myclient.ks file with the appropriate certificate for
the client side. Finally, the client truststore must be created and the broker’s certificate
must be imported into it. Again, keytool is used to achieve this with the following
command:
上述命令的执行结果是为客户端创建了包含相应证书的myclient.ks文件.最后,需要创建客户端的受信的密钥仓库(truststore)
然再将代理的证书导入这个受信的密钥仓库(truststore).同样,完成这些需要使用下面的命令:
$ keytool -import -alias broker -keystore myclient.ts -file mybroker_cert
Enter keystore password: test123
Owner: CN=Dejan Bosanac, OU=Chapter 3, O=ActiveMQ in Action,L=Belgrade, ST=Unknown, C=RS
Issuer: CN=Dejan Bosanac, OU=Chapter 3, O=ActiveMQ in Action,L=Belgrade, ST=Unknown, C=RS
Serial number: 484fdc8a
Valid from: Wed Jun 11 16:09:14 CEST 2008 until: Tue Sep 09 16:09:14 CEST 2008
Certificate fingerprints:
MD5: 04:66:F2:AA:71:3A:9E:0A:3C:1B:83:C0:23:DC:EC:6F
SHA1: FB:FA:BB:45:DC:05:9D:AE:C3:BE:5D:86:86:0F:76:84:43:C7:36:D3
Trust this certificate? [no]: yes
Certificate was added to keystore
With this step, all the necessary stores were created and the broker certificate was
imported into the keystore. Now the stock portfolio example can use them.
Remember to start the broker using the newly created certificate. One way to do
this is to replace the default keystore files and the broker cert in the conf directory
with the ones that were just created. For example, if you want to use certificates that
come with the example source code, you’d do something like this:
通过上面的步骤,所有的证书仓库都创建好了,而且代理(broker)的证书也导入到keystore中.
接下来可以在stock portfolio实例中使用这些证书和keystore了.记住,需要使用这些新创建的
证书和keystore文件来启动代理.一种方式是使用新创建的证书和keystore文件替代ACTIVEMQ版本
的conf目录下面的相关文件.比如,可以使用下面的命令以便使用本书实例源码中的证书文件和keystore
文件.
$ cp src/main/resources/org/apache/activemq/book/ch4/mybroker.ks \
${ACTIVEMQ_HOME}/conf/broker.ks
$ cp src/main/resources/org/apache/activemq/book/ch4/myclient.ks \
${ACTIVEMQ_HOME}/conf/client.ks
$ cp src/main/resources/org/apache/activemq/book/ch4/myclient.ts \
${ACTIVEMQ_HOME}/conf/client.ts
Another way is to pass the SSL-related system properties to the command used to start
our broker. For that we need first to copy certificates with their original names (with
prefix my in the name) to the conf/ directory
另一种方式是传递SSL相关的系统属性给启动代理的命令.为此,首先我们需要使用下面的命令,
将证书文件和keystore文件(文件名保持不变)拷贝到conf目录下面.
$ cp src/main/resources/org/apache/activemq/book/ch4/mybroker.ks \
${ACTIVEMQ_HOME}/conf/
$ cp src/main/resources/org/apache/activemq/book/ch4/myclient.ks \
${ACTIVEMQ_HOME}/conf/
$ cp src/main/resources/org/apache/activemq/book/ch4/myclient.ts \
${ACTIVEMQ_HOME}/conf/
So now we can pass the system property and use a keystore other than default one:
现在可以通过传递相关的系统属性,使用我们自己创建的keystore代替默认的keystore,然后启动
代理.
${ACTIVEMQ_HOME}/bin/activemq console \
-Djavax.net.ssl.keyStorePassword=test123 \
-Djavax.net.ssl.keyStore=${ACTIVEMQ_HOME}/conf/mybroker.ks
Finally, we can achieve the same thing with the <sslContext/> element in the
ActiveMQ configuration file, as shown here:
最后,我们也可以通过修改ActiveMQ配置文件中的<sslContext/>元素来配置SSL,配置代码如下:
<broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.base}/data">
<sslContext>
<sslContext keyStore="file:${activemq.base}/conf/mybroker.ks" keyStorePassword="test123"/>
</sslContext>
<transportConnectors>
<transportConnector name="ssl" uri="ssl://localhost:61617" />
</transportConnectors>
</broker>
and start the broker in the usual manner:
然后,可以使用下面常规的启动代理的的命令来启动代理:
${ACTIVEMQ_HOME}/bin/activemq console
xbean:src/main/resources/org/apache/activemq/book/ch4/activemq-ssl.xml
...
Loading message broker from:
xbean:src/main/resources/org/apache/activemq/book/ch4/activemq-ssl.xml
INFO | Using Persistence Adapter:
AMQPersistenceAdapter(/workspace/apache-activemq-5.3.0/data/localhost)
INFO | AMQStore starting using directory:/workspace/apache-activemq-5.3.0/data/localhost
INFO | Kaha Store using data directory/workspace/apache-activemq-5.3.0/data/localhost/kr-store/state
INFO | Active data files: []
INFO | ActiveMQ 5.3.0 JMS Message Broker (localhost) is starting
INFO | For help or more information please see: http://activemq.apache.org/
INFO | Kaha Store using data directory/workspace/apache-activemq-5.3.0/data/localhost/kr-store/data
INFO | JMX consoles can connect to
service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi
INFO | Listening for connections at: ssl://localhost:61617
INFO | Connector ssl Started
INFO | ActiveMQ JMS Message Broker
(localhost, ID:dejan-bosanacs-macbook-pro.local-52935-1265550444721-0:0)
started
...
Now let’s see how to reflect these same changes to the clients. If you try to run the client
applications with the old certificate file, you’ll get the unknown_certificate exception,
just as when the client attempted to access the broker without using any
certificate. So you’ll have to update the command like the following:
现在,让我们看看上述关于ssl的配置修改对客户端的影响.如果使用旧的证书文件运行客户端程序,你将
看到一个未知证书(unknown_certificate)异常,就好像客户端在没有使用任何证书时尝试连接到代理一样.
因此,你需要修改运行客户端代码的命令如下所示:
$ mvn \
-Djavax.net.ssl.keyStore=${ACTIVEMQ_HOME}/conf/myclient.ks \
-Djavax.net.ssl.keyStorePassword=test123 \
-Djavax.net.ssl.trustStore=${ACTIVEMQ_HOME}/conf/myclient.ts \
exec:java -Dexec.mainClass=org.apache.activemq.book.ch4.Publisher \
-Dexec.args="ssl://localhost:61617 CSCO ORCL"
(译注:windows的dos下,输入下面命令(没有换行,实现要建立ACTIVEMQ_HOME环境变量指向ACTIVEMQ的根目录):
mvn -Djavax.net.ssl.keyStore=%ACTIVEMQ_HOME%/conf/myclient.ks -Djavax.net.ssl.keyStorePassword=123456
-Djavax.net.ssl.trustStore=%ACTIVEMQ_HOME%/conf/myclient.ts exec:java
-Dexec.mainClass=org.apache.activemq.book.ch4.Publisher
-Dexec.args="ssl://localhost:61617 CSCO ORCL")
...
Sending: {price=65.713356601409, stock=JAVA, offer=65.779069958011, up=true} on destination: topic://STOCKS.JAVA
Sending: {price=66.071605671946, stock=JAVA, offer=66.137677277617, up=true} on destination: topic://STOCKS.JAVA
Sending: {price=65.929035001620, stock=JAVA, offer=65.994964036622, up=false} on destination: topic://STOCKS.JAVA
...
The command instructs the publisher to use the newly created client stores. After
these changes, the stock portfolio application works again.
上面的命令让publisher使用新创建的客户端证书仓库,做了上述修改后,stock portfolio实例
又可以正常运行了.
ENABLING AND DISABLING SSL CIPHERS
启用/禁用 SSL加密套件
The SSL cipher suites for the ActiveMQ SSL transport are provided by the JVM. For specific
information about these cipher suites, see the documentation on the Sun JSSE
provider (http://mng.bz/7TYe). The Sun JSSE provider supports a long list of cipher
suites, and these are utilized in their default preference order. In some situations,
there can be a need to disable certain ciphers. Examples of such situations include the
discovery of a vulnerability in a particular cipher or a requirement to support only
certain ciphers. To make it easy to enable/disable cipher suites, starting in ActiveMQ
5.4.0, a new option for the SSL transport named transport.enabledCipherSuites is
available. Here’s an example of this new option:
ActiveMQ的SSL传输连接器使用的SSL加密套件(SSL cipher suites)由JVM提供.关于加密套件的详细信息
请参考SUN的JSSE文档(http://mng.bz/7TYe).Sun JSSE提供者支持一系列的加密套件,这些套件按照其默认的
有限顺序被使用.有些情况下,需要禁用某些特定的加密套件.比如一些套件被发现具有缺陷或者需求只能支持几种
特殊的加密套件.为了简化 启用/禁用 加密套件,从5.4.0版本的ActiveMQ开始,引入了一个新的关于SSL传输连接器的
配置项:transport.enabledCipherSuites.下面是使用这个配置项的配置代码例子:
<transportConnectors>
<transportConnector name="ssl" uri="ssl://localhost:61617
?transport.enabledCipherSuites=SSL_RSA_WITH_RC4_128_SHA" />
</transportConnectors>
Please note that the uri attribute shown here has been split into two lines for the purpose
of readability. This is only for readability and will cause the configuration to
break if left in this manner. If you use the configuration example, make sure to combine
the two lines that are held within the quotes.
请注意,为了更好的可读性,上面例子中的URI属性值被分成两行显示了.这里仅仅是为了是代码具有更好的可读性,
在实际配置文件中RUI属性值不能换行,否则代理不能正常启动.如果你使用上面的示例代码,记得让RUI属性值配置
在一行中.
In the preceding example, the SSL_RSA_WITH_RC4_128_SHA cipher suite is the
only one that’s been enabled on the ActiveMQ SSL transport. Additional cipher suites
can be enabled using a comma-separated list. The purpose of this new option is for
added security as it allows only certain cipher suites to be enabled. This can be handy
in environments that consider some cipher suites too weak to leave them enabled,
such as the Payment Card Industry (PCI).
前面例子中,配置SSL_RSA_WITH_RC4_128_SHA为ActiveMQ SSL传输连接器唯一使用的加密套件.
也可以配置多个加密套件,每个加密套件之间用逗号分隔.新增这个选项的目的是通过使用特定的加密
套件来增强安全性.在某些情况下,比如支付卡行业中,使用这个参数可以不启用哪些安全性差的加密套件.
NOTE
To test which cipher suites are enabled, a Perl script named ssl-ciphercheck.pl
is available (http://mng.bz/Ko7k). This script was inspired by the
Payment Card Industry Data Security Standard (PCI DSS) for preventing
credit card fraud (see http://mng.bz/8cYo). The script is easy to use and
makes performing a check for weak ciphers extremely easy.
Not everyone will need to disable SSL cipher suites, but if you do, this new option for
the SSL transport will make the task easy.
注意:
可以使用一个名称为ssl-ciphercheck.pl(从http://mng.bz/Ko7k获得)的Perl脚本来测试哪些加密套件是可用的.
这个脚本来自支付卡行业数据安全标准,用于防止信用卡诈_骗(参见:see http://mng.bz/8cYo).
这个脚本容易使用,能非常轻易的检查出安全性查的加密套件.不是所有人都需要了解SSL加密套件,但是一旦你有相关需求,
使用SSL transport的这个新参数会很容易的完成任务.
4.3.5 Hypertext Transfer Protocol (HTTP/HTTPS)
4.3.5 超文本传输协议(HTTP/HTTPS)
In many environments, firewalls are configured to allow only basic services such as
web access and email. So how can ActiveMQ be used in such an environment? This is
where the HTTP transport comes into play.
许多情况下,防火墙仅允许基本的网络服务,比如web服务和email,这种情况下应该如何使用ActiveMQ?--
这正是HTTP传输连接器的用武之地.
Hypertext Transfer Protocol (HTTP) was originally designed to transmit hypertext
(HTML) pages over the web. It uses TCP as an underlying network protocol and adds
some additional logic for communication between browsers and web servers. After the
first boom of the internet, web infrastructure and the HTTP protocol in particular
found a new role in supporting web services, commonly used these days to exchange
information between applications. The main difference is that in the case of web services,
XML-formatted data is transmitted using the HTTP protocol rather than HTML
data.
超文本传输协议(HTTP)最初用于在web上传输文本(HTML)页面.该协议使用TCP作为底层协议,
同时为浏览器和服务器之间的通信添加了一些额外的控制逻辑.第一波互联网热潮过后,
web基础设施尤其是HTTP协议在web服务支撑方面扮演了新的角色,已被广泛用于当今的应用
程序之间的信息交换.主要的变化是,目前,在web服务中,传输XML格式的数据多于传输HTML格式的数据.
ActiveMQ implements the HTTP transport connector, which provides for the
exchange of XML-formatted messages with the broker using the HTTP protocol. This
is what allows ActiveMQ to bypass strict firewall rules. By using the HTTP protocol that
runs on the standard web port number (80), ActiveMQ can use an existing hole in the
firewall, so to speak.
ActiveMQ实现了ActiveMQ传输连接器,使用HTTP协议来和代理之间交换XML格式的数据.
这就允许ActiveMQ穿越规则严格的防火强.可以这么说,通过在标准网络端口(80)上使用
HTTP协议,ActiveMQ就像使用了防火墙上的一个已存在的通道一样.
The URI syntax of this transport connector is as follows:
HTTP传输连接器的URI语法如下:
http://hostname:port?key=value
Secure HTTP (HTTP over SSL or HTTPS) is also supported by this transport:
传输连接器同样支持安全的HTTP协议(使用SSL的HTTP或HTTPS):
https://hostname:port?key=value
Note the slight difference in the scheme used by the two examples based on whether
SSL is needed. Let’s walk through an example configuration to see how to run the
examples using the HTTP transport. The transport connectors section of the XML
configuration in this case looks similar to those used in previous sections, but with the
HTTP scheme:
注意上面两个基于是否使用SSL的配置代码中的主题有一点不同.让我们通过一个例子的配置,看看怎样
使用HTTP传输连接器.xml配置文件中传输连接器的配置部分跟前面的很类似,只是使用了HTTP主题:
<transportConnectors>
<transportConnector name="tcp" uri="tcp://localhost:61616?trace=true"/>
<transportConnector name="http" uri="http://localhost:8080?trace=true" />
</transportConnectors>
Note that there are two transports configured here: one for the TCP transport and
one for the HTTP transport, which listens to port 8080.
注意,这里配置了两个传输连接器,一个是TCP传输连接器;另一个是HTTP传输连接器,监听8080端口.
In order to run the clients using the HTTP transport protocol, one dependency
must be added to the classpath. The HTTP transport is located in the ActiveMQ
optional module, so you’ll have to add it to the application’s classpath (along with
appropriate dependencies). Using Maven, you’ll need to add the following dependency
to the pom.xml file:
为了在客户端使用HTTP传输协议,需要在类路径中添加一个依赖.HTTP传输连接器是AtiveMQ的可选模块,
因此,你需要添加这个模块到应用程序的类路径中(根据合适的依赖关系).如果使用Maven,你需要在pom.xml文件中添加
如下代码所示的依赖:
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-optional</artifactId>
<version>5.4.1</version>
</dependency>
This will include activemq-optional module and all its dependencies to the classpath.
In case you don’t use Maven to manage your classpath, be sure to include all of
these JARs into your classpath:
这将添加activemq的可选模块及其所有依赖到类路径.如果没有使用Maven来管理类路径,你需要确保下面
的jar包已经添加到类路径中:
$ACTIVEMQ_HOME/lib/optional/activemq-optional-<version>.jar
$ACTIVEMQ_HOME/lib/optional/commons-httpclient-<version>.jar
$ACTIVEMQ_HOME/lib/optional/xstream-<version>.jar
$ACTIVEMQ_HOME/lib/optional/xmlpull-<version>.jar
Finally, the stock portfolio publisher is ready to be run using the HTTP transport:
最后,可以通过下面的的命令使用HTTP传输连接器来运行stock portfolio例子中的publisher:
$ mvn exec:java -Dexec.mainClass=org.apache.activemq.book.ch4.Publisher -Dexec.args="http://localhost:8080 CSCO ORCL"
...
Sending: {price=65.713356601409, stock=JAVA, offer=65.779069958011, up=true} on destination: topic://STOCKS.JAVA
Sending: {price=66.071605671946, stock=JAVA, offer=66.137677277617, up=true} on destination: topic://STOCKS.JAVA
Sending: {price=65.929035001620, stock=JAVA, offer=65.994964036622, up=false} on destination: topic://STOCKS.JAVA
...
As stated previously, when using the HTTP transport, all broker-to-client communication
is performed by sending XML messages. This type of communication can have an
impact on the overall system performance compared to the use of the TCP transport
with the OpenWire protocol (which is tuned specifically for messaging purposes). So
if performance is a concern, you’re best to stick to the TCP transport and find some
other workaround for the firewall issues.
正如前面提到的,使用HTTP传输连接器后,所有代理-客户端之间的通信都是通过XML消息的.
与使用OpenWire协议(为消息使用做过特别优化)的TCP传输连接器相比,这种通信对整个系统的性能都有影响.
因此,假如需要考虑性能,你最好严格的使用TCP传输连接器,并且找到防火墙问题的其他解决方案.
So far this chapter has covered protocols used to connect brokers and clients using
the network stack in the operating system. As an alternative, ActiveMQ was designed to
be embedded in a Java application. This allows client-to-broker communication to take
place locally in the JVM, instead of via the network. In order to support this kind of intra-
VM communication, ActiveMQ provides a special protocol named the VM protocol.
到目前为止,客户端连接到代理所使用的协议都是操作系统中的网络协议栈.作为一个替代方案,
ActiveMQ也可以嵌入到Java应用程序中.客户端和代理可以不需要通过网络,而是在JVM虚拟机内部通信.
为了支持这种虚拟机内部通信,ActiveMQ提供一种特殊协议叫做VM协议.
相关推荐
连接池是一种资源管理技术,通过复用已建立的数据库连接或网络连接,减少创建和销毁连接的开销,提高系统的性能和响应速度。 首先,我们来看自定义的ActiveMQ连接池。作者自己实现的连接池通常是为了满足特定场景下...
4. **连接ActiveMQ**:使用ActiveMQ的Java API或客户端库(如MQTT-Demo中的MQTT协议)建立SSL连接时,你需要指定使用SSL协议并提供必要的认证信息。例如,使用Paho MQTT Java客户端库,你可以这样设置连接参数: ```...
此外,还可以通过调整ActiveMQ配置,如设置更大的缓存大小,优化网络连接,提高消息处理的效率。 7. **安全性与监控**:ActiveMQ支持身份验证和授权,可以通过修改`users.properties`和`groups.properties`文件来...
但不应直接关闭,而是将其归还到连接池中,使用PooledConnection的getConnection()方法的returnConnection()。 5. **关闭连接池**:在系统关闭或不再使用ActiveMQ时,调用PooledConnectionFactory的stop()方法关闭...
在这个例子中,我们连接到ActiveMQ服务器(将`your.active.mq.server`替换为实际的IP地址或域名),订阅了`test/topic`主题,并向该主题发布了一条消息。当收到消息时,控制台会打印出接收到的主题和消息内容。 在...
网络连接模式允许多个 ActiveMQ broker 实例通过网络互连,形成一个集群,从而提升整个系统的消息处理能力,并实现故障转移和负载均衡。 **网络连接模式的作用** 网络连接模式的主要目标是将多个独立的 ActiveMQ ...
2. 客户端连接:客户端通过WebSocket API建立到ActiveMQ的连接,指定目标URL通常是ws://或者wss://(如果是加密连接)加上ActiveMQ服务器的地址和WebSocket端口。 3. 订阅主题或队列:连接建立后,客户端可以订阅想...
通过遵循JMS规范,并提供多种连接协议、持久性和安全选项,ActiveMQ确保了不同系统之间的高效和安全通信。此外,其支持集群功能和多语言客户端API,使得ActiveMQ成为企业消息传递解决方案的一个强大选择。对于希望...
通过IP地址授权,我们可以限制只有特定网络地址的客户端才能连接到ActiveMQ服务器,从而保护系统免受未经授权的访问。而特征码授权则可以基于预定义的代码或密钥来验证用户身份,增加了另一层安全防护。 ActiveMQ的...
测试环境包括客户端(JMeter服务器)、ActiveMQ服务器以及网络连接,确保了独立且可复现的测试条件。 2.2 JMS结构图 JMS架构中,生产者通过JMeter发送消息到ActiveMQ,而消费者从队列或主题中接收消息。此测试涵盖...
启动该程序,你的Go应用就能连接到ActiveMQ,订阅并接收消息,同时也能发送消息到指定队列。 通过这种方式,Go语言可以很好地集成到基于ActiveMQ的消息传递系统中。了解Go的并发模型和错误处理机制,以及STOMP协议...
ActiveMQ允许应用程序通过创建连接、会话和消息生产者/消费者来交换消息。在这个场景中,我们将关注如何利用ActiveMQ的连接池功能,以优化资源管理和提高性能。 首先,理解`Connection`在ActiveMQ中的角色是至关...
ActiveMQ 集群网络连接模式(Network Connector)详解 ActiveMQ 集群网络连接模式(Network Connector)是 ActiveMQ 提供的一种集群功能,旨在提高消息服务的横向扩展性和高可用性。通过将多个不同的 broker 实例...
`mqttws31.js`为前端开发人员提供了一种简单易用的方式,通过Websocket连接到ActiveMQ并使用MQTT协议进行通信。了解如何配置连接、订阅主题、发布消息以及处理相关事件,是利用这个库的关键。结合ActiveMQ的强大功能...
学习ActiveMQ不仅要理解如何发送消息到队列,还需要了解如何设置持久性、队列的生命周期管理、消息确认机制、网络配置、监控和性能调优等方面。深入理解这些知识点,可以帮助开发者构建更健壮、高可用的分布式系统。...
- **连接断开的原因**:在ActiveMQ的Failover模式中,默认情况下,当检测到连接失败时,会触发一个重新连接的任务。如果该任务被标记为守护线程(daemon thread),则当主线程结束时,守护线程也将随之结束,这可能...
首先,需要安装libactivemq-cpp库,并通过创建`cpp::Connection`对象连接到ActiveMQ服务器。然后,创建`cpp::Session`对象来管理和控制消息的传输,接着创建`cpp::Producer`来发送消息和`cpp::Consumer`来接收消息。...
这样,它们就能互相发现并建立网络连接。启动后,从日志中可以观察到 network connection 已经建立。 2. 动态发现: 动态发现更灵活,它不依赖于固定的地址列表。经纪人可以使用 DNS 或 Multicast 来动态地发现彼此...
这就是ActiveMQ与Spring整合的基本流程,通过连接池优化性能。实际应用中,你可能需要根据业务需求调整配置,如设置消息持久化、事务支持、消息确认策略等。同时,确保监控连接池的状态,以确保系统的稳定性和性能。
2. 分区和负载均衡:通过网络连接器(Network of Brokers)实现。 3. 内存与磁盘策略:调整内存缓存大小和磁盘存储策略,平衡性能和稳定性。 九、故障恢复与高可用性 1. 热备份:通过双机热备或集群实现故障自动...