植物提取网站做的比较好的厂家,中职国示范建设网站,成功品牌策划案例,儿童网站模板免费下载1.同步通讯和异步通讯 举个例子#xff0c;同步通讯就像是在打电话#xff0c;因此它时效性较强#xff0c;可以立即得到结果#xff0c;但如果你正在和一个MM打电话#xff0c;其他MM找你的话#xff0c;你们之间是不能进行消息的传递和响应的 异步通讯就像是微信#…1.同步通讯和异步通讯 举个例子同步通讯就像是在打电话因此它时效性较强可以立即得到结果但如果你正在和一个MM打电话其他MM找你的话你们之间是不能进行消息的传递和响应的 异步通讯就像是微信你可以和多个MM进行消息的传递对方可以立即响应或者有空了在”回“你 同步调用问题 微服务间基于Feign的调用就属于同步方式存在一些问题。 1.代码耦合如果后续需要添加业务需要不断修改支付服务的代码 2.性能下降吞吐量下降支付服务一直在等待订单等服务的响应cpu资源一直在占用。 3.级联失败如果服务提供者出现问题所有调用方都会跟着出问题。
2.异步调用方案 异步调用常见的就是事件驱动模式Broker是事件代理者一旦用户支付成功这就是一个事件这个事件就会被Broker管理订单服务、仓储服务、短信服务。就会找Broker这个叫做订阅事件。一旦用户支付成功之后Broker就会通知被订阅过事件的服务支付服务完成事件发布之后就结束了服务返回给用户 优点 解决代码解耦添加业务时不需要再更改支付服务的代码支付服务只需要发布事件就行。至于后面的业务支付服务可以不用考虑。 性能提升吞吐量提供相比较同步服务业务处理时间的累加支付服务还需要等待其他服务完成并响应通过异步的方式支付服务发布时间之后就结束服务无需等待其他服务响应。提升了性能和吞吐量 服务没有依赖关系不用担心级联失败问题 流量削峰 有多个事件发布可以囤积到broker上订阅该事件的服务可以按自己的处理能力来稳步进行。broker起到缓冲作用 缺点 依赖Broker的可靠性、安全性、吞吐能力 架构复杂了业务没有明显的流程线不好追踪管理
3.什么是MQ
MQMessageQueue中文是消息队列字面来看就是存放消息的队列。也就是事件驱动架构中的Broker
常见的MQ RabbitMQ适用于中小型企业开发如果对性能要求比较高的并且需要定制服务的大型企业推荐使用Kafka。下面会介绍RabbitMQ的使用。
4.RabbitMQ概述和安装
RabbitMQ概述
RabbitMQ是基于Erlang语言开发的开源消息通信中间件官网地址https://www.rabbitmq.com
RabbitMQ的部署
环境centos7docker在线拉取的方式部署。
#拉取RabbitMQ镜像
输入docker pull rabbitmq:3-management
#设置默认用户名密码并启动容器
docker run --name rabbitmq -e RABBITMQ_DEFAULT_USERroot -e RABBITMQ_DEFAULT_PASS123 -p 15672:15672 -p 5672:5672 -d rabbitmq:3-management
端口15672是rabbitMQ的ui界面5672是服务端口
ui界面展示 RabbitMQ结构和概念
PubLisher是我们的消息事件发送者consumer是消息的消费者PubLisher将来会把消息发送到我们的exchange交换机上交换机负责路由并把消息投射到queue队列queue负责暂存消息consumer负责从queue里面获取消息处理消息。 5.RabbitMQ的常见消息模型
一、基本消息队列BasicQueue
HelloWorld是最基本的消息队列模型实现的话包含三个角色
publisher消息发布者将消息发送到队列queue
queue消息队列负责接受并缓存消息
consumer订阅队列处理队列中的消息 官方提供的编码方式非常麻烦下面我们介绍学习一下SpringAMQP它可以大大简化我们消息发送和接收API。
SpringAMQP简介
AMQP是用于在应用程序或之间传递业务消息的开放标准该协议与语言的平台无关更符合微服务中独立性的要求。
Spring AMQP是基于AMQP协议定义的一套API规范提供了模板来发送和接收消息包含两部分其中spring-amqp是基础抽象spring-rabbit是底层的默认实现。
利用SpringAMQP实现基础消息队列功能
通过rabbitTemplate提供的convertAndSend就可以实现消息的发送。
引入相关依赖
dependencygroupIdorg.springframework.amqp/groupIdartifactIdspring-rabbit/artifactIdscopetest/scope
/dependency
publisher消息发布者的application.yml的配置 test的测试代码
RunWith(SpringRunner.class)
SpringBootTest
class PublisherApplicationTests {Autowiredprivate RabbitTemplate rabbitTemplate;Testvoid contextLoads() {String queuenamesimple queue;String messagehello,spring AMQP;rabbitTemplate.convertAndSend(queuename,message);}} 通过rabbitTemplate实现对队列消息的监听
引入依赖
dependencygroupIdorg.springframework.amqp/groupIdartifactIdspring-rabbit/artifactIdscopetest/scope
/dependency
配置consumer消息接收者的application.yml文件
spring:rabbitmq:host: 192.168.10.8 #主机名port: 5672 #端口username: root #用户名password: 123 #密码virtual-host: / #虚拟主机名
监听类的代码
Component
public class SimpleListener {RabbitListener(queues simple queue)public void ListenSimpleQueue(String msg){System.out.println(消费者接收到simple queue的消息msg);}
} ps消息一旦消费就会从队列中删除RabbitMQ没有消息回溯功能。
二、工作消息队列WorkQueue
工作队列的结构如下 工作消息队列的结构相比于基础消息队列多了个消费者因为rabbitMQ阅后即焚的特性这两个消费者属于共同工作的关系如果有50个消息他们两个消费者就会一人分一半也就是一人25条为啥会多一个消费者这是因为如果一个消费者每次处理40个消息但是publisher一次发布50个消息多出来的消息会存储在queue里面又因为queue是占用内存的假以时日内存就会爆满新的消息就存不进去了多一个消费者每次就可以处理80条消息可以有效解决这个问题。
work queue工作队列可以提高消费处理速度避免队列消息堆积。但是这里有一个消息预取机制 消费者会提前把消息拿过来因此消息是平局分配并不是“能者多劳”的模式通过设置prefetch的值来实现每次只能获取一条消息处理完成才能接取下一个消息。实现“能者多劳”的模式。 发布订阅Publish、Subscribe
基础消息队列和工作消息队列都是一条信息只被一个消费者消费消费完就删除显然不能实现我们之前预想的完成支付之后通知仓储、短信等服务。这就需要我们了解学习发布订阅模式。发布订阅模式与之前案例的区别就是允许同一消息发送给多个消费者实现方式是加入exchange交换机结构如下 publisher将消息发送给exchange交换机交换机把这个消息转发给队列因此发布者publisher并不需要知到转发给了那个 队列或多个队列转发给多个队列这种方式就能实现被多个消费者消费那么交换机到底是发给一个还是多个呢这是由交换机类型来决定的。常见的exchange的类型包括
广播Fanout
路由Direct
主题Topic
注意 exchange负责消息路由而不是储存路由失败则消息丢失。 广播-Fanout Exchange
Fanout Exchange 会将接收到的消息路由到每一个绑定的queue。
实现思路
1.在consumer服务中利用代码声明队列、交换机、并将两者绑定。
在consumer服务上添加Configuration注解并声明FanoutExchange、Queue和关系对象Binding代码如下
Configuration
public class FanoutConfig {//声明交换机对象Beanpublic FanoutExchange fanoutExchange(){return new FanoutExchange(fanout);}//声明队列1Beanpublic Queue fanoutqueue1(){return new Queue(fanoutqueue1);}//绑定队列一到交换机Beanpublic Binding fanoutBinding1(Queue fanoutqueue1,FanoutExchange fanoutExchange){return BindingBuilder.bind(fanoutqueue1).to(fanoutExchange);}//声明队列2Beanpublic Queue fanoutqueue2(){return new Queue(fanoutqueue2);}//绑定队列二到交换机Beanpublic Binding fanoutBinding2(Queue fanoutqueue2,FanoutExchange fanoutExchange){return BindingBuilder.bind(fanoutqueue2).to(fanoutExchange);}
} 2.在consumer服务中编写两个消费者方法分别监听fanout.queue1和fanout.queue2
RabbitListener(queues fanoutqueue1)
public void ListenSimpleQueue3(String msg) throws InterruptedException {System.out.println(消费者222接收到fanoutqueue1的消息msg);Thread.sleep(100);
}
RabbitListener(queues fanoutqueue2)
public void ListenSimpleQueue4(String msg) throws InterruptedException {System.out.println(消费者222接收到fanoutqueue2的消息msg);Thread.sleep(100);
}
3.在publisher中编写测试方法向fanout发送消息。
Test
public void contectFonoutExchange()
{//交换机名称String exchangeNamefanout;//消息内容String messagehello everyone;//发送消息rabbitTemplate.convertAndSend(exchangeName,,message);
} 路由-DirectExchange
Direct Exchange 会将接收到的消息根据规则路由到指定的Queue因此称为路由模式routes
每一个Queue都与Exchange设置一个BindingKey一个队列可以绑定多个BindingKey。
发布者发送消息时指定消息的RoutingKey
Exchange交换机将消息路由到Bindingkey与消息RoutingKey一致的队列 实现思路
1.利用RabbitListenner声明Exchange、Queue、RountingKey
2.在consumer服务中编写两个消费者方法分别监听queue1和queue2
在我们的监听类里面增加两个方法用来声明交换机、队列和RountingKey
//发布订阅DirectExchange
RabbitListener(bindings QueueBinding(value Queue(name queue1),exchange Exchange(name direct,type ExchangeTypes.DIRECT),key {red,blue}
))
public void listenerDirectqueue1(String msg)
{System.out.println(消费者接收到direct.queue1的消息msg);
}RabbitListener(bindings QueueBinding(value Queue(name queue2),exchange Exchange(name direct,type ExchangeTypes.DIRECT),key {red,yellow}
))
public void listenerDirectqueue2(String msg)
{System.out.println(消费者接收到direct.queue2的消息msg);
} 3.在publisher中编写测试方法向Exchange发送消息。
Test
public void contextDirectExchange()
{String exchangeNamedirect;String msgbluehello blue;String msgRedhello red;String msgYellowhello yellow;rabbitTemplate.convertAndSend(exchangeName,blue,msgblue);
} Test
public void contextDirectExchange()
{String exchangeNamedirect;String msgbluehello blue;String msgRedhello red;String msgYellowhello yellow;rabbitTemplate.convertAndSend(exchangeName,red,msgRed);
} 话题-TopicExchange
TopicExchange与DirectExchange类似区别在于rountingKey必须是多个单词的列表并且以.分割。Queue与Exchange指定BindingKey可以使用通配符
#代表0个或多个单词
*代表一个单词
我们使用Direct的时候一个队列如果绑定了很多key会非常麻烦通配符的引入就把key的绑定简化许多原来绑定多个key现在只需要绑定一个key。
实现思路
1.利用RabbitListenter声明Exchange、Queue、RoutingKey
2.在consumer服务中编写两个消费者方法分别监听topic.queue1和topic.queue2
//topic话题
RabbitListener(bindings QueueBinding(value Queue(name topic.queue1),exchange Exchange(name topic,type ExchangeTypes.TOPIC),key china.#
))
public void listennertopicqueue1(String msg)
{System.out.println(消费者接收到topic.queue1的消息msg);
}
RabbitListener(bindings QueueBinding(value Queue(name topic.queue2),exchange Exchange(name topic,type ExchangeTypes.TOPIC),key #.news
))
public void listennertopicqueue2(String msg)
{System.out.println(消费者接收到topic.queue2的消息msg);
}
3.在publisher中编写测试方法向交换机topic发送消息
Test
public void contextTopicExchange()
{String exchangeNametopic;String msg我是懒大王;rabbitTemplate.convertAndSend(exchangeName,china.news,msg);
} 6.消息转换器
在SpringAMQP的发送方法中接收消息的类型是Object也就是说我们可以发送任意对象类型的消息SpringAMQP会帮我们序列化为字节后发送。
Spring的消息对象处理是由MessageConcerter来处理的而默认实现是SimpleMessageConverter基于JDK的ObjectOutputStream完成序列化这种序列化方式比较浪费内存资源如果需要修改只需要定义一个MessageConverter类型的Bean即可。推荐用JSON方式序列化步骤如下
我们在publisher服务引入依赖 我们在publisher服务中声明MessageConverter 文章转载自: http://www.morning.ngzkt.cn.gov.cn.ngzkt.cn http://www.morning.hpkgm.cn.gov.cn.hpkgm.cn http://www.morning.lwzgn.cn.gov.cn.lwzgn.cn http://www.morning.twfdm.cn.gov.cn.twfdm.cn http://www.morning.fnssm.cn.gov.cn.fnssm.cn http://www.morning.ywqsk.cn.gov.cn.ywqsk.cn http://www.morning.qtkfp.cn.gov.cn.qtkfp.cn http://www.morning.ksqyj.cn.gov.cn.ksqyj.cn http://www.morning.tfgkq.cn.gov.cn.tfgkq.cn http://www.morning.dphmj.cn.gov.cn.dphmj.cn http://www.morning.hrdx.cn.gov.cn.hrdx.cn http://www.morning.lgpzq.cn.gov.cn.lgpzq.cn http://www.morning.knlbg.cn.gov.cn.knlbg.cn http://www.morning.tlzbt.cn.gov.cn.tlzbt.cn http://www.morning.trhlb.cn.gov.cn.trhlb.cn http://www.morning.kqwsy.cn.gov.cn.kqwsy.cn http://www.morning.nrpp.cn.gov.cn.nrpp.cn http://www.morning.mzydm.cn.gov.cn.mzydm.cn http://www.morning.ydnx.cn.gov.cn.ydnx.cn http://www.morning.jbshh.cn.gov.cn.jbshh.cn http://www.morning.fpqsd.cn.gov.cn.fpqsd.cn http://www.morning.xmnlc.cn.gov.cn.xmnlc.cn http://www.morning.hmgqy.cn.gov.cn.hmgqy.cn http://www.morning.smdkk.cn.gov.cn.smdkk.cn http://www.morning.rcklc.cn.gov.cn.rcklc.cn http://www.morning.wjqbr.cn.gov.cn.wjqbr.cn http://www.morning.gsrh.cn.gov.cn.gsrh.cn http://www.morning.mpscg.cn.gov.cn.mpscg.cn http://www.morning.wwwghs.com.gov.cn.wwwghs.com http://www.morning.ylmxs.cn.gov.cn.ylmxs.cn http://www.morning.qgfkn.cn.gov.cn.qgfkn.cn http://www.morning.youyouling.cn.gov.cn.youyouling.cn http://www.morning.bpptt.cn.gov.cn.bpptt.cn http://www.morning.mmclj.cn.gov.cn.mmclj.cn http://www.morning.iiunion.com.gov.cn.iiunion.com http://www.morning.rwlns.cn.gov.cn.rwlns.cn http://www.morning.bsghk.cn.gov.cn.bsghk.cn http://www.morning.rynrn.cn.gov.cn.rynrn.cn http://www.morning.klzt.cn.gov.cn.klzt.cn http://www.morning.kgqpx.cn.gov.cn.kgqpx.cn http://www.morning.mzwqt.cn.gov.cn.mzwqt.cn http://www.morning.ybqlb.cn.gov.cn.ybqlb.cn http://www.morning.kgtyj.cn.gov.cn.kgtyj.cn http://www.morning.ylkkh.cn.gov.cn.ylkkh.cn http://www.morning.jqhrk.cn.gov.cn.jqhrk.cn http://www.morning.kcsx.cn.gov.cn.kcsx.cn http://www.morning.zqcgt.cn.gov.cn.zqcgt.cn http://www.morning.krwzy.cn.gov.cn.krwzy.cn http://www.morning.yqqgp.cn.gov.cn.yqqgp.cn http://www.morning.lksgz.cn.gov.cn.lksgz.cn http://www.morning.bpmdz.cn.gov.cn.bpmdz.cn http://www.morning.fblkr.cn.gov.cn.fblkr.cn http://www.morning.kzdwt.cn.gov.cn.kzdwt.cn http://www.morning.mpxbl.cn.gov.cn.mpxbl.cn http://www.morning.kxrhj.cn.gov.cn.kxrhj.cn http://www.morning.gcdzp.cn.gov.cn.gcdzp.cn http://www.morning.fkgqn.cn.gov.cn.fkgqn.cn http://www.morning.nptls.cn.gov.cn.nptls.cn http://www.morning.hlwzd.cn.gov.cn.hlwzd.cn http://www.morning.qkcyk.cn.gov.cn.qkcyk.cn http://www.morning.dbrpl.cn.gov.cn.dbrpl.cn http://www.morning.wanjia-sd.com.gov.cn.wanjia-sd.com http://www.morning.dmwbs.cn.gov.cn.dmwbs.cn http://www.morning.dgxrz.cn.gov.cn.dgxrz.cn http://www.morning.czcbl.cn.gov.cn.czcbl.cn http://www.morning.smry.cn.gov.cn.smry.cn http://www.morning.qcsbs.cn.gov.cn.qcsbs.cn http://www.morning.qsmmq.cn.gov.cn.qsmmq.cn http://www.morning.lnbcx.cn.gov.cn.lnbcx.cn http://www.morning.chxsn.cn.gov.cn.chxsn.cn http://www.morning.hcrxn.cn.gov.cn.hcrxn.cn http://www.morning.mmsf.cn.gov.cn.mmsf.cn http://www.morning.mwnch.cn.gov.cn.mwnch.cn http://www.morning.feites.com.gov.cn.feites.com http://www.morning.mmhaoma.com.gov.cn.mmhaoma.com http://www.morning.pmrlt.cn.gov.cn.pmrlt.cn http://www.morning.cflxx.cn.gov.cn.cflxx.cn http://www.morning.bkryb.cn.gov.cn.bkryb.cn http://www.morning.hqqpy.cn.gov.cn.hqqpy.cn http://www.morning.rqdx.cn.gov.cn.rqdx.cn