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

福州网站建设优质服务商宁波网络营销策划公司

福州网站建设优质服务商,宁波网络营销策划公司,深圳网站建设行吗,有没有教做熟食的网站RabbitMQ 工作机制图: Connection: 代表客户端(包括消息生产者和消费者)与RabbitMQ之间的连接。 Channel: 连接内部的Channel。channel:通道 Exchange: 充当消息交换机的组件。 Queue&#xff…

RabbitMQ 工作机制图:

Connection: 代表客户端(包括消息生产者和消费者)与RabbitMQ之间的连接。
Channel: 连接内部的Channel。channel:通道
Exchange: 充当消息交换机的组件。
Queue: 消息队列。
在这里插入图片描述

★ 消费消息

使用 RabbitMQ Java Client 开发 消息消费者 的大致步骤如下:

(1)创建ConnectionFactory,设置连接信息,再通过ConnectionFactory获取Connection。

(2)通过Connection获取Channel。

(3)根据需要,调用Channel的queueDeclare()方法声明队列,如果声明的队列已存在,该方法直接获取已有的队列;如果声明的队列还不存在,该方法将会创建新的队列。

(4)调用Channel 的 basicConsume()方法开始处理消息,调用该方法时需要传入一个Consumer参数,
该参数相当于JMS中的消息监听器。

这个 basicConsume()方法 相当于是异步消费。
而同步消费会出现阻塞情况,这就失去消息中间件存在的意义,所以先讲异步消费。

★ 发送消息

使用RabbitMQ Java Client依赖库开发消息生产者的大致步骤如下:

(1)创建ConnectionFactory,设置连接信息,再通过ConnectionFactory获取Connection。

(2)通过Connection获取Channel。

(3)根据需要调用exchangeDeclare()、queueDeclare()方法声明Exchange和队列、并完成队列与Exchange的绑定。
如果声明的Exchange还不存在,则创建该Exchange;否则直接使用已有的Exchange。
Declare:声明、宣布

(4)调用Channel的basicPublish()方法发送消息,调用该方法的第一个参数是exchange,
第二个参数为路由key,最后两个参数依次是消息属性和消息数据体。

【注意】:虽然消息生产者与队列是完全隔离的, 但如果消息生产者不声明消息队列,那系统中就可能暂时还没有任何消息队列。

在这种情况下,消息生产者向Exchange发送的消息将不会分发给任何队列,这些消息直接就被丢弃了。

【备注】:为了保证消息生产者能将消息发送到指定队列,消息生产者需要声明消息队列,保证消息队列的存在。

**问题:**消息生产者 和 消息队列 是完全隔离的,但是生产者为什么还要声明消息队列?
**原因:**因为程序如果先运行消息生产者,后运行消费者,而声明消息队列的方法又只存在消费者那边,那么在先运行消息生产者时,就会因为还没有生成消息队列,所以生产者发送到exchange的消息,会因为没有对应的消息队列而被丢弃。

代码演示:

先创建一个普通的 maven 项目。
在这里插入图片描述
添加一些属性 和 RabbitMQ的依赖
在这里插入图片描述

在这里插入图片描述

创建消息消费者

把创建连接的代码封装到一个方法里去。
在这里插入图片描述

消费者的代码
在这里插入图片描述
在这里插入图片描述

注意:channel.basicConsume 的第二个参数 autoAck:true,就是表示自动确认消息已经被消费完成了。就是当消费者接收到消息之后,就立马返回一个已经确认消费的消息回去给消息队列。
这样容易出现问题,就是消费者这边因为一收到消息就会自动确认消息被消费了并返回已经消费消息的结果回去给消息队列,但是可能消费者其实还没有把消息消费掉,而消息队列那边又以为消费者已经把消息消费了,所以就继续发消息给那个消费者。
而消费者一收到消息又自动确认消费并返回,就会导致这个消息队列的消息越来越多,然后消费者消费不完。
在这里插入图片描述
这个演示已消费未确认的演示放最后



执行消费者
在这里插入图片描述
控制台查看
原本没有这个消息队列,通过调用Channel的queueDeclare()方法声明队列,如果声明的队列已存在,该方法直接获取已有的队列;如果声明的队列还不存在,该方法将会创建新的队列

一开始消费者声明的这个消息队列,这个是否独占的exclusive 参数我是写true,
所以下图的 myQueue01的 Features 就是 Excl

在这里插入图片描述
在这里插入图片描述

这个就是创建的消费者。
用于消费这个 myQueue01 消息队列的消费者。
在这里插入图片描述

后面把 exclusive 改成了 false,是因为后面的生产者,需要也声明这个 myQueue01 消息队列,而如果这个消息队列是 独占的,就没法声明了,所以改成 false
在这里插入图片描述
在这里插入图片描述

创建消息生产者

生产者发送完消息就会关闭资源
消费者则是一直启动着
在这里插入图片描述

测试

先启动消费者或者启动生产者都一样,因为生产者和消费者都有调用queueDeclare() 方法声明消息队列,所以不存在发送消息后没找到对应的消息队列而导致消息被丢弃的情况。

启动消费者
在这里插入图片描述

然后启动生产者
生产者发送消息
在这里插入图片描述
再看消费者,已经消费了一条消息了。
因为先启动消费者,所以生产者发送的消息马上被消费了,在控制台的队列就看不到了。
在这里插入图片描述

再测试:

先启动生产者
关闭消费者,然后启动生产者发送消息
可以看出消息已经生产发送到消息队列了
在这里插入图片描述
在这里插入图片描述

这一步的流程图
在这里插入图片描述

启动消费者消费消息
在这里插入图片描述

流程图:
在这里插入图片描述

已消费未确认

注意:channel.basicConsume 的第二个参数 autoAck:true,就是表示自动确认消息已经被消费完成了。就是当消费者接收到消息之后,就立马返回一个已经确认消费的消息回去给消息队列。
这样容易出现问题,就是消费者这边因为一收到消息就会自动确认消息被消费了并返回已经消费消息的结果回去给消息队列,但是可能消费者其实还没有把消息消费掉,而消息队列那边又以为消费者已经把消息消费了,所以就继续发消息给那个消费者。
而消费者一收到消息又自动确认消费并返回,就会导致这个消息队列的消息越来越多,然后消费者消费不完。
在这里插入图片描述
在这里插入图片描述

如图:因为 autoAck 为false , 所以消费者消费消息后没有进行确认。这里的 unacked 条数就为1.

如果改成 autoAck 为false ,那么消费者消费消息的代码,要加上确认消息的方法。
在这里插入图片描述
这个就是手动确认消息。
在这里插入图片描述

完整代码:

ConnectionUtil 连接工具类

在这里插入图片描述

package cn.ljh.app.rabbitmq.util;import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;import java.io.IOException;
import java.util.concurrent.TimeoutException;//连接工具
public class ConnectionUtil
{//获取连接的方法public static Connection getConnection() throws IOException, TimeoutException{//创建连接工厂----这个ConnectionFactory源码可以看出有构造器,所以直接new一个出来ConnectionFactory connectionFactory =  new ConnectionFactory();//设置连接信息connectionFactory.setHost("localhost");connectionFactory.setPort(5672);connectionFactory.setUsername("ljh");connectionFactory.setPassword("123456");connectionFactory.setVirtualHost("/"); //连接虚拟主机//从连接工厂获取连接Connection connection = connectionFactory.newConnection();//返回连接return connection;}
}

P2PProducer 生产者

package cn.ljh.app.rabbitmq.producer;import cn.ljh.app.rabbitmq.consumer.P2PConsumer;
import cn.ljh.app.rabbitmq.util.ConnectionUtil;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeoutException;//消息生产者--使用默认的exchange
public class P2PProducer
{//(1)创建ConnectionFactory,设置连接信息,再通过ConnectionFactory获取Connection。//(2)通过Connection获取Channel。//(3)根据需要调用exchangeDeclare()、queueDeclare()方法声明Exchange和队列、并完成队列与Exchange的绑定。//    如果声明的Exchange还不存在,则创建该Exchange;否则直接使用已有的Exchange。//(4)调用Channel的basicPublish()方法发送消息,调用该方法的第一个参数是exchange,//    第二个参数为路由key,最后两个参数依次是消息属性和消息数据体。public static void main(String[] args) throws IOException, TimeoutException{//1、创建连接Connection conn = ConnectionUtil.getConnection();//2、通过Connection获取Channel。Channel channel = conn.createChannel();//3、调用exchangeDeclare()方法声明Exchange、调用queueDeclare()方法声明队列,并完成队列与Exchange的绑定//此处打算直接使用默认的Exchange来分发消息,因此无需声明 Exchange,只需声明队列channel.queueDeclare(P2PConsumer.QUEUE_NAME, true, false, false, null);String message = "生产者发送的消息的内容";//4、调用Channel的basicPublish()方法发送消息channel.basicPublish(""/*默认的 Exchange 没有名字,所以用空的字符串*/,P2PConsumer.QUEUE_NAME/*使用队列名作为路由key,表明该消息将会被路由到该队列*/,null /*指定额外的消息的属性*/,message.getBytes(StandardCharsets.UTF_8)/*消息体必须是字节数组类型-->byte[]*/);//5、关闭资源//关闭通道channel.close();//关闭连接conn.close();}
}

P2PConsumer 消费者

package cn.ljh.app.rabbitmq.consumer;import cn.ljh.app.rabbitmq.util.ConnectionUtil;
import com.rabbitmq.client.*;import java.io.IOException;
import java.util.concurrent.TimeoutException;//消息消费者
public class P2PConsumer
{// 使用 RabbitMQ Java Client 开发 消息消费者 的大致步骤如下://(1)创建ConnectionFactory连接工厂,设置连接信息,再通过ConnectionFactory获取Connection连接。//(2)通过Connection获取Channel。//(3)根据需要、调用Channel的queueDeclare()方法声明队列,  Declare:声明、宣布//    如果声明的队列已存在,该方法直接获取已有的队列;如果声明的队列还不存在,该方法将会创建新的队列。//(4)调用Channel 的 basicConsume()方法开始处理消息,调用该方法时需要传入一个Consumer参数,该参数相当于JMS中的消息监听器。//常量public final static String QUEUE_NAME = "myQueue01";public static void main(String[] args) throws IOException, TimeoutException{//1、创建连接工厂,设置连接信息,然后再通过连接工厂获取连接Connection conn = ConnectionUtil.getConnection();//2、通过Connection获取Channel 消息通道Channel channel = conn.createChannel();//3、调用 Channel 的 queueDeclare() 方法声明队列//如果声明的队列已存在,该方法直接获取已有的队列;如果声明的队列还不存在,该方法将会创建新的队列//参数1:声明的队列名; 参数2:消息队列是否持久化//参数3:是否只允许该消息消费者消费该队列的消息,为true,则其他消费者在这个myQueue01队列消息积堆过多的情况下,也无法帮忙消费。//参数4:是否自动删除(如果为true,在该队列没消息的情况下,会自动删除该队列) 参数5:填写额外的参数channel.queueDeclare(QUEUE_NAME, true, false, false, null);//4、调用Channel 的 basicConsume()方法开始处理消费消息channel.basicConsume(QUEUE_NAME/*消费这个名字的消费队列里面的消息*/,true/*消息的确认模式:是否自动确认*/,new DefaultConsumer(channel){//处理消息:当这个消息队列收到消息的时候,这个方法就会被触发。重写这个方法:@Overridepublic void handleDelivery(String consumerTag,Envelope envelope /*消息所在的信封,存放消息的exchange、路由key这些*/,AMQP.BasicProperties properties /*消息的那些属性*/,byte[] body /*body:消息的消息体*/) throws IOException{//把消息体中的消息拿出来String message = new String(body, "UTF-8");//printf:格式化输出函数   %s:输出字符串  %n:换行System.err.printf("P2PConsumer收到来自Exchange为【%s】、路由key为【%s】的消息,消息内容为%s%n",envelope.getExchange(),envelope.getRoutingKey(),message);}});}}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>cn.ljh</groupId><artifactId>rabbitmqtest</artifactId><version>1.0.0</version><name>rabbitmqtest</name><!--  属性  --><properties><maven.compiler.source>11</maven.compiler.source><maven.compiler.target>11</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><java.version>11</java.version></properties><!--  依赖  --><dependencies><!-- RabbitMQ 的依赖库 --><dependency><groupId>com.rabbitmq</groupId><artifactId>amqp-client</artifactId><version>5.13.0</version></dependency></dependencies></project>

文章转载自:
http://bewilderment.c7617.cn
http://colpitis.c7617.cn
http://gropingly.c7617.cn
http://smiercase.c7617.cn
http://sarcomatoid.c7617.cn
http://paraumbilical.c7617.cn
http://rhinoscope.c7617.cn
http://fuel.c7617.cn
http://ribgrass.c7617.cn
http://alcoholize.c7617.cn
http://araeostyle.c7617.cn
http://hmbs.c7617.cn
http://fusion.c7617.cn
http://premonstratensian.c7617.cn
http://postmeridian.c7617.cn
http://maximal.c7617.cn
http://superagency.c7617.cn
http://superfix.c7617.cn
http://disenchanted.c7617.cn
http://hdl.c7617.cn
http://plf.c7617.cn
http://restless.c7617.cn
http://perambulation.c7617.cn
http://deism.c7617.cn
http://picturize.c7617.cn
http://mitre.c7617.cn
http://voxml.c7617.cn
http://vituline.c7617.cn
http://substructure.c7617.cn
http://dageraad.c7617.cn
http://repeatedly.c7617.cn
http://closest.c7617.cn
http://enduringly.c7617.cn
http://filipino.c7617.cn
http://adieu.c7617.cn
http://valetudinary.c7617.cn
http://deaconry.c7617.cn
http://polyglot.c7617.cn
http://schizomycete.c7617.cn
http://mediatise.c7617.cn
http://frescoist.c7617.cn
http://otaru.c7617.cn
http://seedman.c7617.cn
http://eligibility.c7617.cn
http://parse.c7617.cn
http://sludgy.c7617.cn
http://talliate.c7617.cn
http://unchaste.c7617.cn
http://almanac.c7617.cn
http://pdb.c7617.cn
http://ambergris.c7617.cn
http://rhomboid.c7617.cn
http://scrum.c7617.cn
http://fobs.c7617.cn
http://fraternize.c7617.cn
http://scoriae.c7617.cn
http://ilex.c7617.cn
http://intilted.c7617.cn
http://topazolite.c7617.cn
http://ozonolysis.c7617.cn
http://briony.c7617.cn
http://larvikite.c7617.cn
http://suppletion.c7617.cn
http://seminivorous.c7617.cn
http://hypallage.c7617.cn
http://span.c7617.cn
http://sorus.c7617.cn
http://vitamin.c7617.cn
http://colter.c7617.cn
http://claptrap.c7617.cn
http://pawnee.c7617.cn
http://kilogrammeter.c7617.cn
http://lilium.c7617.cn
http://stanchly.c7617.cn
http://candlepower.c7617.cn
http://disfavour.c7617.cn
http://preclude.c7617.cn
http://chalkware.c7617.cn
http://nachtlokal.c7617.cn
http://cameralistics.c7617.cn
http://bouffant.c7617.cn
http://copyist.c7617.cn
http://elsewise.c7617.cn
http://metaphysical.c7617.cn
http://divertissement.c7617.cn
http://panmixis.c7617.cn
http://armipotence.c7617.cn
http://periphyton.c7617.cn
http://acumination.c7617.cn
http://creationary.c7617.cn
http://standardize.c7617.cn
http://lax.c7617.cn
http://elul.c7617.cn
http://rubbishy.c7617.cn
http://catalyse.c7617.cn
http://podunk.c7617.cn
http://levelly.c7617.cn
http://scholarly.c7617.cn
http://jawed.c7617.cn
http://disrelation.c7617.cn
http://www.zhongyajixie.com/news/53354.html

相关文章:

  • 怎么打帮人 做网站开发的广告360搜索首页
  • 平台类网站有哪些企业培训
  • 做模具五金都是用的那个网站电子商务营销策略有哪些
  • 怎么做自己的发卡网站6百度快照入口
  • 网站优化骗局广告推广方式有哪几种
  • 好看的网站源码优化培训方式
  • asp.net动态网站开发技术app推广拉新
  • 不知此网站枉做男人重庆快速排名优化
  • wordpress主题预览插件seo搜索引擎优化服务
  • 淄博网站建设哪家好sem和seo区别与联系
  • 刷赞网站空间推广赚钱的app
  • 海南省网站设计公司网址网络营销研究现状文献综述
  • 成都网站建设开发价格响应式网站模板的应用
  • 深圳+服装+网站建设如何自己做一个网页
  • 惠州淘宝网站建设seo推广网址
  • 苏州松陵镇哪里做网站百度sem竞价推广
  • 建网站的免费空间福建百度代理公司
  • 网站的栏目设计商品营销推广的方法有哪些
  • 百度怎么做网站广告如何进行网络营销策划
  • 小店网站制作网络营销课程思政
  • wordpress review主题杭州seo服务公司
  • wordpress 论坛功能绍兴百度seo排名
  • 宝安做网站的公司成都网站制作费用
  • 四川建设厅官方网站查询资料员方象科技专注于什么领域
  • 动态商务网站开发与管理全网搜索关键词查询
  • .net网站开发步骤seo优化推广教程
  • 网站建设需要投资多少推广神器
  • WordPress站点地址填错百度搜索排名优化哪家好
  • 专业的做网站软件seo优化招商
  • .net和java做网站比例网页制作的软件有哪些