JMS和ActiveMQ入门

来源:互联网 发布:2017中国大学生数据 编辑:程序博客网 时间:2024/06/07 02:53

activeMQ学习

ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线。

1.JSM介绍

JMS(JavaMessage Service,java消息服务)使分布式通信耦合度更低,消息服务更加可靠以及异步性。JSM分为Point-to-Point(P2P)点对点模型和Publish/Subscribe(Pub/Sub)发布订阅模型。

1.1 p2p模式

每个消息只有一个消费者(Consumer)(即一旦被消费,消息就不再在消息队列中)发送者和接收者之间在时间上没有依赖性,也就是说当发送者发送了消息之后,不管接收者有没有正在运行,它不会影响到消息被发送到队列

接收者在成功接收消息之后需向队列应答成功。

1.2 Pub/Sub模式

每个消息可以有多个消费者,针对某个主题(Topic)的订阅者,它必须创建一个订阅者之后,才能消费发布者的消息,而且为了消费消息,订阅者必须保持运行的状态。即使订阅者没有被激活(运行),它也能接收到发布者的消息。队列模型和PUB/SUB模型的区别,Queue只能由一个消费者接收,其他Queue中的成员无法接受到被已消费的信息,而Topic则可以,只要是订阅了Topic的消费者,全部可以获取到生产者发布的信息。

1.3 消息类型

JMS定义了五种不同的消息正文格式,以及调用的消息类型,允许你发送并接收以一些不同形式的数据。

StreamMessage --Java原始值的数据流

MapMessage--一套名称-值对

TextMessage--一个字符串对象

ObjectMessage--一个序列化的 Java对象

BytesMessage--数据流信息

2. ActiveMQ

完全支持JMS1.1和J2EE 1.4规范 (持久化,XA消息,事务), 对spring的支持。

2.1 下载安装

网址http://activemq.apache.org/

解压到计算机

双击启动ActiveMQ

访问http://127.0.0.1:8161/admin/ 就可以查看active管理后台了

初始账号密码 admin

依赖jar

 

2.2 Queue测试

需求:一个生产者向一个消费者发送一个图片。

生产者:

public classQueueProducer {

   
private static Stringusername ="admin";
    private static
String password= "admin";
    private static
String brokeurl= "tcp://127.0.0.1:61616";

    public static void
main(String[] args){
        ConnectionFactoryconnectionFactory
;
       
Connectionconnection = null;
       
Session session;
       
Destinationdestination;
       
MessageProducermessageProducer;
       
connectionFactory =newActiveMQConnectionFactory(username,password,brokeurl);

        try
{
           
connection =connectionFactory.createConnection();
           
connection.start();
           
session =connection.createSession(true,Session.AUTO_ACKNOWLEDGE);
            
destination = session.createQueue("activemq.queue");
           
messageProducer =session.createProducer(destination);
           
//发送一张图片
           
BytesMessagebytesMessage = session.createBytesMessage();
           
FileInputStreamfileInputStream = new FileInputStream(newFile("E://timg.jpg"));
            byte
[] bytes = new byte[fileInputStream.available()];
           
fileInputStream.read(bytes);
           
bytesMessage.writeBytes(bytes);
           
messageProducer.send(bytesMessage);
           
session.commit();
       
} catch(Exception e) {
            e.printStackTrace()
;
       
}finally{
           
if(connection !=null){
               
try {
                    connection.close()
;
               
} catch(JMSException e){
                    e.printStackTrace()
;
               
}
            }
        }

    }
}

结果

消费者:

public class QueueConsumer {    private static String username = "admin";    private static String password = "admin";    private static String brokeurl = "tcp://127.0.0.1:61616";    private static String queuename = "activemq.queue";    public static void main(String[] args) throws IOException {        ConnectionFactory connectionFactory;        Connection connection;        Session session;        Destination destination;        MessageConsumer messageConsumer;        connectionFactory = new ActiveMQConnectionFactory(username,password,brokeurl);        try {            connection = connectionFactory.createConnection();            connection.start();            session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);            destination = session.createQueue(queuename);            messageConsumer = session.createConsumer(destination);            BytesMessage bytesMessage = (BytesMessage) messageConsumer.receive();            byte[] bytes = new byte[(int) bytesMessage.getBodyLength()];            bytesMessage.readBytes(bytes);            FileOutputStream fileOutputStream = new FileOutputStream(new File("E://111.jpg"));            fileOutputStream.write(bytes);        } catch (JMSException e) {            e.printStackTrace();        }    }}

成功获取图片。

2.3 pub/sub测试

生产者代码:

destination = session.createQueue("activemq.queue");
messageProducer = session.createProducer(destination);

修改为:

topic = session.createTopic(queuename);messageProducer = session.createProducer(topic);

测试结果:

Number Of Pending Messages 等待消费的消息这个是当前未出队列的数量。可以理解为总接收数-总出队列数

Messages Enqueued 进入队列的消息进入队列的总数量,包括出队列的。这个数量只增不减

Messages Dequeued 出了队列的消息可以理解为是消费掉的数量。

 

消费者:

public class TopicConsumer {    private static String username = "admin";    private static String password = "admin";    private static String brokeurl = "tcp://127.0.0.1:61616";    private static String queuename = "activemq.topic";    public static void main(String[] args) throws Exception {        ConnectionFactory connectionFactory;        Connection connection;        Session session;        Topic topic;        MessageConsumer messageConsumer;        connectionFactory = new ActiveMQConnectionFactory(username,password,brokeurl);        try {            connection = connectionFactory.createConnection();            connection.start();            session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);            topic = session.createTopic(queuename);            messageConsumer  = session.createConsumer(topic);            //多条消息处理            messageConsumer.setMessageListener(new MessageListener() {                public void onMessage(Message message) {                    BytesMessage bytesMessage = (BytesMessage) message;                    try {                        byte[] bytes = new byte[(int) bytesMessage.getBodyLength()];                        bytesMessage.readBytes(bytes);                        FileOutputStream fileOutputStream = new FileOutputStream(new File("E://" + UUID.randomUUID() +                                ".jpg"));                        fileOutputStream.write(bytes);                    }catch (Exception e){                        System.out.println("......................");                    }                }            });        } catch (JMSException e) {            e.printStackTrace();        }    }}

messageListener会注册一个监听器,当有消息到达的时候会回调它的Onmessage()方法。

2.4延迟投递

Property name

type

description

AMQ_SCHEDULED_DELAY

long

延迟投递的时间

AMQ_SCHEDULED_PERIOD

long

重复投递的时间间隔

AMQ_SCHEDULED_REPEAT

int

重复投递次数

AMQ_SCHEDULED_CRON

String

Cron表达式

3.ActiveMQ持久化方式

消息持久性对于可靠消息传递来说应该是一种比较好的方法,有了消息持久化,即使发送者和接受者不是同时在线或者消息中心在发送者发送消息后宕机了,在消息中心重新启动后仍然可以将消息发送出去,如果把这种持久化和ReliableMessaging结合起来应该是很好的保证了消息的可靠传送。

发送者将消息发送出去后,消息中心首先将消息存储到本地数据文件、内存数据库或者远程数据库等,然后试图将消息发送给接收者,发送成功则将消息从存储中删除,失败则继续尝试。消息中心启动以后首先要检查制定的存储位置,如果有未发送成功的消息,则需要把消息发送出去。

ActiveMQ持久化方式:AMQ、KahaDB、JDBC、LevelDB。

原创粉丝点击