东营网站建设入门,定制规划设计公司,做网站分几个步骤,WordPress外链方法一、消息中间件
1.1消息队列回顾 消息队列中间件是分布式系统中重要的组件#xff0c;主要解决应用解耦#xff0c;异步消息#xff0c;流量削锋等问题#xff0c;实 现高性能#xff0c;高可用#xff0c;可伸缩和最终一致性架构。目前使用较多的消息队列有ActiveMQ 主要解决应用解耦异步消息流量削锋等问题实 现高性能高可用可伸缩和最终一致性架构。目前使用较多的消息队列有ActiveMQ RabbitMQZeroMQ Kafka MetaMQ RocketMQ。 消息中间件利用高效可靠的消息传递机制进行平台无关的数据交流并基于数据通信来进行分布式 系统的集成。通过提供消息传递和消息排队模型它可以在分布式环境下扩展进程间的通信。对于消息 中间件常见的角色大致也就有 Producer生产者 、 Consumer消费者 。
1.2 消息队列特性 1.2.1 先进先出 消息队列的顺序在入队的时候就基本已经确定了 一般是不需 人工干预的。而且最重要的是 数据是只有一条数据在使用中。 这也是MQ在诸多场景被使用的原因。 1.2.2 发布订阅 一般是MQ的广播模式类似于java的观察者模式。 发布订阅是一种很高效的处理方式如果不发生阻塞基本可以当做是同步操作。这种处理方式能 非常有效的提升服务器利用率这样的应用场景非常广泛。
1.2.3 持久化 持久化确保MQ的使用不只是一个部分场景的辅助工具而是让MQ能像数据库一样存储核心的数 据。
1.2.4 分布式 在现在大流量、大数据的使用场景下只支持单体应用的服务器软件基本是无法使用的支持分布 式的部署才能被广泛使用。而且 MQ的定位就是一个高性能的中间件。
1.3 为什么需要使用消息队列 其实就是问问你消息队列都有哪些使用场景然后你项目里具体是什么场景说说你在这个场景里 用消息队列是什么 1.3.1 应用解耦 在快递柜业务流程中快递员投柜后需要经历扣减系统费、短信通知用户和推送通知快递公司三个 业务动作。传统做法需要依次执行这些业务东西如果其中某一步异常例如用户手机未开机或者快递 公司接口故障将会延迟甚至中断整个投柜流程严重影响用户体验。 如果接口层收到投柜数据后写入消息到MQ后续三个子系统各自消费处理将可以完美解决该问题并且子系统故障不影响上游系统此为 解耦
1.3.2 异步 比如快递投柜后用户马上就结束了不会等待到发送短信或者通知快递公司结束的直接将消息 投递到MQ,然后就直接结束具体到扣减系统费以及后续的通知都是异步操作的不需要用户关心的着就是将用户的同步操作转换为异步操作。 如果全部同步操作需要15S而发送到MQ后交给系统异步处理用户只需要1S就可以完成操作。
1.3.3 流量削峰 就像用户投递快递高峰到40W每秒但是我们的后续处理业务每秒能处理20W还剩下20W在 MQ进行堆积这就是MQ很重要的流量削峰的能力将用户的洪峰流量让后台慢慢来处理MQ承担一个缓冲的左右 就像这个波形图一样如果用户请求的并发量的最高峰时40W系统的承载能力只能达到30W就 可以使用MQ进行削峰将系统最高40W的并发削峰为最高只有20万就是时间换空间的做法。
1.4 消息队列的缺点
1.4.1 系统可用性降低 消息队列在系统中充当一个中间人的身份如果该中间人突然失联了那其他两方就不知所措了 最后也就导致系统之间无法互动。 如果MQ出现了故障就可能会导致系统故障。
1.4.2 系统复杂性提高 在使用消息队列的过程中难免会出现生产者、 MQ、消费者宕机不可用的情况那么随之带来的 问题就是消息重复、消息乱序、消息堆积等等问题都需要我们来控制。
1.4.3 数据一致性问题 如下图所示系统需要保证快递投递扣减系统费通知等之间的数据一致性如果系统短信通 知快递通知执行成功扣减系统费执行失败时就会出现数据不一致问题。 如果出现这种问题我们需要有应对方案比如重试等方案。 所以消息队列实际是一种非常复杂的架构你引入它有很多好处但是也得针对它带来的坏处做各 种额外的技术方案和架构来规避掉做好之后你会发现妈呀系统复杂度提升了一个数量级也许 是复杂了 10 倍。但是关键时刻用还是得用的。
二、常用的消息中间件 消息队列是分布式应用间交换信息的重要组件消息队列可驻留在内存或磁盘上, 队列可以存储消息 直到它们被应用程序读走。 通过消息队列应用程序可以在不知道彼此位置的情况下独立处理消息或者在处理消息前不需要 等待接收此消息。 所以消息队列可以解决应用解耦、异步消息、流量削锋等问题是实现高性能、高可用、可伸缩和 最终一致性架构中不可以或缺的一环。 现在比较常见的消息队列产品主要有ActiveMQ、 RabbitMQ、ZeroMQ、 Kafka、 RocketMQ等
2.1 ActiveMQ ActiveMQ 是Apache出品最流行的能力强劲的开源消息总线。 ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现尽管JMS规范出台已经是很久的事情了但是JMS在当今的J2EE应用中间仍然扮演着特殊的地位。 2.1.1 特性 1.. 多种语言和协议编写客户端。语言: Java,C,C,C#,Ruby,Perl,Python,PHP。应用协议 OpenWire,Stomp REST,WS Notification,XMPP,AMQP 2. 完全支持JMS1.1和J2EE 1.4规范 持久化 XA消息事务) 3. 对Spring的支持 ActiveMQ可以很容易内嵌到使用Spring的系统里面去而且也支持Spring2.0的 特性 4. 通过了常见J2EE服务器如 Geronimo,JBoss 4,GlassFish,WebLogic)的测试其中通过JCA 1.5 resource adaptors的配置可以让ActiveMQ可以自动的部署到任何兼容J2EE 1.4 商业服务器上 5. 支持多种传送协议 in-VM,TCP,SSL,NIO,UDP,JGroups,JXTA 6. 支持通过JDBC和journal提供高速的消息持久化 7. 从设计上保证了高性能的集群客户端-服务器点对点 8. 支持Ajax 9. 支持与Axis的整合 10. 可以很容易得调用内嵌JMS provider进行测试 2.1.2 使用建议 一般的业务系统要引入 MQ最早大家都用 ActiveMQ但是现在确实大家用的不多了没经过大 规模吞吐量场景的验证社区也不是很活跃所以大家还是算了吧我个人不推荐用这个了
2.2 RabbitMQ RabbitMQ是流行的开源消息队列系统用erlang语言开发。 RabbitMQ是AMQP 高级消息队列 协议的标准实现。支持多种客户端如 Python、 Ruby、 .NET、Java、JMS、C、 PHP、ActionScript、XMPP、STOMP等支持AJAX持久化。用于在分布式系统中存储转发消息在易 用性、扩展性、高可用性等方面表现不俗 2.2.1 特性 erlang语言开发性能极其好延时很低 吞吐量到万级 MQ功能比较完备 开源提供的管理界面非常棒用起来很好用 社区相对比较活跃几乎每个月都发布几个版本分 在国内一些互联网公司近几年用rabbitmq也比较多一些 2.2.2 使用建议 大家开始用 RabbitMQ但是确实 erlang 语言阻止了大量的 Java工程师去深入研究和掌控它对 公司而言几乎处于不可控的状态但是确实人家是开源的比较稳定的支持活跃度也高所以中小 型公司技术实力较为一般技术挑战不是特别高用 RabbitMQ 是不错的选择对自家技术没有过高自信的话可以使用RabbitMQ人家有活跃的开源社区绝对不会黄。
2.3 Kafka Kafka是一种高吞吐量的分布式发布订阅消息系统它可以处理消费者规模的网站中的所有动作流 数据。 这种动作网页浏览搜索和其他用户的行动是在现代网络上的许多社会功能的一个关键因素这些数据通常是由于吞吐量的要求而通过处理日志和日志聚合来解决。 对于像Hadoop 的一样的日志数据和离线分析系统但又要求实时处理的限制这是一个可行的解决方案。 Kafka的目的是通过Hadoop的并行加载机制来统一线上和离线的消息处理也是为了通过集群机来提供实时的消费。 2.3.1 特性 通过O(1)的磁盘数据结构提供消息的持久化这种结构对于即使数以TB的消息存储也能够保持长时间的稳定性能。文件追加的方式写入数据过期的数据定期删除 高吞吐量即使是非常普通的硬件Kafka也可以支持每秒数百万的消息 支持通过Kafka服务器和消费机集群来分区消息 支持Hadoop并行数据加载 2.3.2 使用建议 如果是大数据领域的实时计算、日志采集等场景用 Kafka 是业内标准的绝对没问题社区活跃 度很高绝对不会黄何况几乎是全世界这个领域的事实性规范。
2.4 RocketMQ RocketMQ是阿里开源的消息中间件纯Java开发具有高吞吐量、高可用性、适合大规模分布式 系统应用的特点。 RocketMQ思路起源于Kafka但并不是简单的复制它对消息的可靠传输及事 务性做了优化目前在阿里集团被广泛应用于交易、充值、流计算、消息推送、日志流式处理、binglog分发等场景支撑了阿里多次双十一活动。 因为是阿里内部从实践到产品的产物因此里面很多接口、 api并不是很普遍适用。可靠性毋庸置 疑而且与Kafka一脉相承甚至更优性能强劲支持海量堆积。 2.4.1 特性 接口简单易用源码是阿里出品可自定义MQ topic可以达到几百几千个的级别吞吐量会有较小幅度的下降 消息可用性极高经过参数优化配置可以做到0丢失 MQ功能较为完善还是分布式的扩展性好 2.4.2 使用建议 现在确实越来越多的公司会去用 RocketMQ确实很不错毕竟是阿里出品但社区可能有突然黄 掉的风险目前 RocketMQ 已捐给 Apache但 GitHub 上的活跃度其实不算高对自己公司技术实力 有绝对自信的推荐用 RocketMQ否则回去老老实实用 RabbitMQ 吧大型公司基础架构研发实力 较强用 RocketMQ 是很好的选择。
三、RabbitMQ的基本使用 RabbitMQ 与 AMQP 遵循相同的模型架构其架构示例图如下 3.1重要概念
3.1.1 Pulisher 消息生产者就是投递消息的程序,发布者 (或称为生产者) 负责生产消息并将其投递到指定的交换器上。
3.1.2 Message 消息由消息头和消息体组成。消息头用于存储与消息相关的元数据如目标交换器的名字
(exchange_name) 、路由键 (RountingKey)和其他可选配置 (properties) 信息。消息体为实际需要传递 的数据。
3.1.3 Exchange 交换器负责接收来自生产者的消息并将将消息路由到一个或者多个队列中如果路由不到则返 回给生产者或者直接丢弃这取决于交换器的 mandatory 属性 当 mandatory 为 true 时如果交换器无法根据自身类型和路由键找到一个符合条件的队列则会 将该消息返回给生产者 当 mandatory 为 false 时如果交换器无法根据自身类型和路由键找到一个符合条件的队列则 会直接丢弃该消息。
3.1.4 BindingKey 交换器与队列通过 BindingKey 建立绑定关系。
3.1.5 RoutingKey 基于交换器类型的规则相匹配时消息被路由到对应的队列中 生产者将消息发给交换器的时候 一般会指定一个 RountingKey用来指定这个消息的路由规则。当 RountingKey 与 BindingKey匹配那会发送到对应的队列中。
3.1.6 Queue 消息队列载体每个消息都会被投入到一个或多个队列。 用于存储路由过来的消息。多个消费者可以订阅同一个消息队列此时队列会将收到的消息将以轮 询 (round-robin)的方式分发给所有消费者。即每条消息只会发送给一个消费者不会出现一条消息被多个消费者重 复消费的情况。
3.1.7 Comsumer 消费者订阅感兴趣的队列并负责消费存储在队列中的消息。为了保证消息能够从队列可靠地到达消费者 RabbitMQ 提供了消息确认机制 (messageacknowledgement)并通过autoAck 参数来进行 控制。
当 autoAck 为 true 时此时消息发送出去 (写入TCP套接字) 后就认为消费成功而不管消费者是 否真正消费到这些消息。当 TCP 连接或 channel 因意外而关闭或者消费者在消费过程之中意外 宕机时对应的消息就丢失。因此这种模式可以提高吞吐量但会存在数据丢失的风险。 当 autoAck 为 false 时需要用户在数据处理完成后进行手动确认只有用户手动确认完成后RabbitMQ 才认为这条消息已经被成功处理。这可以保证数据的可靠性投递但会降低系统的吞吐量。
3.1.8 Connection 用于传递消息的 TCP 连接。
3.1.9 Channel 消息通道在客户端的每个连接里可建立多个channel每个channel代表一个会话任务。 RabbitMQ 采用类似 NIO (非阻塞式 IO ) 的设计通过 Channel 来复用 TCP 连接并确保每个Channel的隔离性就像是拥有独立的 Connection 连接。当数据流量不是很大时采用连接复用技术可以避免创建过多的 TCP 连接而导致昂贵的性能开销。
3.1.10 Virtual Host 虚拟主机 一个broker里可以开设多个vhost用作不同用户的权限分离 RabbitMQ 通过虚拟主机来实现逻辑分组和资源隔离 一个虚拟主机就是一个小型的 RabbitMQ服 务器拥有独立的队列、交换器和绑定关系。用户可以按照不同业务场景建立不同的虚拟主机虚拟主 机之间是完全独立的你无法将 vhost1上的交换器与vhost2 上的队列进行绑定这可以极大的保证业 务之间的隔离性和数据安全。默认的虚拟主机名为 /。
3.1.11 Broker 简单来说就是消息队列服务器实体。
3.2 消息怎么路由 从概念上来说消息路由必须有三部分 交换器、路由、绑定。生产者把消息发布到交换器上绑 定决定了消息如何从路由器路由到特定的队列消息最终到达队列并被消费者接收。 消息发布到交换器时消息将拥有一个路由键routing key在消息创建时设定通过队列路由 键可以把队列绑定到交换器上。 消息到达交换器后 RabbitMQ会将消息的路由键与队列的路由键进行匹配针对不同的交换器有 不同的路由规则。如果能够匹配到队列则消息会投递到相应队列中如果不能匹配到任何队列消 息将进入 “黑洞”。
3.3 常用的交换器 交换器是消息被发送的 AMQP 实体。交换器拿到消息然后把它路由给0或多个队列。路由算法基 于交换器的类型和 bindings。 常用的交换器主要分为一下三种 Exchange type(交换器类型) Default pre-declared names(预声明默认名称) Direct exchange(直连交换器) (Empty string) and amq.direct Fanout exchange(扇形交换器) amq.fanout Topic exchange(主题交换器) amq.topic Headers exchange(头信息交换器) amq.match (and amq.headers in RabbitMQ) 3.3.1 直接交换机 如果路由键完全匹配消息就被投递到相应的队列 直连型交换机direct exchange是根据消息携带的路由键routing key将消息投递给对应绑 定键的队列。 直连交换机是一种带路由功能的交换机 一个队列会和一个交换机绑定除此之外再绑定一个routing_key当消息被发送的时候需要指定一个binding_key这个消息被送达交换机的时候就会 被这个交换机送到指定的队列里面去。同样的一个binding_key也是支持应用到多个队列中的。 直连型交换机图例 当生产者P发送消息时 Rotuing keybooking 时这时候将消息传送给 Exchange Exchange 获取到生产者发送过来消息后会根据自身的规则进行与匹配相应的 Queue这时发现 Queue1和Queue2 都符合就会将消息传送给这两个队列。 如果我们以 Rotuing keycreate 和 Rotuing keyconfirm 发送消息时这时消息只会被推送到Queue2 队列中其他 Routing Key 的消息将会被丢弃。
3.3.2 扇形交换机 如果交换器收到消息将会广播到所有绑定的队列上 扇型交换机fanout exchange将消息路由给绑定到它身上的所有队列而不理会绑定的路由键。如果 N 个队列绑定到某个扇型交换机上当有消息发送给此扇型交换机时交换机会将消息的拷贝 分别发送给这所有的 N 个队列。扇型用来交换机处理消息的广播路由broadcast routing。 因为扇型交换机投递消息的拷贝到所有绑定到它的队列所以他的应用案例都极其相似 大规模多用户在线MMO游戏可以使用它来处理排行榜更新等全局事件 体育新闻网站可以用它来近乎实时地将比分更新分发给移动客户端分发系统使用它来广播各种状态和配置更新 在群聊的时候它被用来分发消息给参与群聊的用户。AMQP 没有内置 presence 的概念因此 XMPP 可能会是个更好的选择 上图所示生产者P生产消息 1 将消息 1 推送到 Exchange由于 Exchange Typefanout 这 时候会遵循 fanout 的规则将消息推送到所有与它绑定 Queue也就是图上的两个 Queue 最后两个消 费者消费。
3.3.3 主题交换机 可以使来自不同源头的消息能够到达同一个队列。使用topic交换器时可以使用通配符。 基于消息的 routing key 与绑定到该交换器的队列的 pattern 进行匹配路由消息到一个或多个队 列。常用于复杂的发布/订阅场景。 当出现多消费者/应用的场景消费者选择性地接收消息时应该考虑使用topic exchange 前面提到的 direct 规则是严格意义上的匹配换言之 Routing Key 必须与 Binding Key 相匹配的时 候才将消息传送给 Queue. 而Topic 的路由规则是一种模糊匹配可以通过通配符满足一部分规则就可以传送。 匹配规则 1. binding key 中可以存在两种特殊字符 “*” 与“#”用于做模糊匹配其中 “*” 用于匹配一个单词 “#”用于匹配多个单词可以是零个 2. routing key 为一个句点号 “ .” 分隔的字符串我们将被句点号 “ . ” 分隔开的每一段独立的字符串称 为一个单词如“stock.usd.nyse”、“nyse.vmw”、“quick.orange.rabbit” binding key 与 routing key 一样也是句点号 “ .” 分隔的字符串 主题交换机图例 当生产者发送消息 Routing KeyF.C.E 的时候这时候只满足 Queue1所以会被路由到 Queue 中如果 Routing KeyA.C.E 这时候会被同是路由到 Queue1 和 Queue2 中如果 Routing KeyA.F.B 时这里只会发送一条消息到 Queue2 中。 主题交换机拥有非常广泛的用户案例。无论何时当一个问题涉及到那些想要有针对性的选择需要 接收消息的 多消费者 / 多应用multiple consumers/applications 的时候主题交换机都可以被列 入考虑范围。
3.3.4 头交换机 headers 类型的 Exchange 不依赖于 routing key 与 binding key 的匹配规则来路由消息而是根 据发送的消息内容中的 headers 属性进行匹配。 头交换机可以视为直连交换机的另一种表现形式。但直连交换机的路由键必须是一个字符串而头 属性值则没有这个约束它们甚至可以是整数或者哈希值字典等。灵活性更强但实际上我们很少 用到头交换机。工作流程 传来的消息会携带header以及会有一个 “x-match” 参数。当 “x-match” 设置为 “any” 时消息头的任意一个值被匹配就可以满足条件而当 “x-match” 设置为 “all” 的时候就需要消息头的所有值都匹配成功。
3.3.5 交换机总结 类型名 称 路由规则 Default 自动命名的直交换机 Direct 把消息路由到BindingKey和RoutingKey完全匹配的队列中 Routing KeyBinding Key严格匹配 Fanout 发送到该交换机的消息都会路由到与该交换机绑定的所有队列上可以用来做广播 Topic topic和direct类似也是将消息发送到RoutingKey和BindingKey相匹配的队列中 只不过可以模糊匹配 Headers 根据发送的消息内容中的 headers 属性进行匹配性能差基本不会使用