消息队列MQ

MQ概述

1.MQ简介

MQ,Message Queue,是一种提供消息队列服务的中间件,也称为消息中间件,是一套提供了消息生产、储、消费全过程API的软件系统。消息即数据。一般消息的体量不会很大。

2.MQ用途

限流削峰

MQ可以将系统的超量请求暂存其中,以便系统后期可以慢慢进行处理,从而避免了请求的丢失或系统被压垮。

异步解耦

上游系统对下游系统的调用若为同步调用,则会大大降低系统的吞吐量与并发度,且系统耦合度

太高。而异步调用则会解决这些问题。所以两层之间若要实现由同步到异步的转化,一般性做法就是,在这两层间添加一个MQ层。

数据收集

分布式系统会产生海量级数据流,如:业务日志、监控数据、用户行为等。针对这些数据流进行实时或批量采集汇总,然后对这些数据流进行大数据分析,这是当前互联网平台的必备技术通过MQ完成比类数据收集是最好的选择。


3.常见的MQ产品

ActiveMQ

ActiveMQ是使用Java语言开发一款MQ产品。早期很多公司与项目中都在使用。但现在的社区活跃度已经很低。现在的项目中已经很少使用了。


RabbitMQ

RabbitMQ是使用ErLang语言开发的一款MQ产品。其吞吐量较Kafka与RocketMQ要低,且由于其不是Java语言开发,所以公司内部对其实现定制化开发难度较大。


Kafka

Kafka是使用Scala/Java语言开发的一款MQ产品。其最大的特点就是高吞吐率,常用于大数据领域的实时计算、日志采集等场景。其没有遵循任何常见的MQ协议,而是使用自研协议。对于Spring CloudNetcix,其仅支持RabbitMq与Kafka.


RocketMQ

RocketMQ是使用Java语言开发的一款MQ产品。经过数年阿里双 11 的考验,性能与稳定性非常高。其没有遵循任何常见的MQ协议,而是使用自研协议。对于Spring Cloud Alibaba,其支持RabbitMQ、Kafka,但提倡使用RocketMQ.



RocketMQ的安装与启动

下载与安装

1.下载RocketMQ

https://rocketmq.apache.org/download/

2.windows下解压安装,配置环境变量ROCKETMQ_HOME

注意路径不要有中文或者空格等特殊字符


RocketMQ部署

1.启动nameserver

鼠标双击执行bin目录下的mqnamesrv.cmd 文件 或者 cmd 打开控制台,切换目录到rocket的bin目录下,执行命令:

start mqnamesrv.cmd

注:如果出现"找不到主类"的问题,需要将ROCKMQ_HOME和JAVA _HOME两个变量路径改掉,换成没有空格的路径


2.启动broker

执行bin目录下的 mqbroker.cmd 文件 或者 cmd 打开控制台,切换到bin目录下,执行命令:

start mqbroker.cmd -n 127.0.0.1:9876 autoCreateTopicEnable=true

默认端口是9876,autocreateTopicEnable=true表示允许自动创建topic

注:rocketMq运行环境中的内存不足会导致启动失败,可以修改配置文件

runserver.sh/runserver.cmd,runbroker.sh/runbroker.cmd中的配置参数


3.RocketMQ插件安装

访问 https://github.com/apache/rocketmq-externals/tags

下载rocketmq-console-1.0.0,并解压

在Eclipse中导入项目:

修改pom.xml文件中的java环境为当前环境1.8并执行compile指令

构建成功

在application.properties中设置地址namesrvAddr为localhost:9876

右键项目更新Maven

通过启动类App.java启动

在浏览器中打开


这里可以通过下面的指令将项目打包为jar包,失败可以尝试使用管理员身份运行

clean package -Dmaven.test.skip=true

打包成功后刷新项目可以在target文件夹下看到刚生成的jar包

此时复制jar包到到工作文件夹下通过cmd可以直接启动项目

java -jar rocketmq-console-ng-1.0.0.jar

同样可以在浏览器中打开


在bin目录下通过cmd输入指令mqadmin

mqadmin是一个命令行工具,用于管理Apache RocketMQ消息队列系统。它提供了一组命令,用于创建、删除、查询和管理消息队列和主题,以及监控和诊断RocketMQ集群的状态和性能。


基本概念

消息(Message)

消息是指,消息系统所传输信息的物理载体,生产和消费数据的最小单位,每条消息必须属于个主题。

主题(Topic)

Topic表示一类消息的集合,每个主题包含若干条消息,每条消息只能属于一个主题,是RocketMQ进行消息订阅的基本单位。topic:message 1:n message:topic 1:1

一个生产者可以同时发送多种Topic的消息;而一个消费者只对某种特定的Topic感兴趣,只可以订阅和消费一种Topic的消息。producer:topic 1:n consumer:topic 1:1

标签(Tag)

为消息设置的标签,用于同一主题下区分不同类型的消息。来自同一业务单元的消息,可以根据不同业务目的在同一主题下设置不同标签。标签能够有效地保持代码的清晰度和连贯性,并优化RocketMQ提供的查询系统。消费者可以根据Tag实现对不同子主题的不同消费逻辑,实现更好的扩展性。

Topic是消息的一级分类,Tag是消息的二级分类。

队列(Queue)

存储消息的物理实体。一个Topic中可以包含多个Queue,每个Queue中存放的就是该Topic的消息。一个Topic的Queue也被称为一个Topic中消息的分区(Partition)。

一个Topic的Queue中的消息只能被一个消费者组中的一个消费者消费。一个Queue中的消息不允
许同一个消费者组中的多个消费者同时消费

消息标识(MessageId/Key)

RocketMQ中每个消息拥有唯一的MessageId,且可以携带具有业务标识的Key,以方便对消息的查询。

不过需要注意的是,MessageId有两个:在生产者send()消息时会自动生成一个Messaged(msgId),当消息到达Broker后,Broker也会自动生成一个Messageld(offsetMsgId)。

msgId、offsetMsgId与key都称为消息标识。

  • msgId:由producer端生成,其生成规则为:producerIp+进程pid+MessageClientIDSetter类的ClassLoader的hashCode +当前时间+AutomicInteger自增计数器
  • offsetMsgId:由broker端生成,其生成规则为:brokerIp+物理分区的offset(Queue中的偏移量)
  • key:由用户指定的业务相关的唯一标识

发送消息

同步发送

1.新建Maven项目并在pom.xml中导入依赖

XML 复制代码
	<!-- https://mvnrepository.com/artifact/org.apache.rocketmq/rocketmq-client -->
	<dependency>
	    <groupId>org.apache.rocketmq</groupId>
	    <artifactId>rocketmq-client</artifactId>
	    <version>5.3.0</version>
	</dependency>

2.创建测试类同步发送消息

java 复制代码
public class EasyA {
    public static void main(String[] args) throws MQClientException, MQBrokerException, RemotingException, InterruptedException {
        DefaultMQProducer producer = new DefaultMQProducer("easygroup");

        producer.setNamesrvAddr("127.0.0.1:9876");
        producer.start();

        //发送消息
        Message message = new Message("easytopic","rocketmq message".getBytes());
        SendResult result = producer.send(message);
        System.out.println(result);
        
        producer.shutdown();
    }
}

发送成功,在RocketMQ中,默认情况下一个Topic会创建4个队列。


异步发送

java 复制代码
public class EasyB {
    public static void main(String[] args) throws MQClientException, RemotingException, InterruptedException {
        DefaultMQProducer producer=new DefaultMQProducer("easygroup");

        producer.setNamesrvAddr("127.0.0.1:9876");

        Message message=new Message("easytopic","Helloworld".getBytes());

        producer.start();

        producer.send(message, new SendCallback() {
            @Override
            public void onSuccess(SendResult sendResult) {
                System.out.println(sendResult);
                System.out.println("OK");
            }
            @Override
            public void onException(Throwable e) {
                e.printStackTrace();
                System.out.println("Error");
            }
        });

        System.out.println("发送了一个消息");
        Thread.sleep(3000);
        producer.shutdown();
    }
}
相关推荐
k09338 分钟前
sourceTree回滚版本到某次提交
开发语言·前端·javascript
激流丶14 分钟前
【Kafka 实战】如何解决Kafka Topic数量过多带来的性能问题?
java·大数据·kafka·topic
神奇夜光杯15 分钟前
Python酷库之旅-第三方库Pandas(202)
开发语言·人工智能·python·excel·pandas·标准库及第三方库·学习与成长
Themberfue18 分钟前
Java多线程详解⑤(全程干货!!!)线程安全问题 || 锁 || synchronized
java·开发语言·线程·多线程·synchronized·
plmm烟酒僧19 分钟前
Windows下QT调用MinGW编译的OpenCV
开发语言·windows·qt·opencv
测试界的酸菜鱼31 分钟前
Python 大数据展示屏实例
大数据·开发语言·python
让学习成为一种生活方式34 分钟前
R包下载太慢安装中止的解决策略-R语言003
java·数据库·r语言
晨曦_子画40 分钟前
编程语言之战:AI 之后的 Kotlin 与 Java
android·java·开发语言·人工智能·kotlin
Black_Friend1 小时前
关于在VS中使用Qt不同版本报错的问题
开发语言·qt
南宫生1 小时前
贪心算法习题其三【力扣】【算法学习day.20】
java·数据结构·学习·算法·leetcode·贪心算法