activemq的使用场景

一、消息队列概述
消息队列中间件是分布式系统中重要的组件,主要解决应用耦合,异步消息,流量削锋等问题。实现高性能,高可用,可伸缩和最终一致性架构。是大型分布式系统不可缺少的中间件。

目前在生产环境,使用较多的消息队列有ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ等。

二、消息队列应用场景
以下介绍消息队列在实际应用中常用的使用场景。异步处理,应用解耦,流量削锋和消息通讯四个场景。本篇使用ActiveMQ+SpringBoot来模拟这四个场景。

2.1异步处理
场景说明:汽车触发围栏报警后,需要发送报警邮件和报警短信。传统的做法有两种1.串行的方式;2.并行方式。

(1)串行方式:将报警信息写入数据库成功后,发送报警邮件,再发送报警短信。以上三个任务全部完成后,该报警信息加入统计列表。
在这里插入图片描述
(2)并行方式:报警信息写入数据库成功后,同时发送报警邮件和短信。
在这里插入图片描述
假设三个业务节点每个使用50毫秒钟,不考虑网络等其他开销,则串行方式的时间是150毫秒,并行的时间可能是100毫秒。

因为CPU在单位时间内处理的请求数是一定的,假设CPU1秒内吞吐量是100次。则串行方式1秒内CPU可处理的请求量是7次(1000/150)。并行方式处理的请求量是10次(1000/100)。

小结:如以上案例描述,传统的方式系统的性能(并发量,吞吐量,响应时间)会有瓶颈。如何解决这个问题呢?

引入消息队列,将不是必须的业务逻辑,异步处理。改造后的架构如下:
在这里插入图片描述
代码示例

①在pom文件中引入activemq依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-activemq</artifactId><version>1.5.6.RELEASE</version></dependency>

②在配置文件中加上activemq的配置

spring.activemq.broker-url=tcp://127.0.0.1:61616
# 在考虑结束之前等待的时间
#spring.activemq.close-timeout=15s 
# 默认代理URL是否应该在内存中。如果指定了显式代理,则忽略此值。
spring.activemq.in-memory=true 
# 是否在回滚回滚消息之前停止消息传递。这意味着当启用此命令时,消息顺序不会被保留。
spring.activemq.non-blocking-redelivery=false
# 密码
spring.activemq.password=123456
# 等待消息发送响应的时间。设置为0等待永远。
spring.activemq.send-timeout=0
spring.activemq.user=haha
# 是否信任所有包
#spring.activemq.packages.trust-all=
# 要信任的特定包的逗号分隔列表(当不信任所有包时)
#spring.activemq.packages.trusted=
# 当连接请求和池满时是否阻塞。设置false会抛“JMSException异常”。
#spring.activemq.pool.block-if-full=true
# 如果池仍然满,则在抛出异常前阻塞时间。
#spring.activemq.pool.block-if-full-timeout=-1ms
# 是否在启动时创建连接。可以在启动时用于加热池。
#spring.activemq.pool.create-connection-on-startup=true
# 是否用Pooledconnectionfactory代替普通的ConnectionFactory。
#spring.activemq.pool.enabled=false 
# 连接过期超时。
#spring.activemq.pool.expiry-timeout=0ms
# 连接空闲超时
#spring.activemq.pool.idle-timeout=30s
# 连接池最大连接数
#spring.activemq.pool.max-connections=1
# 每个连接的有效会话的最大数目。
#spring.activemq.pool.maximum-active-session-per-connection=500
# 当有"JMSException"时尝试重新连接
#spring.activemq.pool.reconnect-on-exception=true
# 在空闲连接清除线程之间运行的时间。当为负数时,没有空闲连接驱逐线程运行。
#spring.activemq.pool.time-between-expiration-check=-1ms
# 是否只使用一个MessageProducer
#spring.activemq.pool.use-anonymous-producers=true

③消息生产者

import java.util.Map;import javax.jms.Destination;
import javax.jms.Queue;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessagePostProcessor;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;/*** 报警消息Producer* @author ko**/
@Component
//@EnableScheduling
public class AlarmProducer {// 也可以注入JmsTemplate,JmsMessagingTemplate对JmsTemplate进行了封装@Autowiredprivate JmsTemplate jmsTemplate;
//    private JmsMessagingTemplate jmsTemplate;//    @Autowired
//    private Queue queue;//    @Scheduled(fixedDelay=5000) // 5s执行一次   只有无参的方法才能用该注解public void sendMessage(Destination destination, String message){
//        jmsTemplate.convertAndSend(destinationName, payload, messagePostProcessor);this.jmsTemplate.convertAndSend(destination, message);}// 双向队列// @JmsListener(destination="out.queue") //   public void consumerMessage(String text){  //   System.out.println("从out.queue队列收到的回复报文为:"+text);  // }
}

⑤controller里写上测试接口

@Autowiredprivate AlarmProducer alarmProducer;@RequestMapping(value="/chufabaojing",method=RequestMethod.GET)@ApiOperation(value="触发报警", notes="触发报警")@ApiImplicitParams({@ApiImplicitParam(name = "devicename", value = "name",example = "xxxx", required = true, dataType = "string",paramType="query"),})public String chufabaojing(String devicename){List<String> alarmStrList = new ArrayList<>();alarmStrList.add(devicename+"out fence01");alarmStrList.add(devicename+"out fence02");alarmStrList.add(devicename+"in fence01");alarmStrList.add(devicename+"in fence02");System.out.println("设备"+devicename+"出围栏报警");// 报警信息写入数据库System.out.println("报警数据写入数据库。。。");// 写入消息队列Destination destination = new ActiveMQQueue("mytest.queue");for (String alarmStr : alarmStrList) {alarmProducer.sendMessage(destination, alarmStr);}// 消息写进消息队列里就不管了// 下面两步骤移到activemq消费者里// 发送邮件// 发送短信return "success";}

2.2 应用解耦
场景介绍,在spring cloud分布式微服务项目中,工单管理和设备管理分别是两个微服务,如果A工单被张三接单了,那么工单状态要设为已派单,检验员设为张三,设备状态要置为在检。

传统的做法是,先调用工单管理的工单更新接口,成功之后再调用设备管理的设备更新接口,成功之后再返回操作提示给用户。这样做的缺点是应用耦合,如果在派单操作的时候正好设备管理微服务挂了或者阻塞了,那么派单操作就会失败或者要等待很长时间无反馈。另外如果设备管理的接口有变动,那么工单管理里面的代码也要改动。
在这里插入图片描述
引入消息中间件,派单的时候,工单管理的工单更新接口处理好后把信息写入消息队列,然后直接返回操作反馈给用户。不管工单管理服务正不正常,正常就从消息队列里订阅消息处理,不正常就等待回复正常后再订阅消息处理。
在这里插入图片描述
2.3 流量削峰
场景介绍,XX公司的系统原来是针对A地区的客户开发的,现在为了抢占市场,拿下了B和C两个地区的客户,那么新系统上线,就存在如何把B和C的基础数据导入XX公司的系统中来的问题,短时间内要把庞大的旧数据改造适合新系统再导入进来,这很容易使系统挂掉,另外每天还有增量数据产生。

这时可以引入消息中间件,B和C的客户只要负责把数据规则放到消息队列里就好了,XX公司可以有条不紊的从消息队列里订阅数据,可以有效缓解短时间内的高流量压力,但是这也对消息中间件的可靠性提出了要求。

如果遇到activemq的瓶颈,可以看看activemq集群方案,这篇文章 http://blog.csdn.net/shuangzh115/article/details/50989182

2.4 点对点通讯
类似聊天室的功能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/249732.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

复习JavaScript随手记

数据类型 基本类型 stringnumberbooleanundefinednumber类型,包含整数浮点数 NaN和自己都不相等,涉及NaN的计算结果都是NaN isNaN()函数用于判断一个数是不是NaN 引用类型 object类型 function类型 继承自object object类型定义了prototype属性 可以通过它动态给对象绑定方法和…

TP5在前端时间戳转换为时间格式

value"{:date(Y-m-d H:i:s,$data[add_date])}" 例如&#xff1a; <td>{:date(Y-m-d H:i:s,$d[create_time])}</td> 转载于:https://www.cnblogs.com/shark1100913/p/9468077.html

Java(发布/订阅模式)

1、概述 观察者模式又称为发布/订阅(Publish/Subscribe)模式 观察者设计模式涉及到两种角色&#xff1a;主题&#xff08;Subject&#xff09;和观察者&#xff08;Observer&#xff09; &#xff08;1&#xff09;Subject模块 Subjec模块有3个主要操作 addObserver()&#…

VUE $SET源码

转载于:https://www.cnblogs.com/smzd/p/11634255.html

JS 日期格式化

1、将中国标准时间格式化为&#xff08;2017-06-06 15:05:04&#xff09; function formatDateTime(theDate) { var _hour theDate.getHours(); var _minute theDate.getMinutes(); var _second theDate.getSeconds(); var _year theDate.getFullYear() var _month theDat…

canvas 入门

<canvas>是HTML5新增的&#xff0c;是可以使用脚本&#xff08;JavaScript&#xff09;在其中绘制图像的HTML元素。 canvas是由HTML代码配合高度和宽度属性而定义出的可绘制区域&#xff0c;JavaScript代码可访问该区域&#xff0c;类似于其它通用的二维API&#xff0c;通…

Java实现消息队列服务

使用 JAVA 语言自己动手来写一个MQ (类似ActiveMQ,RabbitMQ) 主要角色 首先我们必须需要搞明白 MQ (消息队列) 中的三个基本角色 ProducerBrokerConsumer 整体架构如下所示 自定义协议 首先从上一篇中介绍了协议的相关信息,具体厂商的 MQ(消息队列) 需要遵循某种协议或者…

Knockout中ko.utils中处理数组的方法集合

每一套框架基本上都会有一个工具类&#xff0c;如&#xff1a;Vue中的Vue.util、Knockout中的ko.utils、jQuery直接将一些工具类放到了$里面&#xff0c;如果你还需要更多的工具类可以试试lodash。本文只介绍一下Knockout中ko.utils中处理数组的一些方法。 ko.utils.arrayForEa…

$nextTick 源码

x现在没时间&#xff0c;留个坑 转载于:https://www.cnblogs.com/smzd/p/11634665.html

java 发布订阅

1.发布者接口 package com.yy.subpub; /** * Description: 发布者接口 * author: leijing * date: 2016年9月29日 下午5:07:20 */ public interface IPublisher<M> { /** * Description: 向订阅器发布消息 * param subscribePublish 订阅器 * param message 消息 * para…

.NET Core Session的简单使用

前言 在之前的.NET 里&#xff0c;我们可以很容易的使用Session读取值。那今天我们来看看 如何在.NET Core中读取Session值呢&#xff1f; Session 使用Session之前&#xff0c;我们需要到Startup.cs中配置我们的服务如下&#xff1a; ①在ConfigureServices中加入&#xff1a;…

EasyNVR内网摄像机接入网关+EasyNVS云端管理平台,组件起一套轻量级类似于企业级萤石云的解决方案...

背景分析 对于EasyNVR我们应该都了解&#xff0c;主要应用于互联安防直播&#xff0c;对于EasyNVR&#xff0c;我们可以清楚的发现&#xff0c;EasyNVR的工作机制是EasyNVR拉取摄像机的RTSP/Onvif视频流&#xff0c;然后客户端可以通过访问EasyNVR服务端实现流分发&#xff0c;…

java.util.Queue用法

队列是一种特殊的线性表&#xff0c;它只允许在表的前端&#xff08;front&#xff09;进行删除操作&#xff0c;而在表的后端&#xff08;rear&#xff09;进行插入操作。进行插入操作的端称为队尾&#xff0c;进行删除操作的端称为队头。队列中没有元素时&#xff0c;称为空队…

Vim删除文件到行首或者行尾

vim用的不是很熟练&#xff0c;只是有时候需要的时候会学习一下 我们知道&#xff0c;vim有三种模式&#xff0c;一种是一般模式&#xff0c;一种是编辑模式&#xff0c;另外一种是命令行模式 在一般模式下&#xff0c;可以进行删除&#xff0c;复制粘贴等操作&#xff0c;在编…

新版本微信导致的ios表单bug

解决方法如下&#xff1a; $(document).delegate(input, textarea, select, blur, function(){setTimeout(function(){$(html).animate({height: 100.1vh}, 100, function(){$(this).animate({height: 100vh}, 1)})},100); }); 转载于:https://www.cnblogs.com/qdlhj/p/1033676…

Golang的值类型和引用类型的范围、存储区域、区别

常见的值类型和引用类型分别有哪些&#xff1f; 值类型&#xff1a;基本数据类型 int 系列, float 系列, bool, string 、数组和结构体struct&#xff0c;使用这些类型的变量直接指向存在内存中的值&#xff0c;值类型的变量的值通常存储在栈中。 引用类型&#xff1a;指针、sl…

python3之time模块

时间戳1: import time2: print(time.time()) 可读的时间格式1: import time2: print(time.ctime())3: later time.time() 6004: print(time.ctime(later)) 结果1: Wed Jan 30 17:11:49 20192: Wed Jan 30 17:21:49 2019 暂停程序(进程或者线程)1: time.sleep(secs) 计时时钟1…

网络规划设计(项目类业务)

前期准备&#xff1a;找经开部要到当地的现场结构图 1.和通信段约好时间&#xff0c;实地跑一趟&#xff0c;找到光缆、电缆的原汇聚点。 2.与车间人员沟通&#xff0c;看是否要迁汇聚点&#xff0c;倘若迁汇聚点&#xff0c;迁到哪里。 3.怎么从光缆/电缆的旧址迁到新址&#…

RPC框架实现原理

一、什么是RPC框架&#xff1f; RPC&#xff0c;全称为Remote Procedure Call&#xff0c;即远程过程调用&#xff0c;是一种计算机通信协议。 比如现在有两台机器&#xff1a;A机器和B机器&#xff0c;并且分别部署了应用A和应用B。假设此时位于A机器上的A应用想要调用位于B机…

jQuery安装

http://www.runoob.com/jquery/jquery-install.html 网页中添加jQuery&#xff1a; 方法一&#xff1a;可以从http://jquery.com/download/ 下载jQuery库 方法二&#xff1a;从CDN中载入jQuery 下载 jQuery 有两个版本的 jQuery 可供下载&#xff1a; Production version - 用于…