ActiveMQ学习笔记01

在没有JMS之前,很多应用系统存在缺陷

像下图中A和B直接进行点对点通信,client端的一次调用只能发送给某一个单独的服务对象,无法一对多,而且client 和 server 的生命周期耦合太高,client进程和server服务进程都必须可用,如果server出现问题或者网络故障,那么client端会收到异常,client端发起调用后,必须等待server处理完成并返回结果后才能继续执行

  
JMS,即Java Message Service,通过面向消息中间件(MOM:Message Oriented Middleware)的方式很好的解决了上面的问题。大致的过程是这样的:发送者把消息发送给消息服务器,消息服务器将消息存放在若干队列/主题中,在合适的时候,消息服务器会将消息转发给接受者。在这个过程中,发送和接受是异步的,也就是发送无需等待,而且发送者和接受者的生命周期也没有必然关系;在pub/sub模式下,也可以完成一对多的通信,即让一个消息有多个接受者。


MOM就是面向消息中间件(Message-oriented middleware),是用于以分布式应用或系统中的异步、松耦合、可靠、可扩展和安全通信的一类软件。MOM的总体思想是它作为消息发送器和西消息接收器之间的消息中介,这种中介提供了一个全新水平的松耦合

JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。Java消息服务是一个与具体平台无关的API,绝大多数MOM提供商都对JMS提供支持。JMS是一组消息服务的api即接口规范(ActiveMQ即是对JMS的实现还有阿里的 RocketMQ )。

简单来说就是MOM是中间件,JMS是对中间件定义的规范,而ActiveMQ就是JMS的一种实现

ActiveMQ

activeMQ是Apache推出的,一款开源的,完全支持JMS1.1和J2EE1.4规范的JMS Provider实现的中间件(MOM)

官网地址:http://activemq.apache.org/,分为Linux版和windows版,这里以windows为例

下载号之后解压,目录如下图

bin下面存放的是ActiveMQ的启动脚本activemq.bat,注意分32、64位

conf里面是配置文件,重点关注的是activemq.xml、jetty.xml、jetty-realm.properties。在登录ActiveMQ Web控制台需要用户名、密码信息;在JMS CLIENT和ActiveMQ进行何种协议的连接、端口是什么等这些信息都在上面的配置文件中可以体现。

data目录下是ActiveMQ进行消息持久化存放的地方,默认采用的是kahadb,当然我们可以采用leveldb,或者采用JDBC存储到MySQL,或者干脆不使用持久化机制。

webapps,注意ActiveMQ自带Jetty提供Web管控台

lib中ActiveMQ为我们提供了分功能的JAR包,当然也提供了activemq-all-5.14.4.jar

bin目录下的activemq.bat启动mq,在jetty-realm.properties中可以设置用户名密码,activemq.xml中设置常用配制(端口号等)

在JDK安装没有问题的情况下,直接activemq.bat启动它,并访问Web控制台!


ActiveMQjetty-realm.properties

术语

Provider/MessageProvider:生产者

Consumer/MessageConsumer:消费者

PTP:Point To Point,点对点通信消息模型

Pub/Sub:Publish/Subscribe,发布订阅消息模型

Queue:队列,目标类型之一,和PTP结合

Topic:主题,目标类型之一,和Pub/Sub结合

ConnectionFactory:连接工厂,JMS用它创建连接

Connnection:JMS Client到JMS Provider的连接

Destination:消息目的地,由Session创建

Session:会话,由Connection创建,实质上就是发送、接受消息的一个线程,因此生产者、消费者都是Session创建的

hello world

 
   
public class Sender {
    public static void main(String[] args) throws Exception{
      //1、建立ConnectionFactory,需要填入用户名、密码以及连接的地址,均使用默认即可,默认为"tcp:localhost:61616"
        ConnectionFactory connectfactory = new ActiveMQConnectionFactory(
                    ActiveMQConnectionFactory.DEFAULT_USER,
                    ActiveMQConnectionFactory.DEFAULT_PASSWORD,
                    "tcp://localhost:61616");
        //2、通过connectionfactory创建一个connection,并且调用connection的start方法开启连接,连接默认是关闭的
        Connection connection = connectfactory.createConnection();
        connection.start();
        //3、通过connection创建一个session会话(上下文环境),用于接收消息,
            //3.1  参数1为是否开启事务
            //3.2 参数2为签收模式,一般设置为自动签收
        Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);
        //4、 Destination :消息的目的地;消息发送给谁.在PTP模式中,被称为Queue,在发布订阅模式中被称为Topic
        // 获取session注意参数值my-queue是Query的名字
        Destination destination = session.createQueue("my-queue");
        //5、通过session创建消息的发送者和接受者MessageProducer和MessageCustomer
        MessageProducer producter = session.createProducer(destination);
        
        for(int i=0;i<5;i++){
            TextMessage message = session.createTextMessage("message--"+i);
            producter.send(message);
        }
        
        if(connection!=null)
        connection.close();//会自动关闭session等
    }
}
运行发送者代码,可以看到

有五条消息放入了中间件

Messages Enqueued:表示生产了多少条消息,记做P

Messages Dequeued:表示消费了多少条消息,记做C

Number Of Consumers:表示在该队列上还有多少消费者在等待接受消息

Number Of Pending Messages:表示还有多少条消息没有被消费,实际上是表示消息的积压程度,就是P-C

接下来我们写接收者来接收消息
public static void main(String[] args) throws Exception{
        //1、建立ConnectionFactory,需要填入用户名、密码以及连接的地址,均使用默认即可,默认为"tcp:localhost:61616"
          ConnectionFactory connectfactory = new ActiveMQConnectionFactory(
                      ActiveMQConnectionFactory.DEFAULT_USER,
                      ActiveMQConnectionFactory.DEFAULT_PASSWORD,
                      "tcp://localhost:61616");
          //2、通过connectionfactory创建一个connection,并且调用connection的start方法开启连接,连接默认是关闭的
          Connection connection = connectfactory.createConnection();
          connection.start();
          //3、通过connection创建一个session会话(上下文环境),用于接收消息,
              //3.1  参数1为是否开启事务
              //3.2 参数2为签收模式,一般设置为自动签收
          Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);
          //4、 Destination :消息的目的地;消息发送给谁.在PTP模式中,被称为Queue,在发布订阅模式中被称为Topic
          // 获取session注意参数值my-queue是Query的名字
          Destination destination = session.createQueue("my-queue");
          //5、通过session创建消息的发送者和接受者MessageProducer和MessageCustomer
          MessageConsumer consumer = session.createConsumer(destination);
          
          while(true) {
              TextMessage msg = (TextMessage)consumer.receive();
              if(msg==null)
                  break;
              System.out.println(msg.getText());
          }
          if(connection!=null)
          connection.close();//会自动关闭session等
      }
运行代码之后可以看到
有一个接收者消费了五条消息
至此我们可以看出ActiveMQ的大体作用,发送者相当于我们上图中的A系统,接收者相当于B系统,两者实现了解耦,当A发送消息时,B系统尚没有启动


猜你喜欢

转载自blog.csdn.net/aawmx123/article/details/80177524