消息机制是软件组件和应用程序之间通讯的一种方法,一个消息系统是一个点对点的服务:消息客户端可以发送消息也可以接收消息,每一个客户端连接到一个消息代理,这个代理提供了消息的创建、发送、接收和读取的功能。
因为是松散耦合的架构使得消息机制很适合用在分布式通讯。组件将消息发送到目的地,而接收者从目的地获取所发送的消息。但是不要求发送者和接收者都同时有效。事实上,发送者不需要知道接收者的信息,而接收者也不知道了解发送者信息。发送者和接收者唯一需要一致的是消息的格式,以及使用哪个目标地址。消息机制跟一些紧耦合的技术例如 RMI 远程方法调用是完全不同的,因为 RMI 必须知道远端应用所提供的方法。
点对点消息域
一个点对点 (PTP) 的产品或者应用是基于消息队列、发送者和接收者的概念来构建的。每个消息被定为到一个特定的队列,接收者从队列中提取发送给它的消息,队列将保留所有的消息直到消息被取走或者过期。
每个消息只有唯一一个接收者(消费者)
- 消息的发送者和接收者没有时间上的依赖,接收者可在消息过期前的任意时间内去获取消息,而不一定得发送者是在线的
- 接收者需要确认成功的处理了消息
- 使用 PTP 消息机制可确保一个消息只有一个接收者
发布/订阅消息域
在一个基于发布/订阅模型的应用或者产品中,客户端根据主题来订阅消息,有点像公告牌。发布者和订阅者一般都是匿名的,而且可以动态的发布或者订阅内容。消息系统会谨慎处理消息的分发到订阅了某个主题的所有订阅者,消息只会发送给当前订阅者,然后就失效,新的订阅者无法接收到刚刚失效的消息。
发布和订阅的消息机制具有以下特征:
- 每个消息可以有多个消费者
- 发布者和订阅者是有时间依赖,只有当前订阅了某个主题的订阅者才能收到消息,订阅者必须保持活跃以获取消息
当一个消息可能会有多于1个的接收者是,请使用发布/订阅消息机制。
接下来我们使用 ActionMQ 来简单演示消息的发送和接收。
首先下载 ActiveMQ for windows (HERE)
下载后解压到任意目录,然后执行 apache-activemq-5.5.1\bin 目录下的 activemq 程序。
运行的提示信息如下:
06 | INFO | jetty-7.1.6.v20100715 |
07 | INFO | ActiveMQ WebConsole initialized. |
08 | INFO | Initializing Spring FrameworkServlet 'dispatcher' |
09 | INFO | ActiveMQ Console at http://0.0.0.0:8161/admin |
10 | INFO | ActiveMQ Web Demos at http://0.0.0.0:8161/demo |
11 | INFO | RESTful file access application at http://0.0.0.0:8161/fileserver |
12 | INFO | Started SelectChannelConnector@0.0.0.0:8161 |
这样 ActiveMQ 服务器就已经启动成功了,你可以按 Ctrl+C 来关闭它,但先别急,因为我们马上要写一些程序来做测试。ActiveMQ 提供一个很不错的管理控制台,你可以在浏览器上打开 http://localhost:8161/admin/ 来访问它。
这里是发送消息的代码:
03 | import org.apache.activemq.ActiveMQConnection; |
04 | import org.apache.activemq.ActiveMQConnectionFactory; |
06 | public class Producer { |
09 | private static String url = ActiveMQConnection.DEFAULT_BROKER_URL; |
12 | private static String procon = "QUEUETOTEST" ; |
14 | public static void main(String[] args) throws JMSException { |
16 | ConnectionFactory connectionFactory = |
17 | new ActiveMQConnectionFactory(url); |
18 | Connection connection = connectionFactory.createConnection(); |
24 | Session session = connection.createSession( false , |
25 | Session.AUTO_ACKNOWLEDGE); |
30 | Destination destination = session.createQueue(procon); |
34 | MessageProducer producer = session.createProducer(destination); |
37 | TextMessage message = session.createTextMessage( "I am First Message" ); |
40 | producer.send(message); |
41 | System.out.println( "Sent message '" + message.getText() + "'" + " On Queue - " + procon); |
下面是 Consumer 类的代码:
03 | import org.apache.activemq.ActiveMQConnection; |
04 | import org.apache.activemq.ActiveMQConnectionFactory; |
06 | public class Consumer { |
08 | private static String url = ActiveMQConnection.DEFAULT_BROKER_URL; |
11 | private static String procon = "QUEUETOTEST" ; |
13 | public static void main(String[] args) throws JMSException { |
15 | ConnectionFactory connectionFactory |
16 | = new ActiveMQConnectionFactory(url); |
17 | Connection connection = connectionFactory.createConnection(); |
21 | Session session = connection.createSession( false , |
22 | Session.AUTO_ACKNOWLEDGE); |
25 | Destination destination = session.createQueue(procon); |
28 | MessageConsumer consumer = session.createConsumer(destination); |
33 | Message message = consumer.receive(); |
39 | if (message instanceof TextMessage) { |
40 | TextMessage textMessage = (TextMessage) message; |
41 | System.out.println( "Received message '" |
42 | + textMessage.getText() + "'" + " On Queue - " + procon); |
你可以在 ActiveMQ 的管理控制台 http://localhost:8161/admin/queues.jsp 中看到在 QUEUETOTEST 的队列中有一个消息。
首先运行上面的 Producer 程序,我们可以看到如下输出:
JMS producer
然后运行 Consumer 程序,输出如下:
consumer
现在运行 Consumer 程序,将会在 Queues 中得到如下结果:
consumer_first
Java Message Service (JMS) API 是 Java EE 平台上用于处理消息的标准。