## 4.3 通过网络连接到ActiveMQ-Connecting to ActiveMQ over the network

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.

(消息生产者和消费者)需要使用一些网络协议一般连接到代理目的地.本节中,我们将介绍可用于实现

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.

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)中运行时,他们之间需要通信

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.

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协议是一种主机间的高可用的通信协议,该协议使用数据包交换数据实现主机网络间通信,同时该协议也适用于

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.

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.

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连接器的URI语法如下:

tcp://hostname:port?key=value&key=value

The following configuration snippet provides an example of using the TCP connector

in the ActiveMQ configuration file:

<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.

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:

$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

$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

\$ 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