当前位置: 首页 > news >正文

Spring Cloud Alibaba--ActiveMQ微服务详解之消息队列(四)

        上篇讲述高并发情况下的数据库处理方式:分布式事务管理机制。即使我们做到这一步并发情况只能稍微得到缓解,当然千万级别的问题不大,但在面对双十一淘宝这类的达上亿的并发的时候仅仅靠分布式事务管理还是远远不够,即使数据库可以抗住压力,但从前端访问上并不能根本解决数据库可重复读的问题。

        解决并发问题的方式很多单都无法彻底解决并发问题,因为并发问题以现有的技术无法解决,但我们可以尽可能的使系统无线扩大并发量以达到完全处理并发的效果,限流、熔断都是不错的选择,但会出现系统无法访问的情况,当并发进入到系统的时候直接处理业务功能显然不合适,如果把并发进行队列化操作显然更加合适公平。举个栗子,做核酸检测的医护人员就几个而做核酸检测的人却多的数不过来,如果这些人一块围着谁也做不了核酸,此时排队等待是最适合的先到先排先做。MQ就是维持秩序的管理员,将并发进行排队。

1、MQ介绍

        当今市面上有很多主流的消息中间件,如老牌的ActiveMQ、RabbitMQ,炙手可热的Kafka,阿里巴巴自主开发的Notify、MetaQ、RocketMQ等。

        本文使用ActiveMQ,无论哪种MQ技术都会涉及到消息的存储性、可靠性、传递性等,基本属性都会包含消息生产者、消费者两部分,推送方式一般为订阅广播、点对点的方式。字面意思广播就是通过网络广播发送消息,MQ不关注接收方是否在线,点对点是A端到B端双方进行握手通信后再传输数据。两者比较广播效率更高,但数据丢失率也高,数据安全性低,点对点传输效率相对广播低、数据丢失率低、如果B端掉线消息可以做持久化存储,等待B端上线握手后再次发送。

2、windows系统MQ服务部署

        官网:https://activemq.apache.org/

        官网提供两个版本的MQ供下载,Classic版本为当前稳定版本,Artemis版本为下代版本本文使用Classic版本。下载windows版本的压缩包ActiveMQ 5.16.5.zip。各版本的MQ对应Java JDK版本要看清楚。

        下载完成后解压zip,进入到MQ文件夹下如下:

         进入bin目录下,根据系统选择32位或者64位进入文件夹,运行activemq.bat脚本。

        本地访问http://localhost:8161账号/密码为admin

        点击进入管理界面,至此MQ服务启动成功。消息管理中心有Queues,Topics,Subscribers等我们可以查看队列、订阅等信息。

        Topics:是基于“订阅-发布”模式,当操作者发布一条消息后,所有对这条消息感兴趣的订阅者都可以收到它——也就是说这条消息会被拷贝成多份,进行分发。只有当前“活动的”订阅者能够收到消息。

        Queues:是一种“负载均衡模式”的实现。一个消息能且只能被一个消费者接受。如果当前JMS-Queue中没有任何的消费者,那么这条消息将会被Queue存储起来(实际应用中可以存储在磁盘上,也可以存储在数据库中,看软件的配置),直到有一个消费者连接上。另外,如果消费者在接受到消息后,在他断开与JMS-Queue连接之前,没有发送ack信息(可以是客户端手动发送,也可以是自动发送),那么这条消息将被发送给其他消费者。

比较项目Topic 模式队列Queue 模式队列
工作模式“订阅-发布”模式,如果当前没有订阅者,消息将会被丢弃。如果有多个订阅者,那么这些订阅者都会收到消息“负载均衡”模式,如果当前没有消费者,消息也不会丢弃;如果有多个消费者,那么一条消息也只会发送给其中一个消费者,并且要求消费者ack信息。
有无状态无状态Queue数据默认会在mq服务器上以文件形式保存,比如Active MQ一般保存在$AMQ_HOME\data\kr-store\data下面。也可以配置成DB存储。
传递完整性如果没有订阅者,消息会被丢弃消息不会丢弃
处理效率由于消息要按照订阅者的数量进行复制,所以处理性能会随着订阅者的增加而明显降低,并且还要结合不同消息协议自身的性能差异由于一条消息只发送给一个消费者,所以就算消费者再多,性能也不会有明显降低。当然不同消息协议的具体性能也是有差异的

3、系统集成

        服务启动后我们需要在系统中集成MQ并进行收发消息测试,在父工程下创建MQ子工程。在子工程pom中添加MQ依赖。

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
<dependency><groupId>org.apache.activemq</groupId><artifactId>activemq-pool</artifactId>
</dependency>

        在启动类上添加注解@EnableJms。

在需要使用MQ进行业务处理的服务中依赖MQ服务,并添加MQ配置信息:

server:port: 8081
spring:activemq:broker-url: tcp://127.0.0.1:61616user: adminpassword: adminjms:pub-sub-domain: true # 默认为false,点对点模式queue  true订阅模式topicpool:enabled: false # 是否创建 JmsPoolConnectionFactory 连接池idle-timeout: 30s # 空闲连接超时时间max-connections: 50 # 连接池中最大连接数max-sessions-per-connection: 100 # 每个连接最大会话

        编写MQ配置类:

@Configuration
public class BeanConfig {@Value("${spring.activemq.broker-url}")private String brokerUrl;@Value("${spring.activemq.user}")private String userName;@Value("${spring.activemq.password}")private String password;//定义存放消息的队列@Beanpublic ActiveMQQueue queue() {return new ActiveMQQueue("MyQueue");}@Beanpublic ActiveMQTopic topic() {return new ActiveMQTopic("MyTopic");}@Beanpublic ConnectionFactory connectionFactory() {return new ActiveMQConnectionFactory(userName, password, brokerUrl);}/*** 在 Queue 模式中,对消息的监听需要对containerFactory进行配置*/@Bean("queueListener")public JmsListenerContainerFactory<?> queueJmsListenerContainerFactory(ConnectionFactory connectionFactory) {SimpleJmsListenerContainerFactory factory = new SimpleJmsListenerContainerFactory();factory.setConnectionFactory(connectionFactory);factory.setPubSubDomain(false);return factory;}/*** 在 topic 模式中,对消息的监听需要对containerFactory进行配置*/@Bean("topicListener")public JmsListenerContainerFactory<?> topicJmsListenerContainerFactory(ConnectionFactory connectionFactory) {SimpleJmsListenerContainerFactory factory = new SimpleJmsListenerContainerFactory();factory.setConnectionFactory(connectionFactory);factory.setPubSubDomain(true);return factory;}
}

        编写Queue监听类和Topic监听类:

@Component
public class MyQueueListener {@JmsListener(destination = "MyQueue", containerFactory="queueListener")public void handleMessage(String name) {System.err.println(name);}}

 

@Component
public class MyTopicListener {@JmsListener(destination = "MyTopic", containerFactory="topicListener")public String handleMessage1(String name) {System.out.println("topic 成功接受Name" + name);}
}

        编写消息发送接口 :


@Controller
@RestController("/demo")
public class Demo {@Autowiredprivate Queue queue;@Autowiredprivate JmsMessagingTemplate jmsMessagingTemplate;/*** 发送消息接口* @param msg*/@GetMapping("/{msg}")void demo(@PathVariable String msg) {// 消息入队列jmsMessagingTemplate.convertAndSend(queue, msg);}}

         访问接口传入消息参数:

         

        可以看到控制台打印输出消息内容。至此系统集成MQ完成。

 

http://www.lryc.cn/news/13997.html

相关文章:

  • 32岁,薪水被应届生倒挂,裸辞了
  • 蓝桥杯训练day1
  • Unity毛发系统TressFX Exporter
  • 《爆肝整理》保姆级系列教程python接口自动化(十九)--Json 数据处理---实战(详解)
  • Golang:reflect反射的使用例子
  • markdown常用语法--花括号(超详细)
  • BN、SyncBN、IN、LN、GN学习记录
  • 使用 Auto-scheduling 优化算子
  • 智能运维应用之道,告别企业数字化转型危机
  • 第七章 SQL错误信息 - SQL错误代码 -400 到 -500
  • DDFN: Decoupled Dynamic Filter Networks解耦的动态卷积
  • NISP认证报名条件是什么?考试内容是什么?
  • 利用redis实现缓存、发布订阅、分布式锁功能
  • SVN无法连接到服务器的各种问题原因及解决办法
  • React 基本使用
  • 单例模式设计(面试题)
  • 机器学习:基于支持向量机(SVM)进行人脸识别预测
  • 【服务器数据恢复】多块磁盘离线导致RAIDZ崩溃的数据恢复案例
  • iconfont 图标如何在uniapp中的tabBar使用
  • 第六章.卷积神经网络(CNN)—卷积层(Convolution)池化层(Pooling)
  • c/c++开发,无可避免的模板编程实践(篇六)
  • 【Java】Spring核心与设计思想
  • 组合实现多类别分割(含实战代码)
  • 从红队视角看AWD攻击
  • 龙腾万里,福至万家——“北京龙文化促进协会第九届龙抬头传承会”在京举办
  • 《软件方法》强化自测题-业务建模(4)
  • Prometheus之pushgateway
  • 3分钟带您快速了解HIL测试及其架构
  • 华为认证含金量如何?
  • 刷题记录:牛客NC54586小翔和泰拉瑞亚