SpringBoot学习笔记二:JMS(java Message Service)java消息服务

1. SpringBoot学习笔记二:JMS(java Message Service)java消息服务

文章目录

        • 1. SpringBoot学习笔记二:JMS(java Message Service)java消息服务
          • 1.1. 什么是JMS
          • 1.2. 使用场景
          • 1.3. 一些概念
          • 1.4. 消息队列的编程模型
        • 2. ActiveMQ学习
          • 2.1. SpringBoot整合ActiveMQ
          • 2.2. 消息队列的使用
          • 2.3. 消息队列中的消费者
        • 3. ActiveMQ的发布/订阅者模式
          • 3.1. 发布订阅模式
          • 3.2. 发布/订阅模式中的消费者
          • 3.3. 消息队列实现两种模式

1.1. 什么是JMS
  1. java消息服务,java平台中关于面向消息中间件的接口。
  2. JMS是一种与厂商无关的API,用来访问消息收发系统消息,它类似于JDBC。而JDBC是用来访问许多不同关系数据库的API
1.2. 使用场景
  1. 跨平台
  2. 多语言
  3. 多项目
  4. 解耦
  5. 分布式事务
  6. 流量控制
  7. 最终一致性
  8. RPC调用:上下游对接,数据源变动–>通知下属

SpringBoot学习笔记二:JMS(java Message Service)java消息服务_第1张图片

1.3. 一些概念
  1. JMS提供者(Apache ActiveMQ、RabbitMQ、Kafka、Notify、MetaQ、RocketMQ)
  2. JMS生产者(Message Producer)
  3. JMS消费者(Message Consumer)
  4. 消息队列通常两种模型:点对点(point-to-Point)、发布/订阅(Publish/Subscribe)

SpringBoot学习笔记二:JMS(java Message Service)java消息服务_第2张图片

SpringBoot学习笔记二:JMS(java Message Service)java消息服务_第3张图片

1.4. 消息队列的编程模型
  1. ConnectionFactory:连接工厂,JMS,用它创建连接。
  2. Connection:JMS客户端到JMS Provider的连接。
  3. Session:一个发送或接收消息的线程。
  4. Destination:消息的目的地;消息发送给谁?
  5. MessageConsumer/MessageProducer:消息接收者,消费者。

SpringBoot学习笔记二:JMS(java Message Service)java消息服务_第4张图片

2. ActiveMQ学习

  1. 安装略
  2. 各种名称:

Name:队列名称

Nubmer of Pending Messages:等待消费的消息个数

Nubmer Of Consumers :当前连接的消费者数目

Messages Enqueued: 进入队列的消息总个数,包含出队列和待消费的,这个数量只增不减。

Messages Dequeued:已经消费的消息数量。

  1. linux进入开启消息队列服务
./activemq start
2.1. SpringBoot整合ActiveMQ
  1. 引入工具集依赖:Spring-boot-starter-activemq
    • 消息队列连接池,可以提高效率,减少连接的重复工作。不用来回创建连接,销毁连接了。
<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-activemqartifactId>
dependency>

<dependency>
    <groupId>org.apache.activemqgroupId>
    <artifactId>activemq-poolartifactId>
    <version>5.15.0version>
dependency>
  1. 配置application.properties
#整合jms测试,防火墙和端口号要开放
spring.activemq.broker-url=tcp://127.0.0.1:61616
#集群配置
#spring.activemq.broker-url=failover:(tcp://localhost:61616,tcp://localhost:61617)
spring.activemq.user=admin
spring.activemq.password=admin
#下列配置要添加依赖
spring.activemq.pool.enable=true
spring.activemq.pool.max-connections=100
  1. 启动类
@SpringBootApplication
@EnableJms //启动消息队列
public class ProviderApplication {
	public static void main(String[] args) {
		SpringApplication.run(ProviderApplication.class, args);
	}
}
  1. 将队列交给spring进行管理,方便后续注入
@Bean
public Queue queue(){
    return new ActiveMQQueue("common.queue");
}
2.2. 消息队列的使用
  1. 消息生产者:给消息队列发送消息。

功能描述:

​ 指定消息队列和消息。

​ 使用默认消息队列,发送消息。

public interface ProducerService {

    /**
	 * 功能描述:指定消息队列,还有消息
	 * @param destination
	 * @param message
	 */
    public void sendMessage(Destination destination, final String message);

    /**
	 * 功能描述:使用默认消息队列, 发送消息
	 * @param message
	 */
    public void sendMessage( final String message);


    /**
	 * 功能描述:消息发布者
	 * @param msg
	 */
    public void publish(String msg);
}
  1. 实现类
@Service
public class ProducerServiceImpl implements ProducerService{

    @Autowired
    private Queue queue;

    //这个就是springboot集成的发送消息队列的各种模板。
    @Autowired
    private JmsMessagingTemplate jmsTemplate; //用来发送消息到broker的对象

    //发送消息,destination是发送到的队列,message是待发送的消息
    @Override
    public void sendMessage(Destination destination, String message) {

        jmsTemplate.convertAndSend(destination, message);
    }
    //发送消息,destination是发送到的队列,message是待发送的消息
    @Override
    public void sendMessage(final String message) {
        jmsTemplate.convertAndSend( message);
    }
    //=======发布订阅相关代码=========
    @Autowired
    private Topic topic;
    @Override
    public void publish(String msg) {
        this.jmsTemplate.convertAndSend(this.topic, msg);
    }
}
  1. 通过Controller层往消息队列里面写入消息
@GetMapping("order")
public Object order(String msg){
    //生成消息队列地址,new创建一个队列,然后将该队列给父类,也就是多态Destination,destination包含该队列的所有属性。
    Destination destination = new ActiveMQQueue("order.queue");
    producerService.sendMessage(destination, msg);
    return JsonData.buildSuccess();
}
2.3. 消息队列中的消费者
  1. 消费者监听队列
@Component//这个用于spring扫描和application一起启动
public class OrderConsumer {
    @JmsListener(destination="order.queue")//JmsListener监听消息队列,一旦有消息就会消费。
    public void receiveQueue(String text){
        System.out.println("OrderConsumer收到的报文为:"+text);
    }
}

3. ActiveMQ的发布/订阅者模式

3.1. 发布订阅模式
  1. activeMQ默认支持点对点模式,如果要开启发布订阅者模式需要在application.properties中以下配置
spring.jms.pub-sub-domain=true

  1. 将发布订阅的队列交给spring来管理
@Bean
public Topic topic(){//创建一个订阅队列,video.topic
    return new ActiveMQTopic("video.topic");
}

  1. service层
public void publish(Strin msg);

  1. impl实现层
@Autowired
private Topic topic;//这个说明已经交给Spring来管理了,有这个的前提表明需要提前将队列交给Spring

public void publish(String msg){
    this.jmsTemplate.convertAndSend(this.topic,msg);
}

  1. 提前将队列交给Spring
@Bean
public Topic topic(){
    return new ActiveMQTopic("video.topic");
}

  1. Controller层添加发布消息接口
@GetMapping("topic")
public Object topic(String msg){
    producerService.publish(msg);
    return JsonData.buildSuccess(); 
}

3.2. 发布/订阅模式中的消费者
  1. 使用注解订阅队列,由于订阅模式可以被多个消费者订阅。因此只要改变消费者方法名就可以了。
@Component
public class TopicConsumer{
    @JmsListener(destination="video.topic")
    public void receive(String text){
        System.out.println("video.topic消费者receivel="+text);
    }
    @JmsListener(destination="video.topic")
    public void receive1(String text){
        System.out.println("video.topic消费者receivel="+text);
    }
    @JmsListener(destination="video.topic")
    public void receive2(String text){
        System.out.println("video.topic消费者receivel="+text);
    }
}

3.3. 消息队列实现两种模式
  1. 消息队列如果在application.properties中配置的话,只能支持点对点模式和订阅模式的一种,如何实现两种模式同时支持呢?
  2. 默认消费者并不会消费订阅发布类型的消息,这是由于springBoot默认采用的是p2p模式,进行消息的监听,需要修改配置。
  3. @JmsListener如果不指定独立的containerFactory的话,只能消费queue消息。消费者修改container:containerFactory="jmsListenerContainerTopic"需要给topic定义独立的JmsListenerContainer
@Bean
public JmsListenerContainerFactory<?> jmsListenerContainerTopic(ConnectionFactory activeMQConnectionFactory) {
    DefaultJmsListenerContainerFactory bean = new DefaultJmsListenerContainerFactory();
    bean.setPubSubDomain(true);
    bean.setConnectionFactory(activeMQConnectionFactory);
    return bean;
}

  1. 消费者需要添加独立的containerFactory,否则只会支持queue默认的点对点模式。
@JmsListener(destination="video.topic", containerFactory="jmsListenerContainerTopic")
public void receive1(String text){
    System.out.println("video.topic 消费者:receive1="+text);
}

你可能感兴趣的:(springBoot学习笔记)