新人学习,本文从B站学习借鉴而来,链接:https://www.bilibili.com/video/BV14A411q7pF/?p=9
本文会介绍maven项目创建,通过项目介绍简单模式Simple、工作模式Work、订阅模式Publish/Subscribe、路由模式Routing这四种常用的模式
在普通maven项目应用中使用MQ
- maven项目创建步骤:
- 1.简单模式
- 2.工作模式
- 2.1.消息生产者
- 2.2.消息消费者1
- 2.3.消息消费者2
- 3.订阅模式
- 3.1.消息生产者
- 3.2.消息消费者1
- 3.3.消息消费者2
- 4.路由模式
- 4.1.消息生产者
- 4.2.消息消费者1
- 4.3.消息消费者2
- 结语:
maven项目创建步骤:
1.首先,创建maven项目。
这里我创建了聚合项目(也可以不聚合,producer和consumer分开放也行,这里我是为了方便打包),该聚合项目包含producer和consumer,根据模式不同,消费者consumer会有1到多个,继续往下就知道了。
2.然后,配置pom.xml文件(添加依赖)、日志文件。
四种模式的生产者和消费者都要配置pom.xml和日志,值得注意的是日志是一样的可以直接复制过去,但pom.xml文件头部信息不同,把依赖部分添加即可,不要把整个pom.xml直接拷贝过去,否则会出现一些bug。
3.编写类,实现发送接收消息功能。
分别在producer和consumer中,写发送消息的类sendMsg和接受消息的类receiveMsg,这两个类是主要类。
还有一个工具类ConnectionUtil,用于连接rabbitmq的,连接是一样的所以producer和consumer中,这个工具类除了头部包名不同,具体内容一样,复制的时候注意头部别一起复制了。
以简单模式为例,一个生产者一个消费者,配置后目录:
producer/consumer的pom.xml的依赖部分:
simple父项目的pom.xml不用添加这部分依赖
<dependencies><!-- https://mvnrepository.com/artifact/com.rabbitmq/amqp-client --><dependency><groupId>com.rabbitmq</groupId><artifactId>amqp-client</artifactId><version>5.5.0</version></dependency><!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 --><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>1.7.25</version><scope>test</scope></dependency><!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.9</version></dependency></dependencies>
在src/main/resources目录下,添加log4j.properties日志:
log4j.properties:
log4j.rootLogger=DEBUG,A1 log4j.logger.com.taotao = DEBUG
log4j.logger.org.mybatis = DEBUG
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c]-[%p] %m%n
1.简单模式
在下图中,“ P”是我们的生产者,“ C”是我们的消费者。中间的框是一个队列-RabbitMQ代表使用者保留的消息缓冲区。
生产者将消息发送到“ hello”队列。使用者从该队列接收消息。
1.1.消息生产者
首先,创建帮助类ConnectionUtil.java。这个是一个连接MQ的工具类,是为了代码简洁,所以另外创建一个连接的工具类,使用的话直接导入该包调用即可。
ConnectionUtil:
package com.rbmq.consumer.utils;import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;public class ConnectionUtil {public static Connection getConnection() throws Exception {//定义连接工厂ConnectionFactory factory = new ConnectionFactory();// 设置服务地址factory.setHost("127.0.0.1");//端口factory.setPort(5672);// 设置账号信息,虚拟主机、用户名、密码,这里不特指某一个虚拟主机,所以用默认的“/”factory.setVirtualHost("/");factory.setUsername("guest");factory.setPassword("guest");// 通过工程获取连接Connection connection = factory.newConnection();return connection;}
}
生产者发送消息,SendMsg.java
package com.rbmq.producer.service;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rbmq.producer.utils.ConnectionUtil;public class sendMsg {public static void main(String[] argv) throws Exception {// 获取到连接以及mq通道Connection connection = ConnectionUtil.getConnection(); // 相当于数据库中的创建连接// 从连接中创建通道Channel channel = connection.createChannel(); // 相当于数据库中的 statement// 声明(创建)队列,如果存在就不创建,不存在就创建// 参数1 队列名,// 参数2 durable: 是否持久化, 队列的声明默认是存放到内存中的,如果rabbitmq重启会丢失,如果想重启之后还存在就要使队列持久化,保存到Erlang自带的Mnesia数据库中,当rabbitmq重启之后会读取该数据库// 参数3 exclusive:是否排外的,有两个作用,一:当连接关闭时connection.close()该队列是否会自动删除; 二:该队列是否是私有的private,如果不是排外的,可以使用两个消费者都访问同一个队列,没有任何问题,如果是排外 的,会对当前队列加锁,其他通道channel是不能访问的,如果强制访问会报异常: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=405, reply-text=RESOURCE_LOCKED - cannot obtain exclusive access to locked queue 'queue_name' in vhost '/', class-id=50, method-id=20)一般等于true的话 用于一个队列只能有一个消费者来消费的场景// 参数4 autoDelete:是否自动删除,当最后一个消费者断开连接之后队列是否自动被删除,可以通过RabbitMQ Management,查看某个队列的消费者数量,当consumers = 0时队列就会自动删除// 参数5 arguments: 参数//channel.queueDeclare("queue1", false, false, true, null);// 消息内容String message = "Hello consumer!";// 参数1 交换机,此处无// 参数2 发送到哪个队列// 参数3 属性// 参数4 内容channel.basicPublish("", "queue1", null, message.getBytes());// 将消息发动到数据库System.out.println(" 发送数据: '" + message + "'");//关闭通道和连接channel.close();connection.close();}
}
测试结果:
1.2.消息消费者
同样,首先创建工具类ConnectionUtil.java,这个类是连接mq的,没有连接mq,接收不到消息
然后,编写接收消息类receiveMsg:
package com.rbmq.consumer.service;import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.rbmq.consumer.utils.ConnectionUtil;public class receiveMsg {public static void main(String[] args) throws Exception {Connection connection = ConnectionUtil.getConnection(); // 相当于jdbc里的数据库连接Channel channel = connection.createChannel();// 相当于jdbc操作的statementConsumer consumer = new DefaultConsumer(channel) {@Overridepublic void handleDelivery(String consumerTag,Envelope envelope,AMQP.BasicProperties properties,byte[] body) {//body为从队列中获取的数据String msg = new String(body);System.out.println("接收到的消息:"+msg);}};channel.basicConsume("queue1", true, consumer);}
}
测试结果:
2.工作模式
工作队列,生产者把消息发送到队列中,由队列分配到消费者,采用的是先到先得的原则,即C1、C2共同争抢当前的消息队列内容,谁先拿到谁负责消费消息。例如超市低价促销先到先得。
基本项目步骤和上面的一样,都是:
#mermaid-svg-YHQRRskYJtTc3W0R .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-YHQRRskYJtTc3W0R .label text{fill:#333}#mermaid-svg-YHQRRskYJtTc3W0R .node rect,#mermaid-svg-YHQRRskYJtTc3W0R .node circle,#mermaid-svg-YHQRRskYJtTc3W0R .node ellipse,#mermaid-svg-YHQRRskYJtTc3W0R .node polygon,#mermaid-svg-YHQRRskYJtTc3W0R .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-YHQRRskYJtTc3W0R .node .label{text-align:center;fill:#333}#mermaid-svg-YHQRRskYJtTc3W0R .node.clickable{cursor:pointer}#mermaid-svg-YHQRRskYJtTc3W0R .arrowheadPath{fill:#333}#mermaid-svg-YHQRRskYJtTc3W0R .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-YHQRRskYJtTc3W0R .flowchart-link{stroke:#333;fill:none}#mermaid-svg-YHQRRskYJtTc3W0R .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-YHQRRskYJtTc3W0R .edgeLabel rect{opacity:0.9}#mermaid-svg-YHQRRskYJtTc3W0R .edgeLabel span{color:#333}#mermaid-svg-YHQRRskYJtTc3W0R .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-YHQRRskYJtTc3W0R .cluster text{fill:#333}#mermaid-svg-YHQRRskYJtTc3W0R div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-YHQRRskYJtTc3W0R .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-YHQRRskYJtTc3W0R text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-YHQRRskYJtTc3W0R .actor-line{stroke:grey}#mermaid-svg-YHQRRskYJtTc3W0R .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-YHQRRskYJtTc3W0R .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-YHQRRskYJtTc3W0R #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-YHQRRskYJtTc3W0R .sequenceNumber{fill:#fff}#mermaid-svg-YHQRRskYJtTc3W0R #sequencenumber{fill:#333}#mermaid-svg-YHQRRskYJtTc3W0R #crosshead path{fill:#333;stroke:#333}#mermaid-svg-YHQRRskYJtTc3W0R .messageText{fill:#333;stroke:#333}#mermaid-svg-YHQRRskYJtTc3W0R .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-YHQRRskYJtTc3W0R .labelText,#mermaid-svg-YHQRRskYJtTc3W0R .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-YHQRRskYJtTc3W0R .loopText,#mermaid-svg-YHQRRskYJtTc3W0R .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-YHQRRskYJtTc3W0R .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-YHQRRskYJtTc3W0R .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-YHQRRskYJtTc3W0R .noteText,#mermaid-svg-YHQRRskYJtTc3W0R .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-YHQRRskYJtTc3W0R .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-YHQRRskYJtTc3W0R .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-YHQRRskYJtTc3W0R .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-YHQRRskYJtTc3W0R .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-YHQRRskYJtTc3W0R .section{stroke:none;opacity:0.2}#mermaid-svg-YHQRRskYJtTc3W0R .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-YHQRRskYJtTc3W0R .section2{fill:#fff400}#mermaid-svg-YHQRRskYJtTc3W0R .section1,#mermaid-svg-YHQRRskYJtTc3W0R .section3{fill:#fff;opacity:0.2}#mermaid-svg-YHQRRskYJtTc3W0R .sectionTitle0{fill:#333}#mermaid-svg-YHQRRskYJtTc3W0R .sectionTitle1{fill:#333}#mermaid-svg-YHQRRskYJtTc3W0R .sectionTitle2{fill:#333}#mermaid-svg-YHQRRskYJtTc3W0R .sectionTitle3{fill:#333}#mermaid-svg-YHQRRskYJtTc3W0R .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-YHQRRskYJtTc3W0R .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-YHQRRskYJtTc3W0R .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-YHQRRskYJtTc3W0R .grid path{stroke-width:0}#mermaid-svg-YHQRRskYJtTc3W0R .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-YHQRRskYJtTc3W0R .task{stroke-width:2}#mermaid-svg-YHQRRskYJtTc3W0R .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-YHQRRskYJtTc3W0R .taskText:not([font-size]){font-size:11px}#mermaid-svg-YHQRRskYJtTc3W0R .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-YHQRRskYJtTc3W0R .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-YHQRRskYJtTc3W0R .task.clickable{cursor:pointer}#mermaid-svg-YHQRRskYJtTc3W0R .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-YHQRRskYJtTc3W0R .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-YHQRRskYJtTc3W0R .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-YHQRRskYJtTc3W0R .taskText0,#mermaid-svg-YHQRRskYJtTc3W0R .taskText1,#mermaid-svg-YHQRRskYJtTc3W0R .taskText2,#mermaid-svg-YHQRRskYJtTc3W0R .taskText3{fill:#fff}#mermaid-svg-YHQRRskYJtTc3W0R .task0,#mermaid-svg-YHQRRskYJtTc3W0R .task1,#mermaid-svg-YHQRRskYJtTc3W0R .task2,#mermaid-svg-YHQRRskYJtTc3W0R .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-YHQRRskYJtTc3W0R .taskTextOutside0,#mermaid-svg-YHQRRskYJtTc3W0R .taskTextOutside2{fill:#000}#mermaid-svg-YHQRRskYJtTc3W0R .taskTextOutside1,#mermaid-svg-YHQRRskYJtTc3W0R .taskTextOutside3{fill:#000}#mermaid-svg-YHQRRskYJtTc3W0R .active0,#mermaid-svg-YHQRRskYJtTc3W0R .active1,#mermaid-svg-YHQRRskYJtTc3W0R .active2,#mermaid-svg-YHQRRskYJtTc3W0R .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-YHQRRskYJtTc3W0R .activeText0,#mermaid-svg-YHQRRskYJtTc3W0R .activeText1,#mermaid-svg-YHQRRskYJtTc3W0R .activeText2,#mermaid-svg-YHQRRskYJtTc3W0R .activeText3{fill:#000 !important}#mermaid-svg-YHQRRskYJtTc3W0R .done0,#mermaid-svg-YHQRRskYJtTc3W0R .done1,#mermaid-svg-YHQRRskYJtTc3W0R .done2,#mermaid-svg-YHQRRskYJtTc3W0R .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-YHQRRskYJtTc3W0R .doneText0,#mermaid-svg-YHQRRskYJtTc3W0R .doneText1,#mermaid-svg-YHQRRskYJtTc3W0R .doneText2,#mermaid-svg-YHQRRskYJtTc3W0R .doneText3{fill:#000 !important}#mermaid-svg-YHQRRskYJtTc3W0R .crit0,#mermaid-svg-YHQRRskYJtTc3W0R .crit1,#mermaid-svg-YHQRRskYJtTc3W0R .crit2,#mermaid-svg-YHQRRskYJtTc3W0R .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-YHQRRskYJtTc3W0R .activeCrit0,#mermaid-svg-YHQRRskYJtTc3W0R .activeCrit1,#mermaid-svg-YHQRRskYJtTc3W0R .activeCrit2,#mermaid-svg-YHQRRskYJtTc3W0R .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-YHQRRskYJtTc3W0R .doneCrit0,#mermaid-svg-YHQRRskYJtTc3W0R .doneCrit1,#mermaid-svg-YHQRRskYJtTc3W0R .doneCrit2,#mermaid-svg-YHQRRskYJtTc3W0R .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-YHQRRskYJtTc3W0R .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-YHQRRskYJtTc3W0R .milestoneText{font-style:italic}#mermaid-svg-YHQRRskYJtTc3W0R .doneCritText0,#mermaid-svg-YHQRRskYJtTc3W0R .doneCritText1,#mermaid-svg-YHQRRskYJtTc3W0R .doneCritText2,#mermaid-svg-YHQRRskYJtTc3W0R .doneCritText3{fill:#000 !important}#mermaid-svg-YHQRRskYJtTc3W0R .activeCritText0,#mermaid-svg-YHQRRskYJtTc3W0R .activeCritText1,#mermaid-svg-YHQRRskYJtTc3W0R .activeCritText2,#mermaid-svg-YHQRRskYJtTc3W0R .activeCritText3{fill:#000 !important}#mermaid-svg-YHQRRskYJtTc3W0R .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-YHQRRskYJtTc3W0R g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-YHQRRskYJtTc3W0R g.classGroup text .title{font-weight:bolder}#mermaid-svg-YHQRRskYJtTc3W0R g.clickable{cursor:pointer}#mermaid-svg-YHQRRskYJtTc3W0R g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-YHQRRskYJtTc3W0R g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-YHQRRskYJtTc3W0R .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-YHQRRskYJtTc3W0R .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-YHQRRskYJtTc3W0R .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-YHQRRskYJtTc3W0R .dashed-line{stroke-dasharray:3}#mermaid-svg-YHQRRskYJtTc3W0R #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-YHQRRskYJtTc3W0R #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-YHQRRskYJtTc3W0R #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-YHQRRskYJtTc3W0R #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-YHQRRskYJtTc3W0R #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-YHQRRskYJtTc3W0R #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-YHQRRskYJtTc3W0R #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-YHQRRskYJtTc3W0R #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-YHQRRskYJtTc3W0R .commit-id,#mermaid-svg-YHQRRskYJtTc3W0R .commit-msg,#mermaid-svg-YHQRRskYJtTc3W0R .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-YHQRRskYJtTc3W0R .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-YHQRRskYJtTc3W0R .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-YHQRRskYJtTc3W0R g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-YHQRRskYJtTc3W0R g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-YHQRRskYJtTc3W0R g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-YHQRRskYJtTc3W0R g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-YHQRRskYJtTc3W0R g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-YHQRRskYJtTc3W0R g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-YHQRRskYJtTc3W0R .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-YHQRRskYJtTc3W0R .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-YHQRRskYJtTc3W0R .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-YHQRRskYJtTc3W0R .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-YHQRRskYJtTc3W0R .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-YHQRRskYJtTc3W0R .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-YHQRRskYJtTc3W0R .edgeLabel text{fill:#333}#mermaid-svg-YHQRRskYJtTc3W0R .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-YHQRRskYJtTc3W0R .node circle.state-start{fill:black;stroke:black}#mermaid-svg-YHQRRskYJtTc3W0R .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-YHQRRskYJtTc3W0R #statediagram-barbEnd{fill:#9370db}#mermaid-svg-YHQRRskYJtTc3W0R .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-YHQRRskYJtTc3W0R .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-YHQRRskYJtTc3W0R .statediagram-state .divider{stroke:#9370db}#mermaid-svg-YHQRRskYJtTc3W0R .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-YHQRRskYJtTc3W0R .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-YHQRRskYJtTc3W0R .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-YHQRRskYJtTc3W0R .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-YHQRRskYJtTc3W0R .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-YHQRRskYJtTc3W0R .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-YHQRRskYJtTc3W0R .note-edge{stroke-dasharray:5}#mermaid-svg-YHQRRskYJtTc3W0R .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-YHQRRskYJtTc3W0R .error-icon{fill:#522}#mermaid-svg-YHQRRskYJtTc3W0R .error-text{fill:#522;stroke:#522}#mermaid-svg-YHQRRskYJtTc3W0R .edge-thickness-normal{stroke-width:2px}#mermaid-svg-YHQRRskYJtTc3W0R .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-YHQRRskYJtTc3W0R .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-YHQRRskYJtTc3W0R .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-YHQRRskYJtTc3W0R .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-YHQRRskYJtTc3W0R .marker{fill:#333}#mermaid-svg-YHQRRskYJtTc3W0R .marker.cross{stroke:#333}:root { --mermaid-font-family: "trebuchet ms", verdana, arial;} #mermaid-svg-YHQRRskYJtTc3W0R {color: rgba(0, 0, 0, 0.75);font: ;}
创建maven项目
导入依赖和日志
编写实现类实现
项目创建和依赖、日志、ConnectionUtil帮助类一样的,不同的是多了一个消费者:
2.1.消息生产者
sendMsg:
package com.rbmq.producer.service;import java.util.Scanner;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rbmq.producer.utils.ConnectionUtil;public class sendMsg {public static void main(String[] argv) throws Exception {System.out.println("请输入消息:");Scanner scaner = new Scanner(System.in);String msg=null;while(!"quit".equals(msg=scaner.nextLine())) {// 获取到连接以及mq通道Connection connection = ConnectionUtil.getConnection(); // 从连接中创建通道Channel channel = connection.createChannel(); // 参数1 交换机,此处无// 参数2 发送到哪个队列// 参数3 属性// 参数4 内容channel.basicPublish("", "queue4", null, msg.getBytes());// 将消息发动到数据库System.out.println(" 发送数据: '" + msg + "'");//关闭通道和连接channel.close();connection.close();} }
}
测试环节(中间有丢包情况,所以多发了一次hello msg3):
2.2.消息消费者1
package com.rbmq.consumer.service;import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.rbmq.consumer.utils.ConnectionUtil;public class receiveMsg {public static void main(String[] args) throws Exception {Connection connection = ConnectionUtil.getConnection(); // 相当于jdbc里的数据库连接Channel channel = connection.createChannel();// 相当于jdbc操作的statementConsumer consumer = new DefaultConsumer(channel) {@Overridepublic void handleDelivery(String consumerTag,Envelope envelope,AMQP.BasicProperties properties,byte[] body) {//body为从队列中获取的数据String msg = new String(body);System.out.println("consumer1接收到的消息:"+msg);}};channel.basicConsume("queue4", true, consumer);}
}
测试结果:
2.3.消息消费者2
package com.rbmq.consumer.service;import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.rbmq.consumer.utils.ConnectionUtil;public class receiveMsg {public static void main(String[] args) throws Exception {Connection connection = ConnectionUtil.getConnection(); // 相当于jdbc里的数据库连接Channel channel = connection.createChannel();// 相当于jdbc操作的statementConsumer consumer = new DefaultConsumer(channel) {@Overridepublic void handleDelivery(String consumerTag,Envelope envelope,AMQP.BasicProperties properties,byte[] body) {//body为从队列中获取的数据String msg = new String(body);System.out.println("consumer2接收到的消息:"+msg);}};channel.basicConsume("queue4", true, consumer);}
}
测试结果:
3.订阅模式
一次向许多消费者发送消息,X代表交换机rabbitMQ内部组件,消息产生者将消息放入交换机,交换机发布订阅把消息发送到所有消息队列中,对应消息队列的消费者拿到消息进行消费,例如广告。
项目和上面的基本不变,主要改变发送接收模式参数即可。
3.1.消息生产者
sendMsg代码和上面的工作模式基本没有改变,改变的只有这一行:
channel.basicPublish("ex1", "", null, msg.getBytes());
注释:把消息发送到交换机ex1上而不是队列中,而在rabbitmq管理页面上交换机ex1绑定了队列1和队列2
测试环节:
3.2.消息消费者1
同样,receiveMsg1也基本没有改变,改变的是这一行:
channel.basicConsume("queue1", true, consumer);
消息消费者1接收的是交换机ex1所绑定的queue1队列
测试结果:
3.3.消息消费者2
同样,receiveMsg2也基本没有改变,改变的是这一行:
channel.basicConsume("queue2", true, consumer);
消息消费者1接收的是交换机ex1所绑定的queue2队列
测试结果:
注:这两个消费者都提前运行,同时接收到这两个消息。
4.路由模式
路由模式,消息生产者将消息发送给交换机按照路由判断,路由是字符串(info) ,交换机根据路由的key,只能匹配上路由key对应的消息队列,对应的消费者才能消费消息。
项目同样没有多大改动
4.1.消息生产者
sendMsg主要代码,其余不变:
// 获取到连接以及mq通道Connection connection = ConnectionUtil.getConnection(); // 从连接中创建通道Channel channel = connection.createChannel(); // 参数1 交换机// 参数2 路由key,如果前面的交换机为空,这里是队列参数// 参数3 属性// 参数4 内容if(msg.startsWith("a")) {channel.basicPublish("ex2", "a", null, msg.getBytes());}else if(msg.startsWith("b")) {channel.basicPublish("ex2", "b", null, msg.getBytes());}// 将消息发动到数据库System.out.println(" 发送数据: '" + msg + "'");//关闭通道和连接channel.close();connection.close();
测试环节:
4.2.消息消费者1
channel.basicConsume("queue3", true, consumer);
交换机ex2绑定了queue3,路由key为a,消费者1直接监听队列3
测试结果:
消费者1只接受路由key为a的消息,前面把字符串以a开头的路由key设置为a
4.3.消息消费者2
channel.basicConsume("queue4", true, consumer);
交换机ex2绑定了queue4,路由key为b,消费者2直接监听队列4
测试结果:
消费者2只接受路由key为b的消息,前面把字符串以b开头的路由key设置为b
结语:
通过四个项目的实现,对rabbitmq的几种常用的模式有比较好的了解,不足的地方是,经常出现丢包现象。
附上项目代码:
链接:https://pan.baidu.com/s/1jv-WZv9zQ6fU_jnQQRb73Q
提取码:pkar
在普通maven项目应用中使用MQ相关推荐
- 解决IDEA中maven项目视图中出现红色波浪线的问题
1.出现的问题 对于初次使用idea的开发者来说,可能会遇到自己创建好maven项目后,打开Maven Projects视图却发现下图中部分jar包出现了红色波浪线,此时自己能想到的最常见的解决方法就 ...
- 记一次解决maven项目sonarqube中覆盖率一直显示为0的问题.jacoco统计显示.
用了整整三天.QAQ.靠体力一下下试出来的结果.踩了个坑. 一开始,项目的覆盖率显示的是0,单元测试数也没有显示. 首先,想到的是test中的项目包结构目录的问题. 倒不是一定是全的,需要的包的路径结 ...
- maven项目pom中scope类型
1.compile:默认值 他表示被依赖项目需要参与当前项目的编译,还有后续的测试,运行周期也参与其中,是一个比较强的依赖.打包的时候通常需要包含进去2.test:依赖项目仅仅参与测试相关的工作,包括 ...
- Maven项目代码中定位resources文件夹下的文件目录,解决文件不存在的问题
在IDEA中对于文件的路径会提示: ../resources/xxx.txt 不要这样!!!,会报错找不到路径,改为: src/main/resources/xxx.txt
- 使用Scala-IDE构建Maven项目
转载自:http://blog.csdn.net/bingduanlbd/article/details/50991635 1. 下载Scala IDE 通过以下链接下载Scala IDE: htt ...
- javax maven项目缺少_教育平台项目后台管理系统:介绍与搭建
项目架构 项目介绍 教育后台管理系统是提供给相关业务人员使用的一个后台管理系统,业务人员可以在这个后台管理系统中,对课程信息.讲师信息. 学员信息等数据进行维护. 课程管理模块 课程管理 新建课程 条 ...
- java+maven项目+tapd+jenkins+gitlab+sonarqube+docker实现自动化持续部署(超详细)
文章目录 前言 相关介绍 一.准备 环境 二.安装docker 开放docker 2375端口 三.docker安装gitlab 修改gitlab.rb配置文件 进入容器重启配置 修改http的clo ...
- 在maven项目中使用Junit进行单元测试
在maven项目中使用Junit进行单元测试(一) 在maven项目中使用Junit进行单元测试一 创建maven项目 编写测试用代码 小结 这是第一篇博文,所以我决定先从比较简单的内容写起,同时熟悉 ...
- Dubbo 在maven项目中的应用
首先我们来看一下dubbo的架构: 所以通过此图,我们看到就是服务的提供者将服务注册到注册中心,服务的消费者从注册中心获取服务,monitor监控服务的调用. 关于dubbo的使用,我们举个简单的例子 ...
最新文章
- 计算机基础课程教学创新,【计算机基础论文】大学计算机基础课程教学创新探讨(共5359字)...
- 兼容浏览器_你知道什么是跨浏览器兼容吗?
- Java数据库连接(JDBC)之二:Statement对象和PreparedStatement对象的使用
- POPUP_TO_CONFIRM
- java jedis使用_Java中使用Jedis操作Redis
- 2021秋季跳槽必备:软件测试面试题(附带答案)备战金九银十!
- obj type using in findobj
- 转 LCD的接口类型详解
- matlab textscan 分块读取,【转】matlab的textscan与textread区别
- 手把手教你如何破解软件
- No serializer found for class JSONNull and no properties discovered to create BeanSerializer
- XCOM Enemy Unknown
- 最近一直在被螺旋槽成型铣刀的计算折磨着
- 自用房屋租住管理系统
- tf.estimator.Estimator的使用
- Unicode以及字符集转换
- java小程序——数字找规律小游戏
- 面试官:说说二维码扫码登录是什么原理吗?
- 华为前副总裁李玉琢:华为无法培养出企业家
- 使用nat123在个人电脑上搭建服务器(小白详细教程)
热门文章
- matlab射线平均速度时距曲线,时距曲线实验
- 产品分型面、插靠破、潜水进胶注意事项!
- JZJZJZ---数组中出现次数超过一半的数字
- mysql 数据库第二次安装不了_mysql数据库二次安装无法启动
- iPics2Go: iPhone变身扫描仪
- unl导入导出数据库
- 破解携程中文验证码爬取机票价格数据
- Android——一个简单的记账本APP
- Java关键字详解this、private、static、super、extends继承、instanceof、final、abstract、interface、implements、enum...
- 买天猫网店转让成为电商创业新趋势