java之activeMQ

一、activeMQ

默认已经安装完毕

启动,进入activemq目录下的bin目录,启动,./activemq start
关闭防火前或者打开端口

activemq监听的是61616,我们访要查看消息队列的状态时访问8161

java端操作消息队列使用的是61616端口

本地物理机访问8161
http://127.0.0.1:8161/admin/  
弹出输入框,默认用户和密码为admin,查看状态

登录后,会有这么一些列

Number Of Pending Messages :等待消费的消息 这个是当前未出队列的数量。
Number Of Consumers :消费者 这个是消费者端的消费者数量,正在监听的消费端
Messages Enqueued :进入队列的消息 进入队列的总数量,包括出队列的。 
Messages Dequeued :出了队列的消息 可以理解为是消费这消费掉的数量。

队列

点对点模式

点对点的模式主要建立在一个队列上面,当连接一个列队的时候,发送端不需要知道接 收端是否正在接收,
可以直接向 ActiveMQ 发送消息,发送的消息,将会先进入队列中,如 果有接收端在监听,
则会发向接收端,如果没有接收端接收,则会保存在 activemq 服务器, 直到接收端接收消息,
点对点的消息模式可以有多个发送端,多个接收端,但是一条消息, 只会被一个接收端给接收到,
哪个接收端先连上 ActiveMQ,则会先接收到,而后来的接收 端则接收不到那条消息。


服务提供方

public class Test {
    private static final String ACTIVEMQ="tcp://192.168.182.130:61616";
    private static final String QUEUE="que1";
    public static void main(String[] args) throws Exception{
        //创建连接工厂
        ActiveMQConnectionFactory activeMQConnectionFactory=new ActiveMQConnectionFactory(ACTIVEMQ);

        //获得连接
        Connection connection = activeMQConnectionFactory.createConnection();
        //启动访问
        connection.start();
        //创建会话

        //参数: 第一个是事物,第二个是签收
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

        // 创建目的地     分为主题和队列,  这里是创建队列
        Queue queue = session.createQueue(QUEUE);

        //创建消息的生产者
        MessageProducer producer = session.createProducer(queue);


        TextMessage xxxx = session.createTextMessage("xxxx");   //创建消息
        producer.send(xxxx);//发送

        producer.close();
        session.close();
        connection.close();

        System.out.println("发生消息");

    }
}

服务消消费方(一)

同步 阻塞

public class Cous {
    private static final String ACTIVEMQ="tcp://192.168.182.130:61616";
    private static final String QUEUE="que1";
    public static void main(String[] args)throws Exception {

        //创建连接工厂
        ActiveMQConnectionFactory activeMQConnectionFactory=new ActiveMQConnectionFactory(ACTIVEMQ);

        //获得连接
        Connection connection = activeMQConnectionFactory.createConnection();
        //启动访问
        connection.start();
        //创建会话

        //参数: 第一个是事物,第二个是签收
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

        // 创建目的地     分为主题和队列,  这里是创建队列
        Queue queue = session.createQueue(QUEUE);

        MessageConsumer consumer = session.createConsumer(queue);

        TextMessage textMessage=(TextMessage)consumer.receive();等待消息,有消息就获取消息,断开连接
         //还有一个带参数的方法设置时间,当到了时间就会断开连接
         
        System.out.println(textMessage.getText());
        System.out.println("访问结束");
        consumer.close();
        session.close();
        connection.close();
    }
}
同步 阻塞
如果指定的队列没有消息,则会等待,知道队列有消息,获取消息,然后断开连接

服务消消费方(二)

/**
 *  使用监听的方式获取数据  监听器
 *  异步非阻塞
 */
public class Cous2 {
    private static final String ACTIVEMQ="tcp://192.168.182.130:61616";
    private static final String QUEUE="que1";
    public static void main(String[] args)throws Exception {

        //创建连接工厂
        ActiveMQConnectionFactory activeMQConnectionFactory=new ActiveMQConnectionFactory(ACTIVEMQ);

        //获得连接
        Connection connection = activeMQConnectionFactory.createConnection();
        //启动访问
        connection.start();
        //创建会话

        //参数: 第一个是事物,第二个是签收
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

        // 创建目的地     分为主题和队列,  这里是创建队列
        Queue queue = session.createQueue(QUEUE);

        MessageConsumer consumer = session.createConsumer(queue);

        consumer.setMessageListener(new MessageListener() {
            @Override
            public void onMessage(Message message) {
                if (null !=message && message instanceof TextMessage){
                    TextMessage textMessage= (TextMessage)message;
                    try {
                        String text = textMessage.getText();
                        System.out.println(text);
                    } catch (JMSException e) {
                        e.printStackTrace();
                    }
                }
            }
        });

        System.out.println("访问结束");
        System.in.read();
        consumer.close();
        session.close();
        connection.close();
    }
  }
    //当先启动一个服务方,然后在启动消费方,是可以被消费到数据的。
    //当先启动一个服务方,随后启动两个消费方(注意,消费方启动有顺序的),
       //那么只有前面先启动的消费方才可以得到数据。
    //如果是先启动两个消费方,然后在启动服务方,在服务方启动前,消费方会监听消息,当服务方启动后发送数据。
    //那么就会使用轮询的方式让消费方得到值。

主题

服务提供方

/**
 * 生产者
 */
public class Test {
    private static final String ACTIVEMQ="tcp://192.168.182.130:61616";
    private static final String TOPIC="topic";
    public static void main(String[] args) throws Exception{
        //创建连接工厂
        ActiveMQConnectionFactory activeMQConnectionFactory=new ActiveMQConnectionFactory(ACTIVEMQ);

        //获得连接
        Connection connection = activeMQConnectionFactory.createConnection();
        //启动访问
        connection.start();
        //创建会话

        //参数: 第一个是事物,第二个是签收
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

        // 创建目的地     分为主题和队列,  这里是创建主题
        Topic topic = session.createTopic(TOPIC);

        //创建消息的生产者
        MessageProducer producer = session.createProducer(topic);


        TextMessage xxxx = session.createTextMessage("消息订阅");   //创建消息
        producer.send(xxxx);//发送
        producer.close();
        session.close();
        connection.close();

        System.out.println("发生消息");
    }
}

服务消费方(一)

/**
 *  同步阻塞
 *  当有订阅消息是退出程序
 */
public class Cous {
    private static final String ACTIVEMQ="tcp://192.168.182.130:61616";
    private static final String TOPIC="topic";
    public static void main(String[] args)throws Exception {

        //创建连接工厂
        ActiveMQConnectionFactory activeMQConnectionFactory=new ActiveMQConnectionFactory(ACTIVEMQ);

        //获得连接
        Connection connection = activeMQConnectionFactory.createConnection();
        //启动访问
        connection.start();
        //创建会话

        //参数: 第一个是事物,第二个是签收
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

        // 创建目的地     分为主题和队列,  这里是创建主题
        Topic topic = session.createTopic(TOPIC);

        MessageConsumer consumer = session.createConsumer(topic);

        TextMessage textMessage=(TextMessage)consumer.receive();  //还有一个带参数的方法设置时间,当到了时间就会断开连接
        System.out.println(textMessage.getText());
        System.out.println("访问结束");
        consumer.close();
        session.close();
        connection.close();
    }
}


当先启动服务提供方,在启动服务消费方,那么消费方是订阅不到自身启动前的数据,
阻塞的只有订阅到数据才会结束连接

服务消费方(二)

/**
 *  使用监听的方式获取数据  监听器
 *  异步非阻塞
 *  程序一直监听着消息
 *  注意,只能监听到订阅后的消息推送
 */
public class Cous2 {
    private static final String ACTIVEMQ="tcp://192.168.182.130:61616";
    private static final String TOPIC="topic";
    public static void main(String[] args)throws Exception {

        //创建连接工厂
        ActiveMQConnectionFactory activeMQConnectionFactory=new ActiveMQConnectionFactory(ACTIVEMQ);

        //获得连接
        Connection connection = activeMQConnectionFactory.createConnection();
        //启动访问
        connection.start();
        //创建会话

        //参数: 第一个是事物,第二个是签收
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

        // 创建目的地     分为主题和队列,  这里是创建队列
        Topic topic = session.createTopic(TOPIC);


        MessageConsumer consumer = session.createConsumer(topic);

        consumer.setMessageListener(new MessageListener() {
            @Override
            public void onMessage(Message message) {
                if (null !=message && message instanceof TextMessage){
                    TextMessage textMessage= (TextMessage)message;
                    try {
                        String text = textMessage.getText();
                        System.out.println(text);
                    } catch (JMSException e) {
                        e.printStackTrace();
                    }
                }
            }
        });

        System.out.println("监听1");
        System.in.read();
        consumer.close();
        session.close();
        connection.close();
      }
    }

一样,如果服务提供方比消费方先启动执行,那么消费端是无法订阅到自身启动之前服务提供方的发布消息
只不过是非阻塞,使用监听


手动签收

之前的都是自动签收,就是无需消费方返回数据
现在改为手动签收,就以上面的点对点的案例说明
在消费方端改变
这是自动签收的意思
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

手动签收就是第二个参数 改为Session.CLIENT_ACKNOWLEDGE
改为自动签收后,依然可以获取数据,但是activemq依然显示的是消息还没有被消费
需要  textMessage.acknowledge();表示签收了

事物

Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
同样是这句代码
false表示不使用事物
session.commit()提交事物
服务提供方使用事物,必须要手动提交事物。否则消息不能发布
服务消费方如果使用了事物,也必须要提交事物,否则不能改变已经消费的消息状态

总结

所有,必须要先启动服务提供方,在启动消费方

而且有多个消费端,都是比服务提供方先启动的话,那么他们都能够订阅到信息,
队列是只能有一个消费端获取,轮询获取,
而主题是全部都可以获取,前提是消费端要先启动

demo

springboot 整合activemq

点对点

坐标

在springboot环境下加入坐标
 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-activemq</artifactId>
  </dependency>
  没有版本号,说明已经被springboot集成了

yml

spring:
  activemq:
    broker-url: tcp://192.168.182.1157:61616
server:
  port: 8888
queue: xiao   #队列名称

创建一个Queue(队列)

@Component
public class Que {

    @Value("${queue}")
    private String queue;

    @Bean   //加入到spring管理
    public Queue getQueue(){
        return new ActiveMQQueue(queue);
    }
}

服务提供方

@Component
public class pro {

    @Autowired
    private JmsMessagingTemplate jmsMessagingTemplate;  //使用模板

    @Autowired
    private Queue queue;   

    @Scheduled(fixedDelay = 5000)  //定时任务,每隔5秒执行一次
    public void set(){
        long l = System.currentTimeMillis();
        System.out.println("发送到队列");
        jmsMessagingTemplate.convertAndSend(queue, l);
    }
}

启动类

要加上该注解
@EnableScheduling    开启定时任务注解


然后,就会每隔五秒往队列发送消息

服务消费方

@Component
public class cons {

    @JmsListener(destination = "${queue}")
    public void get(String msg){
        System.out.println(msg);
    }
}

监听队列,队列有信息就会被消费

点对点demo

发布订阅

其实和点对点差不多都一样

将Queue改为Topic


注意:发布消息是可以的,但是订阅会有问题,就是springboot整合mq的时候,会默认关闭订阅功能,
需要手动开启

在配置文件中配置
spring:
  jms:
    pub-sub-domain: true

就可以了

发布订阅demo

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页