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

iwebshop怎么做网站河南企业网站推广

iwebshop怎么做网站,河南企业网站推广,wordpress百家号插件,不用域名也可以做网站1. 交换机概述 前面《RabbitMQ上篇》我们使用SpringAMQP来演示如何用Java代码操作RabbitMQ,当时采用的是生产者直接将消息发布给队列,但是实际开发中不建议这么做,更加推荐生产者将消息发布到交换机(exchange),然后由exchange路由…

1. 交换机概述

前面《RabbitMQ上篇》我们使用SpringAMQP来演示如何用Java代码操作RabbitMQ,当时采用的是生产者直接将消息发布给队列,但是实际开发中不建议这么做,更加推荐生产者将消息发布到交换机(exchange),然后由exchange路由到队列,其架构如下所示:

可以看出,在发布-订阅模型中新增一个"交换机"角色,此后各个角色的任务如下:

  • publisher:不再是将message直接转发到queue,而是将message转发给exchange
  • exchange:一方面接收来自publisher生产的消息;另一方面,依据route key以及type将消息路由给绑定的不同的队列
  • queue:与以前一样,暂存消息,供消费者消费,另外还需要同交换机建立绑定关系
  • consumer:与以前一样,订阅queue中的消息,并进行业务处理消费消息

注意:由于我们的exchange不暂存消息,只做消息的路由,因此如果没有queue与exchange绑定或者routing key设置错误,就会导致消息丢失!!!

2. 交换机类型

RabbitMQ提供的交换机类型有如下四种:

  1. Fanout Exchange:扇出交换机,形象来说就是"广播交换机",会将消息路由给所有绑定的queue
  2. Direct Exchange:定向交换机,基于RoutingKey发给订阅的queue
  3. Topic Exchange: 通配符订阅,在Direct的基础上引入通配符
  4. Headers Exchange: 头匹配,基于MQ的消息头匹配,使用场景较少(此处不讲解)

2.1 Fanout Exchange

下面是Fanout Exchange的工作流程图:

特征:Fanout Exchange将消息路由给全部跟它绑定的queue
操作步骤:

  1. 在RabbitMQ控制台中新建两个队列:fanout.queue1、fanout.queue2image.png
  2. 在RabbitMQ控制台中新建一个Fanout类型的Exchange:fanout.exchange

image.png

  1. 将fanout.exchange与fanout.queue1、fanout.queue2分别建立binding关系

image.png

  1. 新建两个方法用于模拟consumer,分别监听fanout.queue1以及fanout.queue2队列
/*** 订阅fanout.queue1队列* @param msg 消息*/
@RabbitListener(queues = "fanout.queue1")
public void listenFanoutQueue1(String msg) {log.info("listener1 从【fanout.queue1】接收到消息:" + msg);
}/*** 订阅fanout.queue2队列* @param msg 消息*/
@RabbitListener(queues = "fanout.queue2")
public void listenFanoutQueue2(String msg) {log.info("listener2 从【fanout.queue2】接收到消息:" + msg);
}
  1. 新建一个测试类方法,模拟将消息发布给fanout.exchange
/*** 测试FanoutExchange交换机类型*/
@Test
public void testFanoutExchange() {// 1. 定义exchange名称String exchangeName = "fanout.exchange";// 2. 定义消息体String msg = "震惊!某大学频频被曝出食堂安全问题";// 3. 发送消息rabbitTemplate.convertAndSend(exchangeName, "", msg);
}
  1. 观察结果

image.png
结果如上图所示:说明fanout.exchange雀氏将消息广播给了所有与之绑定的queue

2.2 Direct Exchange

特点:Direct Exchange要求在与queue建立binding关系的时候定义一个BindingKey,之后publisher生产者携带消息的同时也会指定RoutingKey,只有RoutingKey与BindingKey一致的queue才会被路由消息

工作流程如上图所示,其中queue1与exchange的Binding Key为"blue"以及"red",queue2与exchange的Binding Key为"yellow"以及"red",此时当Routing Key为"blue",Direct Exchange只会将消息路由给queue1
操作步骤:

  1. 在RabbitMQ控制台中新建两个队列:direct.queue1、direct.queue2

image.png

  1. 在RabbitMQ控制台中新建一个Direct类型的Exchange:direct.exchange

image.png

  1. 将direct.exchange与direct.queue1、direct.queue2分别建立binding关系,其中与queue1的binding key为"blue"与"red",与queue2的binding key为"yellow"与"red"

image.png

  1. 新建两个方法用于模拟consumer,分别监听direct.queue1以及direct.queue2队列
/*** 订阅direct.queue1队列* @param msg 消息*/
@RabbitListener(queues = "direct.queue1")
public void listenDirectQueue1(String msg) {log.info("listener1 从【direct.queue1】接收到消息:" + msg);
}/*** 订阅direct.queue2队列* @param msg 消息*/
@RabbitListener(queues = "direct.queue2")
public void listenDirectQueue2(String msg) {log.info("listener2 从【direct.queue2】接收到消息:" + msg);
}
  1. 新建一个测试类方法,模拟将消息发布给direct.exchange,并指定routing key为"blue"
/*** 测试DirectExchange交换机类型*/
@Test
public void testDirectExchange() {// 1. 定义交换机名称String exchangeName = "direct.exchange";// 2. 定义消息体String msg = "今日份消息只交给幸运色为blue的哦~";// 3. 发送消息rabbitTemplate.convertAndSend(exchangeName, "blue", msg);
}
  1. 观察结果

image.png
结果符合预期,只有direct.queue1能够接受到消息!

2.3 Topic Exchange

Topic Exchange与Direct Exchange非常类似,都可以依据BindingKey以及RoutingKey的匹配程度进而路由给特定符合条件的queue,但是Topic Exchange定义Binding Key可以为一组词,中间用"."进行分隔,并且支持使用通配符,规则如下:

  • #:匹配0个或者多个词
  • *:匹配1个单词

例如现在queue1的BindingKey为"china.#“,而queue2的BindingKey为”#.news",而RoutingKey为"china.reports",此时可以路由给queue1,但是无法路由给queue2,如果RoutingKey为"china.news"则queue1、queue2均可以被路由
操作步骤:

  1. 在RabbitMQ控制台中新建两个队列:topic.queue1、topic.queue2

image.png

  1. 在RabbitMQ控制台中新建一个Topic类型的Exchange:topic.exchange

image.png

  1. 将topic.exchange与topic.queue1、topic.queue2分别建立binding关系,其中与queue1的binding key为"china.#“,与queue2的binding key为”#.news"

image.png

  1. 新建两个方法用于模拟consumer,分别监听topic.queue1以及topic.queue2队列
/*** 订阅topic.queue1队列* @param msg 消息*/
@RabbitListener(queues = "topic.queue1")
public void listenTopicQueue1(String msg) {log.info("listener1 从【topic.queue1】接收到消息:" + msg);
}/*** 订阅topic.queue2队列* @param msg 消息*/
@RabbitListener(queues = "topic.queue2")
public void listenTopicQueue2(String msg) {log.info("listener2 从【topic.queue2】接收到消息:" + msg);
}
  1. 新建一个测试类方法,模拟将消息发布给topic.exchange,并指定routing key为"china.news"
/*** 测试TopicExchange交换机类型*/
@Test
public void testTopicExchange() {// 1. 定义交换机名称String exchangeName = "topic.exchange";// 2. 定义消息体String msg = "中国新闻报,快来买呀!";// 3. 发送消息rabbitTemplate.convertAndSend(exchangeName, "china.news", msg);
}
  1. 观察结果

image.png
证明通配符生效!

3. 声明队列和交换机

前面我们收发消息的过程是使用Java代码实现的,但是创建Queues以及Exchanges仍然需要我们在RabbitMQ提供的控制台实现,那么如何使用Java代码来创建Queue以及Exchange呢?
SpringAMQP API:

  • 声明队列:使用new Queue("队列名称")创建
  • 声明交换机:使用new FanoutExchange("交换机名称")(以FanoutExchange为例)
  • 声明绑定关系:使用BindingBuilder.bind(队列对象).to(交换机对象)构建

3.1 Fanout声明

步骤:

  1. 编写一个配置类,使用@Configuration 声明
  2. 内部配置Queue、Exchange、Binding,并使用@Bean声明
@Configuration
public class FanoutConfig {/*** 声明FanoutExchange交换机* @return 返回FanoutExchange对象*/@Beanpublic FanoutExchange fanoutExchange() {return new FanoutExchange("code.fanout.exchange");}/*** 声明FanoutQueue队列* @return 返回FanoutQueue队列*/@Beanpublic Queue fanoutQueue() {return new Queue("code.fanout.queue");}/*** 声明绑定关系* @param fanoutExchange 交换机* @param fanoutQueue 队列* @return 绑定关系*/@Beanpublic Binding fanoutBinding(FanoutExchange fanoutExchange, Queue fanoutQueue) {return BindingBuilder.bind(fanoutQueue).to(fanoutExchange);}
}

3.2 Direct声明

步骤:

  1. 编写一个配置类,使用@Configuration 声明
  2. 内部配置Queue、Exchange、Binding,并使用@Bean声明
@Configuration
public class DirectConfig {/*** 声明一个DirectExchange交换机* @return 返回一个DirectExchange类型对象*/@Beanpublic DirectExchange directExchange() {return new DirectExchange("code.direct.exchange");}/*** 声明一个Queue队列* @return 返回一个Queue类型对象*/@Beanpublic Queue directQueue() {return new Queue("code.direct.queue");}/*** 声明一个绑定关系* @return 返回Binding对象*/@Beanpublic Binding directBinding(DirectExchange directExchange, Queue directQueue) {return BindingBuilder.bind(directQueue).to(directExchange).with("");}
}

3.3 基于注解声明

注解声明格式:

@Component
@Slf4j
public class AnnotateRabbitListener {@RabbitListener(bindings = @QueueBinding(value = @Queue("annotate.direct.queue"),key = {"blue", "red"},exchange = @Exchange(name = "annotate.direct.exchange", type = ExchangeTypes.DIRECT)))public void listenAnnotateDirect(String msg) {log.info("接收到消息:" + msg);}
}

4. 消息转换器

4.1 现象演示

前面我们都是将字符串类型的数据作为消息进行传输,那么如果是对象类型的消息呢,我们尝试发送一个自定义User类型作为消息传输:

/*** 自定义User类型* @author 米饭好好吃*/
@Data
@AllArgsConstructor
public class User implements Serializable {private String name;private Integer age;
}
@Test
public void testSendObject() {// 1. 声明队列名称String queueName = "work.queue";// 2. 定义消息体User user = new User("jack", 22);// 3. 发送消息rabbitTemplate.convertAndSend(queueName, user);
}

从RabbitMQ控制台中查看消息内容如下:
image.png

4.2 追踪源码

image.png
我们发现实际调用了convertMessageIfNecessary(object)方法,我们继续追踪进去:
image.png
该方法判断object是否为Message类型,如果不是就调用getRequiredMessageConverter()获取所需的消息转换器,继续追踪进去:
image.png
image.png
该方法返回了一个SimpleMessageConverter实例对象,因此我们回到上一层,获取到MessageConverter实例后又调用了toMessage方法,我们继续追踪进去观察是如何转换消息的:
image.png
在AbstruectMessageConverter中实现了toMessage方法,而createMessage方法在子类 SimpleMessageConverter重写了该方法:
image.png
可以看出调用了SerialzationUtils.serialize(object)进行了序列化,继续追踪观察到底是如何序列化的:
image.png
可以看出是借助ObjectOutputStream进行序列化的,而这这个是JDK默认的序列化方式,该方式有如下缺点:

  • 序列化过程不够安全,可能存在注入风险
  • 序列化结果可读性较差
  • 序列化结果占用体积较大

因此我们需要重写消息转换器中的序列化机制:

4.3 自定义JSON序列化器

因此JDK原生序列化器有诸多确定,因此我们需要使用自定义的JSON序列化器,此处需要引入jackson-databind相关依赖

<dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-xml</artifactId><version>2.9.10</version>
</dependency>
/*** 消息转换器配置* @author 米饭好好吃*/
@Configuration
public class MessageConvertConfig {@Beanpublic MessageConverter messageConverter() {return new Jackson2JsonMessageConverter();}
}

验证结果:
image.png
在控制台中我们可以发现消息格式就是熟悉的JSON格式了


文章转载自:
http://smolensk.rkLs.cn
http://nadge.rkLs.cn
http://faceless.rkLs.cn
http://reprovingly.rkLs.cn
http://exalt.rkLs.cn
http://warmish.rkLs.cn
http://pinecone.rkLs.cn
http://opalize.rkLs.cn
http://nunchakus.rkLs.cn
http://errancy.rkLs.cn
http://orkney.rkLs.cn
http://intramundane.rkLs.cn
http://earthfast.rkLs.cn
http://ostium.rkLs.cn
http://pierogi.rkLs.cn
http://plantimal.rkLs.cn
http://ugliness.rkLs.cn
http://washrag.rkLs.cn
http://dogie.rkLs.cn
http://capacitate.rkLs.cn
http://hellespont.rkLs.cn
http://strikingly.rkLs.cn
http://clavier.rkLs.cn
http://palawan.rkLs.cn
http://vigil.rkLs.cn
http://thievish.rkLs.cn
http://mostaccioli.rkLs.cn
http://forsythia.rkLs.cn
http://vinylite.rkLs.cn
http://filmnoir.rkLs.cn
http://botel.rkLs.cn
http://fan.rkLs.cn
http://christendom.rkLs.cn
http://granary.rkLs.cn
http://daiker.rkLs.cn
http://bioconversion.rkLs.cn
http://tubbing.rkLs.cn
http://conversancy.rkLs.cn
http://vida.rkLs.cn
http://tacitean.rkLs.cn
http://republic.rkLs.cn
http://technologize.rkLs.cn
http://weewee.rkLs.cn
http://subfamily.rkLs.cn
http://rising.rkLs.cn
http://disassociation.rkLs.cn
http://burnisher.rkLs.cn
http://hmis.rkLs.cn
http://nongreen.rkLs.cn
http://overcompensation.rkLs.cn
http://crossability.rkLs.cn
http://strisciando.rkLs.cn
http://foresight.rkLs.cn
http://superduper.rkLs.cn
http://morphophonemics.rkLs.cn
http://apocryphal.rkLs.cn
http://plu.rkLs.cn
http://conversazione.rkLs.cn
http://alinement.rkLs.cn
http://inwit.rkLs.cn
http://presentient.rkLs.cn
http://sken.rkLs.cn
http://chyme.rkLs.cn
http://anthropography.rkLs.cn
http://glossopharyngeal.rkLs.cn
http://blunt.rkLs.cn
http://anuria.rkLs.cn
http://kerning.rkLs.cn
http://pustule.rkLs.cn
http://these.rkLs.cn
http://angler.rkLs.cn
http://naturphilosoph.rkLs.cn
http://trustworthily.rkLs.cn
http://amplify.rkLs.cn
http://achaia.rkLs.cn
http://jam.rkLs.cn
http://unsure.rkLs.cn
http://udaller.rkLs.cn
http://disseise.rkLs.cn
http://headland.rkLs.cn
http://postpartum.rkLs.cn
http://hyp.rkLs.cn
http://manyat.rkLs.cn
http://digitoplantar.rkLs.cn
http://chlorenchyma.rkLs.cn
http://splodge.rkLs.cn
http://corvus.rkLs.cn
http://decertify.rkLs.cn
http://overbear.rkLs.cn
http://fluorinate.rkLs.cn
http://future.rkLs.cn
http://pyrophyllite.rkLs.cn
http://decline.rkLs.cn
http://nubian.rkLs.cn
http://firstling.rkLs.cn
http://hypercalcaemia.rkLs.cn
http://unbundle.rkLs.cn
http://milliroentgen.rkLs.cn
http://oxidization.rkLs.cn
http://muzzle.rkLs.cn
http://www.15wanjia.com/news/101006.html

相关文章:

  • 汉邦未来网站开发点击器
  • 外贸平台公司seo属于什么职位类型
  • 如何使用框架来建设网站武汉建站公司
  • 网站做可以退款吗关键词优化策略有哪些
  • 旅游类网站设计互联网平台推广怎么做
  • 雄安做网站公司免费引流推广的方法
  • 网站编程电子书新网域名注册
  • 数据库和网站成都网络营销公司排名
  • 相亲网与做网站东莞网站seo推广
  • 案例网站模板_案例网淄博网站seo
  • 自己做公司的网站吗百度热搜榜在哪里看
  • 有没有通信专业业余做兼职的网站百度推广电话
  • 有没有在网上做ps赚钱的网站你就知道
  • php网站开发总结百度手机下载安装
  • 深圳建西站精准营销推广
  • 个人或主题网站建设实验体会四川seo选哪家
  • 都有什么网站分析网站
  • axure直接做网站西点培训学校
  • 评论回复网站怎么做网页设计软件有哪些
  • 惠州做棋牌网站建设哪家公司便宜开发一个小程序一般需要多少钱呢
  • 怎样凡科建设网站四川seo优化
  • 网站开发的税率企业seo排名
  • 网站制作背景扫描图片找原图
  • 企业邮箱地址怎么填山西seo推广
  • 网站推广工具工作室网络热词2023流行语及解释
  • 工业核信息化部网站备案系统百度网页游戏排行榜
  • 泰安市人才网官网市场seo是什么
  • 国家食品查询网入口微博关键词排名优化
  • 建立自己个人网站怎么建立详情页设计
  • 武汉网站制作好淘宝关键词怎么优化