Java SE foundation consolidation (xiv): JMS

1 Overview

That JMS Java Message Service (Java Message Service), which is a set of specifications, provide a convenient and versatile way to make Java programs to create, send, receive and read messages.

In large projects, many of which are used in the called middleware, message-oriented (the Message Oriented Middleware) , commonly referred to as messaging middleware, now popular messaging middleware products mainly include ActiveMQ, RabbitMQ, Kafka, RocketMQ and so on, a lot of large commercial software products to build applications using these messaging systems, messages transmitted between each module (or service) application, in order to achieve decoupling, clipping, and the like to improve the throughput of the application object.

Because many products, if not a mature specification constraint, the concrete realization of various manufacturers may differ materially messaging middleware, enabling developers when switching products is very troublesome and had to rewrite a lot of code to adapt the product. JMS is such a specification that defines what components should have a messaging middleware product, which interfaces, etc., if the message can be based on middleware specification defines interfaces to achieve it, developers only need to pay when building the messaging system very little cost to switch to a different product, because the interface is the same, almost no how to modify the code.

JMS specification defines several components are as follows:

  • JMS Provider. Components provide messaging services, to provide service to JMS clients, JMS client may have a producer client and consumer clients.
  • JMS Message. I.e. messaging entity.
  • JMS Domains. I.e., the destination messaging.

JMS Message contains the following parts:

  • Header. All messages have the same set of Header field, similar to the HTTP Header, these fields are used between the client and server (Provider) routing the authentication or the like, comprising JMSDestination, JMSMessageID, JMSTimestamp like.
  • Properties. That property is optional, a property of constituting a key, the key is the attribute name, value is the value of the property. Applications can custom attributes, and attach it to the Message Header and Body and sent together.
  • Body, that is the main message body, such as for an ordinary text message, the message is the subject of this article, such as "Hello" string.

The above is a brief introduction to JMS, and more about the JMS specification, the proposed document refer to JSR 914 (the keyword search directly in the search engines can find), I will show JMS specification defines the interface and to use ActiveMQ Demo as building a small practice, it will eventually introduce two common message delivery models: point to point transmission model and the publish / subscribe transmission model.

Note that this message is not narrowly said the news that is not specific to a word or a mail, the message may be not only a string, can also be a Java objects.

2 JMS interfaces

i0qesK.png

FIG JMS specification defines the interface is the most common interface JMS is left, the right side is an interface of two different message delivery model, universal interface to introduce the following:

  • ConnectionFactory, namely the connection factory, Connection needs to be created by ConnectionFactory.
  • Connection, i.e. connection represents a connection to the JMS Provider.
  • Destination, i.e. the destination, indicates the end of a message sent, for example, when the mail recipient mailbox.
  • The Session, i.e. a session, and for transmitting a threaded context accept message.
  • MessageProducer, that is news producer, news producers are the sender of a message, is responsible for creating and sending messages JMS Provider.
  • MessageConsumer, that is the message consumers, message consumer is the recipient of the message, is responsible for receiving and reading (consumption) message from the JMS Provider.

The figure is the view of the relationship between several interfaces:

i0qcLT.png

Next it will be, so we almost according to a diagram to write at the time of writing code using ActiveMQ.

3 Using ActiveMQ

There is no standard Java SE implements the JMS specification, so there are no standard JDK several interfaces and corresponding implementation mentioned above, but there are implemented Java EE, but relatively cumbersome to build Java EE (just a Demo only), so here ActiveMQ directly use this product. ActiveMQ JMS to achieve a specification that provides JMS specification defines an interface, the reason for using ActiveMQ as opposed to other products, because of ActiveMQ achieve more "standard", very fit JMS specification, and low learning curve called several other products .

3.1 is installed and running ActiveMQ

Installation is very simple, ActiveMQ directly to the official website to download it, I used here is 5.15.6 This version, in windows, download apache-activemq-5.15.6-bin.zip this archive (under Unix systems, download --5.15.6-ActiveMQ the Apache bin.tar.gz ), then extract into the bin directory on the command line, you can enter activemq start.

Recommendations to Get Start section of the official website to see the installation starts up very detailed, I will not say more.

Once started, you can enter in the browser http: // localhost: 8161 to view the data ActiveMQ, as follows:

i0LKXV.png

Click Manage ActiveMQ broker to enter the console, the default account and password are admin, as shown below after entering:

i0L17F.png

Here, you can select each tab bar to see different information, such as Topic, Queue, and specifically in this much to say, readers can try on their own.

Import dependent ActiveMQ 3.2

If you are using Maven to build the project, you can add the following dependence:

<dependency>
    <groupId>org.apache.activemq</groupId>
    <artifactId>activemq-all</artifactId>
    <version>5.15.6</version>
</dependency>
复制代码

If you do not use Maven, you need to project yourself in import jar package, just download the compressed package, including activemq-all-5.15.6.jar this jar package, import it to the class path to the project.

3.3 write Demo

After the preparatory work done, you can officially write code, demo code as follows:

JMSProducer

package top.yeonon.jms;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

/**
 * @Author yeonon
 * @date 2018/10/20 0020 14:09
 **/
public class JMSProducer {

    private static final String USERNAME = ActiveMQConnection.DEFAULT_USER;
    private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD;
    private static final String BROKER_URL = ActiveMQConnection.DEFAULT_BROKER_URL;

    public static void main(String[] args) throws JMSException {
        //连接工厂
        ConnectionFactory connectionFactory;
        //连接
        Connection connection;
        //Session会话
        Session session;
        //目的地
        Destination destination;

        //创建连接工厂实例
        connectionFactory = new ActiveMQConnectionFactory(USERNAME,PASSWORD, BROKER_URL);
        //从连接工厂实例中创建连接
        connection = connectionFactory.createConnection();
        //从连接中创建Session,第一个参数是是否开启事务,这里选择不开启,传入false
        // 第二个参数是消息确认模式,这里选择的是自动确认
        session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //创建了一个队列,队列Queue(javax.jms包里的Queue)继承了Destination接口
        destination = session.createQueue("Hello");
        //创建一个消息生产者,需要传入一个destination,这样这个producer就和destination绑定了
        MessageProducer producer = session.createProducer(destination);

        //配置完成之后,启动连接
        connection.start();

        //发送消息
        for (int i = 0; i < 10; i++) {
            TextMessage message = session.createTextMessage("message " + i);
            System.out.println("producer send message : " + message.getText());
            producer.send(message);
        }

        //发送完成后,关闭连接
        connection.close();
    }
}

复制代码

JMSConsumer

package top.yeonon.jms;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

/**
 * @Author yeonon
 * @date 2018/10/20 0020 14:19
 **/
public class JMSConsumer {

    private static final String USERNAME = ActiveMQConnection.DEFAULT_USER;
    private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD;
    private static final String BROKER_URL = ActiveMQConnection.DEFAULT_BROKER_URL;

    public static void main(String[] args) throws JMSException {
        //连接工厂
        ConnectionFactory connectionFactory;
        //连接
        Connection connection;
        //Session会话
        Session session;
        //目的地
        Destination destination;

        //创建连接工厂实例
        connectionFactory = new ActiveMQConnectionFactory(USERNAME,PASSWORD, BROKER_URL);
        //从连接工厂实例中创建连接
        connection = connectionFactory.createConnection();
        //从连接中创建Session,第一个参数是是否开启事务,这里选择不开启,传入false
        // 第二个参数是消息确认模式,这里选择的是自动确认
        session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //创建了一个队列,队列Queue(javax.jms包里的Queue)继承了Destination接口
        destination = session.createQueue("Hello");
        //创建一个消息生产者,需要传入一个destination,这样这个producer就和destination绑定了
        MessageConsumer consumer = session.createConsumer(destination);

        //配置完成之后,启动连接
        connection.start();

        //接受消息
        while (true) {
            TextMessage message = (TextMessage) consumer.receive(10000);
            if (message != null)
                System.out.println("receive message : " + message.getText());
        }
    }
}
复制代码

Notes written in code is very clear, they only talk about a feel puzzled Destination, in the demo code, use the Queue to represent the destination, the initial contact message queue, you may feel a little strange, how a Queue is a the destination? In fact, this is entirely possible, because the destination is not necessarily the stuff ip address or E-mail and the like, as long as it can accept a message of support to, and now most of the messaging middleware are more or less only a message queue as a carrier, sometimes referred to as middleware message directly to the message queue (message queue).

Consumer first run, a slight wait for a while, and then run producer, after the producer has finished running similar to the following can be seen in the producer output console:

producer send message : message 0
producer send message : message 1
producer send message : message 2
producer send message : message 3
producer send message : message 4
producer send message : message 5
producer send message : message 6
producer send message : message 7
producer send message : message 8
producer send message : message 9
复制代码

Then go to the consumer to see the console, you found similar to the following output:

receive message : message 0
receive message : message 1
receive message : message 2
receive message : message 3
receive message : message 4
receive message : message 5
receive message : message 6
receive message : message 7
receive message : message 8
receive message : message 9
复制代码

If you can see the above output, the producers have successfully send messages to the JMS provider (ActiveMQ service), and smooth and the consumer has removed a message from a JMS provider and read in, the process. If you open more than one consumer, but also to see the message sent by the producer to be more common consumer spending, for example, there are two consumer, may have the following output:

consumer1:

receive message : message 0
receive message : message 2
receive message : message 4
receive message : message 6
receive message : message 8
复制代码

consumer2:

receive message : message 1
receive message : message 3
receive message : message 5
receive message : message 7
receive message : message 9
复制代码

Load Balancing little meaning, because now there are two consumer Hello shared a queue, and then turn out the message from the queue Hello and consumption (which is the default ActiveMQ).

4 messaging model

JMS specification defines two messaging models: point to point transmission model and publish / subscribe transmission model .

4.1 point to point transmission model

In the point to point model, messages sent by the producer to the queue, the message queue and then sent to the consumer. In this process, the destination of the message is a queue, the queue monitor consumer, when there are messages in the queue, the queue will listen to the message queue of the consumer. The queue can simply be seen as a transit point, responsible for receiving messages sent from producers and then re-send the message to the consumer.

A queue can have multiple producers and consumers, but the message can only be accepted and consume a consumer, JMS provider will determine which message is sent to the consumer in accordance with the principle of "first come, first served". If none of the consumers in the listen queue, the message and then accumulate in the queue, stackable news how much the discretion of the specific size of the queue and JMS provider, if the size exceeds the limits, the excess messages may be discarded, it may also be stored to persistent memory (depending on the particular implementation).

4.2 publish / subscribe model transmission

In the publish / subscribe model, destination of the message is no longer a simple queue, but a Topic (theme), the message sent by the producer to Topic, and then passed to subscribed to the topic of consumers. A Topic can also bind multiple producers and multiple consumers, and peer to peer model is different, a message can be consumed more consumers, which assumes that there are two consumers simultaneously subscribe to a Topic, then when there is news Topic is sent to this, two copies of the message will be sent to the Topic two consumers.

Notably, this is actually a Topic abstract concept, which may be a concrete form a queue, or queue group composed of a plurality of queues (depending on the particular implementation), only on the queue again on a label Topic producers and consumers is no longer a simple goal of a queue, but a Topic. For example, we now define the Topic called hello, the producer indicate you want to send a message to this hello Topic, consumers are also interested in this hello Topic (ie subscription Topic), while the bottom is a Topic queue, when producers send messages, the underlying fact is sent to the queue hello topic marked the label, and then copy the message is then passed to the consumer hello topic of interest.

The explanation here may be some not so reasonable, I hope readers can understand. Do not understand all right, here I will write a publication demo code / subscription model, to facilitate understanding of this model.

Written in Section 3 Demo in fact, point to point model, the model switched from point to point your publish / subscribe model is very simple, for the Demo above, only you need to modify two lines of code:

//点对点模型中的producer
destination = session.createQueue("Hello");
//发布/订阅模型中的producer
destination = session.createTopic("Hello");


//点对点模型中的consumer
destination = session.createQueue("Hello");
//发布/订阅模型中的consumer
destination = session.createTopic("Hello");
复制代码

When you're done, run two consumer, a producer, and then look at the output console.

Producer output substantially as follows:

producer send message : message 0
producer send message : message 1
producer send message : message 2
producer send message : message 3
producer send message : message 4
producer send message : message 5
producer send message : message 6
producer send message : message 7
producer send message : message 8
producer send message : message 9
复制代码

consumer1:

receive message : message 0
receive message : message 1
receive message : message 2
receive message : message 3
receive message : message 4
receive message : message 5
receive message : message 6
receive message : message 7
receive message : message 8
receive message : message 9
复制代码

consumer2:

receive message : message 0
receive message : message 1
receive message : message 2
receive message : message 3
receive message : message 4
receive message : message 5
receive message : message 6
receive message : message 7
receive message : message 8
receive message : message 9
复制代码

Found consumer1 and consumer2 have received producer released 10 news, a total of 20 messages. This point is not the same model, peer model, no matter how many consumers will only accept a total of 10 messages.

5 Summary

This paper briefly describes the JMS specification of some components, interfaces, JMS can understand a deeper understanding of the various messaging middleware products. After introducing two JMS messaging model defined: point to point model and publish / subscribe model . The biggest difference between the two is: point to point model, no matter how many consumers, a message can only be accepted by a consumer and the consumer, publish / subscribe model, a message can be consumed by multiple consumers. The article also provides a Demo, so that we intuitively feel the difference between these two models, deepen understanding.

6 References

JSR 914

Guess you like

Origin juejin.im/post/5d6e808e518825168e6a2767