ActiveMQ入门介绍与整合SpringBoot使用

先说说JMS

消息队列的JAVAEE规范JMS 。JMS(Java Message Service,java消息服务)API是一个消息服务的标准/规范,允许应用程序组件基于JavaEE平台创建、发送、接收和读取消息。它使分布式通信耦合度更低,消息服务更加可靠以及异步性。

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创建的

ActiveMQ说明

MQ是消息中间件,是一种在分布式系统中应用程序借以传递消息的媒介,常用的有ActiveMQ,RabbitMQ,kafka。ActiveMQ是Apache下的开源项目,完全支持JMS1.1和J2EE1.4规范的JMS Provider实现。
ActiveMQ是一种开源的基于JMS(Java Message Servie)规范的一种消息中间件的实现,ActiveMQ的设计目标是提供标准的,面向消息的,能够跨越多语言和多系统的应用集成消息通信中间件。
ActiveMQ常被应用与系统业务的解耦,异步消息的推送,增加系统并发量,提高用户体验。例如以我在工作中的使用,在比较耗时且异步的远程开锁操作时

ActiveMQ有两种消息传递类型
  • 点对点传输(PTP),即一个生产者对应一个消费者,生产者向broke推送数据,数据存储在broke的一个队列中,当消费者接受该条队列里的数据。
    • 一个消息只能被一个消费者消费,不可重复消费
    • 多个消费者均分消息(负载均衡策略)
    • 发送者和接收者之间在时间上没有依赖性,也就是说当发送者发送了消息之后,不管接收者有没有正在运行,它不会影响到消息被发送到队列
    • 当消费者在消费某个消息的时候,mq一定要等到它的成功回执,才会分发下一个消息
    • queue入队之后,无论等待多久,消息都会一直等待消费者来处理
    • 如果希望发送的每个消息都会被成功处理的话,那么需要P2P模式。
  • 基于发布/订阅模式的传输(Topic),即根据订阅话题来接收相应数据,一个生产者可向多个消费者推送数据。
    • 发布者和订阅者之间有时间上的依赖性。针对某个主题(Topic)的订阅者,它必须创建一个订阅者之后,才能消费发布者的消息
    • 为了消费消息,订阅者必须保持运行的状态

ActiveMQ应用场景

  1. 异步处理:用户注册后储存数据库,发送短信,发送邮件。使用ActiveMQ提高速度,存入数据库后信息写入消息队列后直接返回,异步发送短息发送邮件。
  2. 应用程序解耦:用户下单后,订单系统需要通知库存系统。传统的做法是,订单系统调用库存系统的接口,假如库存系统无法访问,则订单减库存将失败,从而导致订单失败,订单系统与库存系统耦合。使用ActiveMQ,用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户订单下单成功。库存系统订阅下单的消息,采用pub/sub(发布/订阅)的方式,获取下单信息,库存系统根据下单信息,进行库存操作。假如:在下单时库存系统不能正常使用。也不影响正常下单,因为下单后,订单系统写入消息队列就不再关心其他的后续操作了。实现订单系统与库存系统的应用解耦
  3. 流量削锋:流量削锋也是消息队列中的常用场景,一般在秒杀或团抢活动中使用广泛。秒杀活动,一般会因为流量过大,导致流量暴增,应用挂掉。为解决这个问题,一般需要在应用前端加入消息队列。1.可以控制活动的人数。2.可以缓解短时间内高流量压垮应用。
    用户的请求,服务器接收后,首先写入消息队列。假如消息队列长度超过最大数量,则直接抛弃用户请求或跳转到错误页面,秒杀业务根据消息队列中的请求信息,再做后续处理。
  4. 日志处理:日志采集客户端将日志写入消息队列,日志分析客户端监听消息进行处理
  5. 消息通讯:消息通讯是指,消息队列一般都内置了高效的通信机制,因此也可以用在纯的消息通讯。比如实现点对点消息队列,或者聊天室等。

ActiveMQ整合Springboot

  1. 下载ActiveMQ
    http://activemq.apache.org/download-archives.html
    启动后登陆地址: http://localhost:8161/admin(用户名和密码默认为admin)

  2. maven导包
    <spring-boot.version>2.2.7.RELEASE</spring-boot.version>
    <pooled-jms.version>1.0.4</pooled-jms.version>
    使用springboot2.1+时候,maven配置依赖是:

		<!--activeMQ starter-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-activemq</artifactId>
		</dependency>
		<!--mq连接池-->
		<dependency>
			<groupId>org.messaginghub</groupId>
			<artifactId>pooled-jms</artifactId>
		</dependency>

使用springboot2.0+及以下版本时候,maven配置依赖是:

<dependency>
    <groupId>org.apache.activemq</groupId>
    <artifactId>activemq-pool</artifactId>
</dependency>
  1. 配置application.yml
spring:
  activemq:
    broker-url: tcp://localhost:61616
    #true 表示使用内置的MQ,false则连接服务器
    in-memory: false
    pool:
      #true表示使用连接池;false时,每发送一条数据创建一个连接
      enabled: true
      #连接池最大连接数
      max-connections: 10
      #空闲的连接过期时间,默认为30秒
      idle-timeout: 30000
  1. 配置Queue
    @EnableJms必须有,加到启动类上也可以
@EnableJms
@Configuration
public class MqConfiguration {
    @Bean
    public Queue getQueue(){
        return new ActiveMQQueue("ActiveMQQueue");
    }
    @Bean
    public Topic topic() {
        return new ActiveMQTopic("ActiveMQTopic");
    }
}
  1. 提供消息

@RestController
@RequestMapping("/email")
public class EmailController {
    @Autowired
    private Queue emailQueue;
    @Autowired
    private JmsMessagingTemplate jmsMessageTemplate;

    @PostMapping("/sendMessage/{userid}")
    public ResponseEntity<String> sendMessage(@PathVariable("userid") String userid){
        
        MapMessage mapMessage = new ActiveMQMapMessage();
        try {
            mapMessage.setString("userid", userid);
        } catch (JMSException e) {
            e.printStackTrace();
        }
        //方法一:添加消息到消息队列
        jmsMessageTemplate.convertAndSend(emailQueue, mapMessage);
        //方法二:这种方式不需要手动创建queue,系统会自行创建名为test的队列
        //jmsMessageTemplate.convertAndSend("test", name);
        return new ResponseEntity<String>(HttpStatus.OK);
    }
}
  1. 消费消息 在customer端
@Service
public class EmailService {
    @Autowired
    private JmsMessagingTemplate jmsMessagingTemplate;

    // 使用JmsListener配置消费者监听的队列,其中name是接收到的消息
    @JmsListener(destination = "ActiveMQQueue")
    // SendTo 会将此方法返回的数据, 写入到 OutQueue 中去.
    @SendTo("SQueue")
    public String handleMessage(MapMessage message) {
    	MapMessage mapMessage = (MapMessage) message;
        String name = mapMessage.getString("userid");
        System.out.println("成功接受Name" + name);
        return "成功接受Name" + name;
    }

}

实际项目中的使用

合同管理系统提交合同后将信息保存到DB,然后向MQ发送json,托管人平台监听到MQ消息后将产品预发行信息储存起来,邮件系统监听MQ后发送邮件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值