精华内容
下载资源
问答
  • 解码方法(一条包含字母 A-Z 的消息通过以下方式进行了编码)
    千次阅读
    2019-05-11 19:09:50

    一条包含字母 A-Z 的消息通过以下方式进行了编码:
    'A' -> 1
    'B' -> 2
    ...
    'Z' -> 26

    给定一个只包含数字的非空字符串,请计算解码方法的总数。

    示例 1:
    输入: "12"
    输出: 2
    解释: 它可以解码为 "AB"(1 2)或者 "L"(12)。

    示例 2:
    输入: "226"
    输出: 3
    解释: 它可以解码为 "BZ" (2 26), "VF" (22 6), 或者 "BBF" (2 2 6) 。

     

    解题思路:非常类似于斐波那契序列,可以理解为dp[i]=dp[i-1]+dp[i-2]。 但是这个是有条件的:

    如果以i为下标的字符串,i-1位与i位组成的两位数不在10-26之间,那么dp[i-2]就不能加。如果以i为下标的元素为0,也不能加dp[i-1].

     

    public class test0511 {
        public static void main(String[] args) {
            Solution s = new Solution();
            System.out.println(s.numDecodings("101"));
        }
    }
    
    class Solution {
        public int numDecodings(String s) {
            if(s.length() == 0 || s.charAt(0) =='0' ){
                return 0;
            }
            if(s.length() == 1 ){
                return 1;
            }
            int dp1 = 1;//相当于dp[i-2]
            int dp2 = 1;//相当于dp[i-1]
            int result = 0;
            for(int i = 1;i<s.length();i++){
                int i1 = (s.charAt(i - 1) - 48) * 10 + (s.charAt(i) - 48);
                //不能连续出现0
                if(i1 == 0){
                    return 0;
                }
                if(i1 >=10 && i1 <=26 ){
                    result = dp1;
                }
                if(s.charAt(i) != '0'){
                    result += dp2;
                }
                dp1 = dp2;
                dp2 = result;
                result = 0;
            }
            return dp2;
        }
    }

     

    更多相关内容
  • CRC32:4个字节,消息的校验码。 magic:1字节,魔数标识,与消息格式有关,取值为0或1。当magic为0时,消息的offset使用绝对offset且消息格式中没有timestamp部分;当magic为1时,消息的offset使用相对offset且消息...

    在这里插入图片描述

    • CRC32:4个字节,消息的校验码。

    • magic:1字节,魔数标识,与消息格式有关,取值为0或1。当magic为0时,消息的offset使用绝对offset且消息格式中没有timestamp部分;当magic为1时,消息的offset使用相对offset且消息格式中存在timestamp部分。所以,magic值不同,消息的长度是不同的。

    • attributes: 1字节,消息的属性。其中第0~ 2位的组合表示消息使用的压缩类型,0表示无压缩,1表示gzip压缩,2表示snappy压缩,3表示lz4压缩。第3位表示时间戳类型,0表示创建时间,1表示追加时间。

    • timestamp: 时间戳,其含义由attributes的第3位确定。

    • key length:消息key的长度。

    • key:消息的key。

    • value length:消息的value长度。

    • value:消息的内容

    展开全文
  • 消息队列之 RabbitMQ(

    千次阅读 2021-11-28 23:19:31
    文章目录消息队列什么消息队列为什么要用消息队列RabbitMQ 消息队列 消息队列 (Messaeg Queue) 是种使用队列 (Queue) 作为底层存储数据结构,可用于解决不同进程与应用之间通讯的分布式消息容器,也称为消息...

    消息队列

    消息队列 (Messaeg Queue) 是一种使用队列 (Queue) 作为底层存储数据结构,可用于解决不同进程与应用之间通讯的分布式消息容器,也称为消息中间件。

    什么是消息队列

    • 消息队列(message queue,MQ),从字面意思上看,本质是个队列,FIFO 先入先出,只不过队列中存放的内容是message 而已,还是一种跨进程的通信机制,用于上下游传递消息。在互联网架构中,MQ 是一种非常常见的上下游“逻辑解耦+物理解耦”的消息通信服务。使用了 MQ 之后,消息发送上游只需要依赖 MQ,不用依赖其他服务。

    为什么要用消息队列

    消息通讯

    • 消息队列最主要功能收发消息,其内部有高效的通讯机制,因此非常适合用于消息通讯。我们可以基于消息队列开发点对点聊天系统,也可以开发广播系统,用于将消息广播给大量接收者。

    流量消峰

    • 举个例子,如果订单系统最多能处理一万次订单,这个处理能力应付正常时段的下单时绰绰有余,正常时段我们下单一秒后就能返回结果。但是在高峰期,如果有两万次下单操作系统是处理不了的,只能限制订单超过一万后不允许用户下单。使用消息队列做缓冲,我们可以取消这个限制,把一秒内下的订单分散成一段时间来处理,这时有些用户可能在下单十几秒后才能收到下单成功的操作,但是比不能下单的体验要好。

    应用解耦

    • 以电商应用为例,应用中有订单系统、库存系统、物流系统、支付系统。用户创建订单后,如果耦合调用库存系统、物流系统、支付系统,任何一个子系统出了故障,都会造成下单操作异常。当转变成基于消息队列的方式后,系统间调用的问题会减少很多,比如物流系统因为发生故障,需要几分钟来修复。在这几分钟的时间里,物流系统要处理的内存被缓存在消息队列中,用户的下单操作可以正常完成。当物流系统恢复后,继续处理订单信息即可,中单用户感受不到物流系统的故障,提升系统的可用性。
      在这里插入图片描述

    异步处理

    • 有些服务间调用是异步的,例如 A 调用 B,B 需要花费很长时间执行,但是 A 需要知道 B 什么时候可以执行完,以前一般有两种方式,A 过一段时间去调用 B 的查询 api 查询。或者 A 提供一个 callback api, B 执行完之后调用 api 通知 A 服务。这两种方式都不是很优雅,使用消息总线,可以很方便解决这个问题,A 调用 B 服务后,只需要监听 B 处理完成的消息,当 B 处理完成后,会发送一条消息给 MQ,MQ 会将此消息转发给 A 服务。这样 A 服务既不用循环调用 B 的查询 api,也不用提供 callback api。同样B 服务也不用做这些操作。A 服务还能及时的得到异步处理成功的消息。
      在这里插入图片描述

    目前使用得比较多的消息队列有 ActiveMQ,RabbitMQ,Kafka,RocketMQ 等。本文主要讲述的是 RabbitMQ,RabbitMQ 是用 Erlang 语言开发的一个实现了 AMQP 协议的消息队列服务器,相比其他同类型的消息队列,最大的特点在保证可观的单机吞吐量的同时,延时方面非常出色。

    RabbitMQ

    RabbitMQ 的概念

    • RabbitMQ是一个消息代理。它的工作就是接收和转发消息。你可以把它想像成一个邮局:你把信件放入邮箱,邮递员就会把信件投递到你的收件人处。在这个比喻中,RabbitMQ就扮演着邮箱、邮局以及邮递员的角色。RabbitMQ和邮局的主要区别在于,它处理纸张,而是接收、存储和发送消息(message)这种二进制数据。

    RabbitMQ相关名词介绍

    RabbitMQ 内部结构

    RabbitMQ 内部结构
    Message

    • 消息,由Header和body组成,Header是由生产者添加的各种属性的集合,包括Message是否被持久化、优先级是多少、由哪个Message Queue接收等;body是真正需要发送的数据内容;

    Publisher

    • 消息的生产者,也是一个向交换器发布消息的客户端应用程序。

    Exchange

    • 消息交换机,作用是接收来自生产者的消息,并根据路由键转发消息到所绑定的队列。生产者发送上的消息,就是先通过 Exchnage 按照绑定 (binding) 规则转发到队列的。
    • 交换机类型 (Exchange Type) 有四种:fanout、direct、topic,headers,其中 headers 并不常用。

    Binding

    • 绑定,用于消息队列和交换器之间的关联。一个绑定就是基于路由键将交换器和消息队列连接起来的路由规则,所以可以将交换器理解成一个由绑定构成的路由表,Binding 操作一般用于 RabbitMQ 的路由工作模式和主题工作模式。

    Queue

    • 消息队列,内部用于存储消息的对象,是真正用来存储消息的结构。它是消息的容器,也是消息的终点。在生产端,生产者的消息最终发送到指定队列,而消费者也是通过订阅某个队列,达到获取消息的目的。一个消息可投入一个或多个队列。消息一直在队列里面,等待消费者连接到这个队列将其取走。

    Connection

    • 网络连接,是 RabbitMQ 内部对象之一,用于管理每个到 RabbitMQ 的 TCP 网络连接。

    Channel

    • 信道,多路复用连接中的一条独立的双向数据流通道,也是我们与 RabbitMQ 打交道的最重要的一个接口,我们大部分的业务操作是在 Channel 这个接口中完成的,包括定义 Queue、定义 Exchange、绑定 Queue 与 Exchange、发布消息等。
    • 信道是建立在真实的TCP连接内地虚拟连接,AMQP 命令都是通过信道发出去的,不管是发布消息、订阅队列还是接收消息,这些动作都是通过信道完成。因为对于操作系统来说建立和销毁 TCP 都是非常昂贵的开销,所以引入了信道的概念,以复用一条 TCP 连接。

    Consumer

    • 消息的消费者,表示一个从消息队列中取得消息的客户端应用程序。

    Virtual Host

    • 虚拟主机,表示一批交换器、消息队列和相关对象。虚拟主机是共享相同的身份认证和加密环境的独立服务器域。每个 vhost 本质上就是一个 mini 版的 RabbitMQ 服务器,拥有自己的队列、交换器、绑定和权限机制。vhost 是 AMQP 概念的基础,必须在连接时指定,RabbitMQ 默认的 vhost 是 / 。
    • 一个 VirtualHost 下面有一组不同 Exchnage 与 Queue,不同的 Virtual host 的 Exchnage 与 Queue 之间互相不影响。应用隔离与权限划分,Virtual host 是 RabbitMQ 中最小颗粒的权限单位划分。
    • 如果要类比的话,我们可以把 Virtual host 比作 MySQL 中的数据库,通常我们在使用 MySQL 时,会为不同的项目指定不同的数据库,同样的,在使用 RabbitMQ 时,我们可以为不同的应用程序指定不同的 Virtual host。

    Broker

    • 表示消息队列服务器实体。

    RabbitMQ 消息应答

    概念

    • 消费者完成一个任务可能需要一段时间,如果其中一个消费者处理一个长的任务并仅只完成了部分突然它挂掉了,会发生什么情况。RabbitMQ 一旦向消费者传递了一条消息,便立即将该消息标记为删除。在这种情况下,突然有个消费者挂掉了,我们将丢失正在处理的消息。以及后续发送给该消费这的消息,因为它无法接收到。
    • 为了保证消息在发送过程中不丢失,rabbitmq 引入消息应答机制,消息应答就是:消费者在接收到消息并且处理该消息之后,告诉 rabbitmq 它已经处理了,rabbitmq 可以把该消息删除了。

    自动应答

    • 消息发送后立即被认为已经传送成功,这种模式需要在高吞吐量和数据传输安全性方面做权衡,因为这种模式如果消息在接收到之前,消费者那边出现连接或者 channel 关闭,那么消息就丢失 了,当然另一方面这种模式消费者那边可以传递过载的消息,没有对传递的消息数量进行限制,当然这样有可能使得消费者这边由于接收太多还来不及处理的消息,导致这些消息的积压,最终使得内存耗尽,最终这些消费者线程被操作系统杀死,所以这种模式仅适用在消费者可以高效并以某种速率能够处理这些消息的情况下使用。

    手动应答

    • 消费者从队列中获取消息后,服务器会将该消息标记为不可用状态,等待消费者的反馈,如果消费者一直没有反馈,那么该消息将一直处于不可用状态。

    默认消息采用的是自动应答,所以我们要想实现消息消费过程中不丢失,需要把自动应答改为手动应答。

    消息应答的方法

    • A.Channel.basicAck(用于肯定确认)
      • RabbitMQ 已知道该消息并且成功的处理消息,可以将其丢弃了
    • B.Channel.basicNack(用于否定确认)
    • C.Channel.basicReject(用于否定确认)
      • 与 Channel.basicNack 相比少一个参数。 不处理该消息了直接拒绝,可以将其丢弃了
    channel.basicAck()
    
    void basicNack(long deliveryTag, boolean multiple, boolean requeue) throws IOException;
      参数:
    	deliveryTag:该消息的index
    	multiple:是否批量处理.true:将一次性ack所有小于deliveryTag的消息
    	requeue:被拒绝的是否重新入队列
    

    发布确认

    发布确认原理

    • 生产者将信道设置成 confirm 模式,一旦信道进入 confirm 模式,所有在该信道上面发布的消息都将会被指派一个唯一的 ID(从 1 开始),一旦消息被投递到所有匹配的队列之后,broker 就会发送一个确认给生产者(包含消息的唯一 ID),这就使得生产者知道消息已经正确到达目的队列了,如果消息和队列是可持久化的,那么确认消息会在将消息写入磁盘之后发出,broker 回传给生产者的确认消息中 delivery-tag 域包含了确认消息的序列号,此外 broker 也可以设置basic.ack 的multiple 域,表示到这个序列号之前的所有消息都已经得到了处理。
    • confirm 模式最大的好处在于他是异步的,一旦发布一条消息,生产者应用程序就可以在等信道返回确认的同时继续发送下一条消息,当消息最终得到确认之后,生产者应用便可以通过回调方法来处理该确认消息,如果 RabbitMQ 因为自身内部错误导致消息丢失,就会发送一条 nack 消息,生产者应用程序同样可以在回调方法中处理该 nack 消息。

    3 种发布确认

    单独发布消息

    • 同步等待确认,简单,但吞吐量非常有限。

    批量发布消息

    • 批量同步等待确认,简单,合理的吞吐量,一旦出现问题但很难推断出是那条消息出现了问题。

    异步处理

    • 最佳性能和资源使用,在出现错误的情况下可以很好地控制,但是实现起来稍微难些

    交换机

    Exchanges 概念

    • RabbitMQ 消息传递模型的核心思想是: 生产者生产的消息从不会直接发送到队列。实际上,通常生产者甚至都不知道这些消息传递传递到了哪些队列中。
    • 相反,生产者只能将消息发送到交换机(exchange),交换机工作的内容非常简单,一方面它接收来自生产者的消息,另一方面将它们推入队列。交换机必须确切知道如何处理收到的消息。是应该把这些消息放到特定队列还是说把他们到许多队列中还是说应该丢弃它们。这就的由交换机的类型来决定。
      在这里插入图片描述

    Exchanges 的类型

    • 总共有以下类型:直接(direct), 主题(topic) ,标题(headers) , 扇出(fanout)。
      • fanout:这种类型不处理路由键 (RoutingKey),很像子网广播,每台子网内的主机都获得了一份复制的消息,发布 / 订阅模式就是指使用 fanout 交换机类型,fanout 类型交换机转发消息是最快的。
      • direct:模式处理路由键,需要路由键完全匹配的队列才能收到消息,路由模式使用的是 direct 类型的交换机。
      • topic:将路由键和某模式进行匹配。主题模式使用的是 topic 类型的交换机。

    你知道的越多,你不知道的越多。

    展开全文
  • 消息队列”是在消息的传输过程中保存消息的容器。 “消息”是在两台计算机间传送的数据单位。消息可以非常简单,例如只包含文本字符串;也可以更复杂,可能包含嵌入对象。 消息被发送到队列中。“消息队列”是在...

    “消息队列”是在消息的传输过程中保存消息的容器。
    “消息”是在两台计算机间传送的数据单位。消息可以非常简单,例如只包含文本字符串;也可以更复杂,可能包含嵌入对象。
    消息被发送到队列中。“消息队列”是在消息的传输过程中保存消息的容器。消息队列管理器在将消息从它的源中继到它的目标时充当中间人。队列的主要目的是提供路由并保证消息的传递;如果发送消息时接收者不可用,消息队列会保留消息,直到可以成功地传递它。

    为什么会需要消息队列(MQ)?

    主要原因是由于在高并发环境下,由于来不及同步处理,请求往往会发生堵塞,比如说,大量的insert,update之类的请求同时到达MySQL,直接导致无数的行锁表锁,甚至最后请求会堆积过多,从而触发too many connections错误。通过使用消息队列,我们可以异步处理请求,从而缓解系统的压力。

    美国计算机科学家,LaTex的作者Leslie Lamport说:“分布式系统就是这样一个系统,系统中一个你甚至都不知道的计算机出了故障,却可能导致你自己的计算机不可用。”一语道破了开发分布式系统的玄机,那就是它的复杂与不可控。所以Martin Fowler强调:分布式调用的第一原则就是不要分布式。这句话看似颇具哲理,然而就企业应用系统而言,只要整个系统在不停地演化,并有多个子系统共同存在时,这条原则就会被迫打破。盖因为在当今的企业应用系统中,很难寻找到完全不需要分布式调用的场景。Martin Fowler提出的这条原则,一方面是希望设计者能够审慎地对待分布式调用,另一方面却也是分布式系统自身存在的缺陷所致。无论是CORBA,还是EJB 2;无论是RPC平台,还是Web Service,都因为驻留在不同进程空间的分布式组件,而引入额外的复杂度,并可能对系统的效率、可靠性、可预测性等诸多方面带来负面的影响。

    然而,不可否认的是在企业应用系统领域,我们总是会面对不同系统之间的通信、集成与整合,尤其当面临异构系统时,这种分布式的调用与通信变得越重要,它在架构设计中就更加凸显其价值。并且,从业务分析与架构质量的角度来讲,我们也希望在系统架构中尽可能地形成对服务的重用,通过独立运行在进程中服务的形式,彻底解除客户端与服务端的耦合。这常常是架构演化的必然道路。在我的同事陈金洲发表在InfoQ上的文章《架构腐化之谜》中,就认为可以通过“将独立的模块放入独立的进程”来解决架构因为代码规模变大而腐化的问题。

    随着网络基础设施的逐步成熟,从RPC进化到Web Service,并在业界开始普遍推行SOA,再到后来的RESTful平台以及云计算中的PaaS与SaaS概念的推广,分布式架构在企业应用中开始呈现出不同的风貌,然而殊途同归,这些分布式架构的目标仍然是希望回到建造巴别塔的时代,系统之间的交流不再为不同语言与平台的隔阂而产生障碍。正如Martin Fowler在《企业集成模式》一书的序中写道:“集成之所以重要是因为相互独立的应用是没有生命力的。我们需要一种技术能将在设计时并未考虑互操作的应用集成起来,打破它们之间的隔阂,获得比单个应用更多的效益”。这或许是分布式架构存在的主要意义。
     

    目录

    1. 消息队列概述
    2. 消息队列应用场景
    3. 消息中间件示例
    4. JMS消息服务
    5. 常用消息队列
    6. 参考(推荐)资料
    7. 本次分享总结

    一、消息队列概述

    消息队列中间件是分布式系统中重要的组件,主要解决应用耦合,异步消息,流量削锋等问题。实现高性能,高可用,可伸缩和最终一致性架构。是大型分布式系统不可缺少的中间件。

    目前在生产环境,使用较多的消息队列有ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ等。

    二、消息队列应用场景

    以下介绍消息队列在实际应用中常用的使用场景。异步处理,应用解耦,流量削锋和消息通讯四个场景。

    2.1异步处理

    场景说明:用户注册后,需要发注册邮件和注册短信。传统的做法有两种1.串行的方式;2.并行方式。

    (1)串行方式:将注册信息写入数据库成功后,发送注册邮件,再发送注册短信。以上三个任务全部完成后,返回给客户端。

     

    (2)并行方式:将注册信息写入数据库成功后,发送注册邮件的同时,发送注册短信。以上三个任务完成后,返回给客户端。与串行的差别是,并行的方式可以提高处理的时间。

     

    假设三个业务节点每个使用50毫秒钟,不考虑网络等其他开销,则串行方式的时间是150毫秒,并行的时间可能是100毫秒。

    因为CPU在单位时间内处理的请求数是一定的,假设CPU1秒内吞吐量是100次。则串行方式1秒内CPU可处理的请求量是7次(1000/150)。并行方式处理的请求量是10次(1000/100)。

     

    小结:如以上案例描述,传统的方式系统的性能(并发量,吞吐量,响应时间)会有瓶颈。如何解决这个问题呢?

    引入消息队列,将不是必须的业务逻辑,异步处理。改造后的架构如下:

     

    按照以上约定,用户的响应时间相当于是注册信息写入数据库的时间,也就是50毫秒。注册邮件,发送短信写入消息队列后,直接返回,因此写入消息队列的速度很快,基本可以忽略,因此用户的响应时间可能是50毫秒。因此架构改变后,系统的吞吐量提高到每秒20 QPS。比串行提高了3倍,比并行提高了两倍。

    2.2应用解耦

    场景说明:用户下单后,订单系统需要通知库存系统。传统的做法是,订单系统调用库存系统的接口。如下图:

     

    传统模式的缺点:

    1)  假如库存系统无法访问,则订单减库存将失败,从而导致订单失败;

    2)  订单系统与库存系统耦合;

    如何解决以上问题呢?引入应用消息队列后的方案,如下图:

     

    • 订单系统:用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户订单下单成功。
    • 库存系统:订阅下单的消息,采用拉/推的方式,获取下单信息,库存系统根据下单信息,进行库存操作。
    • 假如:在下单时库存系统不能正常使用。也不影响正常下单,因为下单后,订单系统写入消息队列就不再关心其他的后续操作了。实现订单系统与库存系统的应用解耦。

    2.3流量削锋

    流量削锋也是消息队列中的常用场景,一般在秒杀或团抢活动中使用广泛。

    应用场景:秒杀活动,一般会因为流量过大,导致流量暴增,应用挂掉。为解决这个问题,一般需要在应用前端加入消息队列。

    1. 可以控制活动的人数;
    2. 可以缓解短时间内高流量压垮应用;

     

    1. 用户的请求,服务器接收后,首先写入消息队列。假如消息队列长度超过最大数量,则直接抛弃用户请求或跳转到错误页面;
    2. 秒杀业务根据消息队列中的请求信息,再做后续处理。

    2.4日志处理

    日志处理是指将消息队列用在日志处理中,比如Kafka的应用,解决大量日志传输的问题。架构简化如下:

     

    • 日志采集客户端,负责日志数据采集,定时写受写入Kafka队列;
    • Kafka消息队列,负责日志数据的接收,存储和转发;
    • 日志处理应用:订阅并消费kafka队列中的日志数据;


    以下是新浪kafka日志处理应用案例:

     

    (1)Kafka:接收用户日志的消息队列。

    (2)Logstash:做日志解析,统一成JSON输出给Elasticsearch。

    (3)Elasticsearch:实时日志分析服务的核心技术,一个Schemaless,实时的数据存储服务,通过index组织数据,兼具强大的搜索和统计功能。

    (4)Kibana:基于Elasticsearch的数据可视化组件,超强的数据可视化能力是众多公司选择ELK stack的重要原因。

    2.5消息通讯

    消息通讯是指,消息队列一般都内置了高效的通信机制,因此也可以用在纯的消息通讯。比如实现点对点消息队列,或者聊天室等。

    点对点通讯:

     

    客户端A和客户端B使用同一队列,进行消息通讯。

    聊天室通讯:

     

    客户端A,客户端B,客户端N订阅同一主题,进行消息发布和接收。实现类似聊天室效果。

    以上实际是消息队列的两种消息模式,点对点或发布订阅模式。模型为示意图,供参考。

    三、消息中间件示例

    3.1电商系统

     

    消息队列采用高可用,可持久化的消息中间件。比如Active MQ,Rabbit MQ,Rocket Mq。(1)应用将主干逻辑处理完成后,写入消息队列。消息发送是否成功可以开启消息的确认模式。(消息队列返回消息接收成功状态后,应用再返回,这样保障消息的完整性)

    (2)扩展流程(发短信,配送处理)订阅队列消息。采用推或拉的方式获取消息并处理。

    (3)消息将应用解耦的同时,带来了数据一致性问题,可以采用最终一致性方式解决。比如主数据写入数据库,扩展应用根据消息队列,并结合数据库方式实现基于消息队列的后续处理。

    3.2日志收集系统

     

    分为Zookeeper注册中心,日志收集客户端,Kafka集群和Storm集群(OtherApp)四部分组成。

    • Zookeeper注册中心,提出负载均衡和地址查找服务;
    • 日志收集客户端,用于采集应用系统的日志,并将数据推送到kafka队列;
    • Kafka集群:接收,路由,存储,转发等消息处理;

    Storm集群:与OtherApp处于同一级别,采用拉的方式消费队列中的数据;

    四、JMS消息服务

    讲消息队列就不得不提JMS 。JMS(JAVA Message Service,java消息服务)API是一个消息服务的标准/规范,允许应用程序组件基于JavaEE平台创建、发送、接收和读取消息。它使分布式通信耦合度更低,消息服务更加可靠以及异步性。

    在EJB架构中,有消息bean可以无缝的与JM消息服务集成。在J2EE架构模式中,有消息服务者模式,用于实现消息与应用直接的解耦。

    4.1消息模型

    在JMS标准中,有两种消息模型P2P(Point to Point),Publish/Subscribe(Pub/Sub)。

    4.1.1 P2P模式

     

    P2P模式包含三个角色:消息队列(Queue),发送者(Sender),接收者(Receiver)。每个消息都被发送到一个特定的队列,接收者从队列中获取消息。队列保留着消息,直到他们被消费或超时。

     

    P2P的特点

    • 每个消息只有一个消费者(Consumer)(即一旦被消费,消息就不再在消息队列中)
    • 发送者和接收者之间在时间上没有依赖性,也就是说当发送者发送了消息之后,不管接收者有没有正在运行,它不会影响到消息被发送到队列
    • 接收者在成功接收消息之后需向队列应答成功

     

    如果希望发送的每个消息都会被成功处理的话,那么需要P2P模式。

    4.1.2 Pub/sub模式

     

    包含三个角色主题(Topic),发布者(Publisher),订阅者(Subscriber) 。多个发布者将消息发送到Topic,系统将这些消息传递给多个订阅者。

    Pub/Sub的特点

    • 每个消息可以有多个消费者
    • 发布者和订阅者之间有时间上的依赖性。针对某个主题(Topic)的订阅者,它必须创建一个订阅者之后,才能消费发布者的消息。
    • 为了消费消息,订阅者必须保持运行的状态。

     

    为了缓和这样严格的时间相关性,JMS允许订阅者创建一个可持久化的订阅。这样,即使订阅者没有被激活(运行),它也能接收到发布者的消息。

    如果希望发送的消息可以不被做任何处理、或者只被一个消息者处理、或者可以被多个消费者处理的话,那么可以采用Pub/Sub模型。

    4.2消息消费

    在JMS中,消息的产生和消费都是异步的。对于消费来说,JMS的消息者可以通过两种方式来消费消息。

    (1)同步

    订阅者或接收者通过receive方法来接收消息,receive方法在接收到消息之前(或超时之前)将一直阻塞;

    (2)异步

    订阅者或接收者可以注册为一个消息监听器。当消息到达之后,系统自动调用监听器的onMessage方法。

     

    JNDI:Java命名和目录接口,是一种标准的Java命名系统接口。可以在网络上查找和访问服务。通过指定一个资源名称,该名称对应于数据库或命名服务中的一个记录,同时返回资源连接建立所必须的信息。

    JNDI在JMS中起到查找和访问发送目标或消息来源的作用。

    4.3JMS编程模型

    (1) ConnectionFactory

    创建Connection对象的工厂,针对两种不同的jms消息模型,分别有QueueConnectionFactory和TopicConnectionFactory两种。可以通过JNDI来查找ConnectionFactory对象。

    (2) Destination

    Destination的意思是消息生产者的消息发送目标或者说消息消费者的消息来源。对于消息生产者来说,它的Destination是某个队列(Queue)或某个主题(Topic);对于消息消费者来说,它的Destination也是某个队列或主题(即消息来源)。

    所以,Destination实际上就是两种类型的对象:Queue、Topic可以通过JNDI来查找Destination。

    (3) Connection

    Connection表示在客户端和JMS系统之间建立的链接(对TCP/IP socket的包装)。Connection可以产生一个或多个Session。跟ConnectionFactory一样,Connection也有两种类型:QueueConnection和TopicConnection。

    (4) Session

    Session是操作消息的接口。可以通过session创建生产者、消费者、消息等。Session提供了事务的功能。当需要使用session发送/接收多个消息时,可以将这些发送/接收动作放到一个事务中。同样,也分QueueSession和TopicSession。

    (5) 消息的生产者

    消息生产者由Session创建,并用于将消息发送到Destination。同样,消息生产者分两种类型:QueueSender和TopicPublisher。可以调用消息生产者的方法(send或publish方法)发送消息。

    (6) 消息消费者

    消息消费者由Session创建,用于接收被发送到Destination的消息。两种类型:QueueReceiver和TopicSubscriber。可分别通过session的createReceiver(Queue)或createSubscriber(Topic)来创建。当然,也可以session的creatDurableSubscriber方法来创建持久化的订阅者。

    (7) MessageListener

    消息监听器。如果注册了消息监听器,一旦消息到达,将自动调用监听器的onMessage方法。EJB中的MDB(Message-Driven Bean)就是一种MessageListener。

     

    深入学习JMS对掌握JAVA架构,EJB架构有很好的帮助,消息中间件也是大型分布式系统必须的组件。本次分享主要做全局性介绍,具体的深入需要大家学习,实践,总结,领会。

    五、常用消息队列

    一般商用的容器,比如WebLogic,JBoss,都支持JMS标准,开发上很方便。但免费的比如Tomcat,Jetty等则需要使用第三方的消息中间件。本部分内容介绍常用的消息中间件(Active MQ,Rabbit MQ,Zero MQ,Kafka)以及他们的特点。

    5.1 ActiveMQ

    ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线。ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现,尽管JMS规范出台已经是很久的事情了,但是JMS在当今的J2EE应用中间仍然扮演着特殊的地位。

    ActiveMQ特性如下:

    ⒈ 多种语言和协议编写客户端。语言: Java,C,C++,C#,Ruby,Perl,Python,PHP。应用协议: OpenWire,Stomp REST,WS Notification,XMPP,AMQP

    ⒉ 完全支持JMS1.1和J2EE 1.4规范 (持久化,XA消息,事务)

    ⒊ 对Spring的支持,ActiveMQ可以很容易内嵌到使用Spring的系统里面去,而且也支持Spring2.0的特性

    ⒋ 通过了常见J2EE服务器(如 Geronimo,JBoss 4,GlassFish,WebLogic)的测试,其中通过JCA 1.5 resource adaptors的配置,可以让ActiveMQ可以自动的部署到任何兼容J2EE 1.4 商业服务器上

    ⒌ 支持多种传送协议:in-VM,TCP,SSL,NIO,UDP,JGroups,JXTA

    ⒍ 支持通过JDBC和journal提供高速的消息持久化

    ⒎ 从设计上保证了高性能的集群,客户端-服务器,点对点

    ⒏ 支持ajax

    ⒐ 支持与Axis的整合

    ⒑ 可以很容易得调用内嵌JMS provider,进行测试

    5.2 RabbitMQ

    RabbitMQ是流行的开源消息队列系统,用erlang语言开发。RabbitMQ是AMQP(高级消息队列协议)的标准实现。支持多种客户端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX,持久化。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。

    结构图如下:

    几个重要概念:

    Broker:简单来说就是消息队列服务器实体。

      Exchange:消息交换机,它指定消息按什么规则,路由到哪个队列。

      Queue:消息队列载体,每个消息都会被投入到一个或多个队列。

      Binding:绑定,它的作用就是把exchange和queue按照路由规则绑定起来。

      Routing Key:路由关键字,exchange根据这个关键字进行消息投递。

      vhost:虚拟主机,一个broker里可以开设多个vhost,用作不同用户的权限分离。

      producer:消息生产者,就是投递消息的程序。

      consumer:消息消费者,就是接受消息的程序。

      channel:消息通道,在客户端的每个连接里,可建立多个channel,每个channel代表一个会话任务。

    消息队列的使用过程,如下:

    (1)客户端连接到消息队列服务器,打开一个channel。

    (2)客户端声明一个exchange,并设置相关属性。

    (3)客户端声明一个queue,并设置相关属性。

    (4)客户端使用routing key,在exchange和queue之间建立好绑定关系。

    (5)客户端投递消息到exchange。

    exchange接收到消息后,就根据消息的key和已经设置的binding,进行消息路由,将消息投递到一个或多个队列里。

    5.3 ZeroMQ

    号称史上最快的消息队列,它实际类似于Socket的一系列接口,他跟Socket的区别是:普通的socket是端到端的(1:1的关系),而ZMQ却是可以N:M 的关系,人们对BSD套接字的了解较多的是点对点的连接,点对点连接需要显式地建立连接、销毁连接、选择协议(TCP/UDP)和处理错误等,而ZMQ屏蔽了这些细节,让你的网络编程更为简单。ZMQ用于node与node间的通信,node可以是主机或者是进程。

    引用官方的说法: “ZMQ(以下ZeroMQ简称ZMQ)是一个简单好用的传输层,像框架一样的一个socket library,他使得Socket编程更加简单、简洁和性能更高。是一个消息处理队列库,可在多个线程、内核和主机盒之间弹性伸缩。ZMQ的明确目标是“成为标准网络协议栈的一部分,之后进入Linux内核”。现在还未看到它们的成功。但是,它无疑是极具前景的、并且是人们更加需要的“传统”BSD套接字之上的一 层封装。ZMQ让编写高性能网络应用程序极为简单和有趣。”

    特点是:

    • 高性能,非持久化;
    • 跨平台:支持Linux、Windows、OS X等。
    • 多语言支持; C、C++、Java、.NET、Python等30多种开发语言。
    • 可单独部署或集成到应用中使用;
    • 可作为Socket通信库使用。

    与RabbitMQ相比,ZMQ并不像是一个传统意义上的消息队列服务器,事实上,它也根本不是一个服务器,更像一个底层的网络通讯库,在Socket API之上做了一层封装,将网络通讯、进程通讯和线程通讯抽象为统一的API接口。支持“Request-Reply “,”Publisher-Subscriber“,”Parallel Pipeline”三种基本模型和扩展模型。

     

    ZeroMQ高性能设计要点:

    1、无锁的队列模型

       对于跨线程间的交互(用户端和session)之间的数据交换通道pipe,采用无锁的队列算法CAS;在pipe两端注册有异步事件,在读或者写消息到pipe的时,会自动触发读写事件。

    2、批量处理的算法

       对于传统的消息处理,每个消息在发送和接收的时候,都需要系统的调用,这样对于大量的消息,系统的开销比较大,zeroMQ对于批量的消息,进行了适应性的优化,可以批量的接收和发送消息。

    3、多核下的线程绑定,无须CPU切换

       区别于传统的多线程并发模式,信号量或者临界区, zeroMQ充分利用多核的优势,每个核绑定运行一个工作者线程,避免多线程之间的CPU切换开销。

    5.4 Kafka

    Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据。 这种动作(网页浏览,搜索和其他用户的行动)是在现代网络上的许多社会功能的一个关键因素。 这些数据通常是由于吞吐量的要求而通过处理日志和日志聚合来解决。 对于像Hadoop的一样的日志数据和离线分析系统,但又要求实时处理的限制,这是一个可行的解决方案。Kafka的目的是通过Hadoop的并行加载机制来统一线上和离线的消息处理,也是为了通过集群机来提供实时的消费。

    Kafka是一种高吞吐量的分布式发布订阅消息系统,有如下特性:

    • 通过O(1)的磁盘数据结构提供消息的持久化,这种结构对于即使数以TB的消息存储也能够保持长时间的稳定性能。(文件追加的方式写入数据,过期的数据定期删除)
    • 高吞吐量:即使是非常普通的硬件Kafka也可以支持每秒数百万的消息。
    • 支持通过Kafka服务器和消费机集群来分区消息。
    • 支持Hadoop并行数据加载。

     

    Kafka相关概念

    • Broker

    Kafka集群包含一个或多个服务器,这种服务器被称为broker[5]

    • Topic

    每条发布到Kafka集群的消息都有一个类别,这个类别被称为Topic。(物理上不同Topic的消息分开存储,逻辑上一个Topic的消息虽然保存于一个或多个broker上但用户只需指定消息的Topic即可生产或消费数据而不必关心数据存于何处)

    • Partition

    Parition是物理上的概念,每个Topic包含一个或多个Partition.

    • Producer

    负责发布消息到Kafka broker

    • Consumer

    消息消费者,向Kafka broker读取消息的客户端。

    • Consumer Group

    每个Consumer属于一个特定的Consumer Group(可为每个Consumer指定group name,若不指定group name则属于默认的group)。

     

    一般应用在大数据日志处理或对实时性(少量延迟),可靠性(少量丢数据)要求稍低的场景使用。

    六、参考资料

    以下是本次分享参考的资料和推荐大家参考的资料。

     

    参考资料(可参考资料):

    (1)Jms

    http://blog.sina.com.cn/s/blog_3fba24680100r777.html

    http://blog.csdn.net/jiuqiyuliang/article/details/46701559(深入浅出JMS(一)--JMS基本概念)

    (2)RabbitMQ

    http://baike.baidu.com/link?url=s2cU-QgOsXan7j0AM5qxxlmruz6WEeBQXX-Bbk0O3F5jt9Qts2uYQARxQxl7CBT2SO2NF2VkzX_XZLqU-CTaPa

    http://blog.csdn.net/sun305355024sun/article/details/41913105

    (3)Zero MQ

    http://www.searchtb.com/2012/08/zeromq-primer.html

    http://blog.csdn.net/yangbutao/article/details/8498790

    http://wenku.baidu.com/link?url=yYoiZ_pYPCuUxEsGQvMMleY08bcptZvwF3IMHo2W1i-ti66YXXPpLLJBGXboddwgGBnOehHiUdslFhtz7RGZYkrtMQQ02DV5sv9JFF4LZnK

    (4)Kafka

    http://baike.baidu.com/link?url=qQXyqvPQ1MVrw9WkOGSGEfSX1NHy4unsgc4ezzJwU94SrPuVnrKf2tbm4SllVaN3ArGGxV_N5hw8JTT2-lw4QK

    http://www.infoq.com/cn/articles/apache-kafka/

    http://www.mincoder.com/article/3942.shtml

     

    七、本次分享总结

    以上是本周的分享,主要讲解了消息队列概述,常用消息队列应用场景(异步处理,应用解耦,流量削锋,日志处理和消息通讯),JMS Java消息服务,以及目前流行的几款消息队列介绍。最后演示了两个使用消息中间件的架构。

    因为时间关系,有些讲解的不细致,大家可以问下度娘/Google,希望本次分享对大家有帮助。



    链接:http://www.365jz.com/article/23947 

    展开全文
  • 一条CAN报文到底有多少位?

    千次阅读 2020-12-28 19:46:17
    CAN-bus总线是应用最广泛的现场总线之一,而很多非常熟练的CAN工程师,面对一条CAN报文到底有多少位的问题时,却不能非常准确地回答。今天我们就从最基本的帧格式来解惑一条CAN报文的到底有多少位。CAN报文帧分为几...
  • 消息中间件(消息队列)

    千次阅读 2022-02-17 13:52:30
    消息中间件
  • 1、Kafka概述 ...个典型的 kafka 集群包含若干 Producer,若干个 Broker(kafka )、若干个 Consumer Group,以及个 zookeeper 集群。kafka 通过 zookeeper 管理集群配置及服务协同。Producer 使
  • RabbitMQ消息模型详解

    千次阅读 2022-03-03 15:03:32
    RabbitMQ消息模型详解,原理详解,代码展示。其中包括简单消息模型,工作模型,订阅发布模型,订阅模型-Fanout,订阅模型-Direct。
  • 什么消息队列

    万次阅读 多人点赞 2018-03-01 13:58:00
    什么消息队列 消息(Message)是指在应用之间传送的数据,消息可以非常简单,比如只包含文本字符串,也可以更复杂,可能包含嵌入对象。 消息队列(Message Queue)是种应用间的通信方式,消息发送后可以...
  • 完整的HTTP请求过程详细

    万次阅读 多人点赞 2018-05-29 14:41:54
    完整的HTTP请求过程 整个流程 域名解析 —&gt; 与服务器建立连接 —&gt; 发起HTTP请求 —&gt; 服务器响应HTTP请求,浏览器得到html代码 —&gt; 浏览器解析html代码,并请求html代码中的资源...
  • RocketMQ(五)RocketMQ消息生产及消息储存机制
  • 文章目录: 消息队列如何选型,各自的优缺点? 如何保证其可用性 如何保证消息不丢失?...我们项目中常常用到消息队列,那么为什么我们需要使用消息队列,用了它对系统带来了什么好处了?解决了什么问题,还是是...
  • MQ的优点及使用场景: 消息总线(Message Queue),后文称MQ,是种跨进程的通信机制,用于上下游传递消息...什么时候不使用消息总线? 既然MQ是互联网分层架构中的解耦利器,那所有通讯都使用MQ岂不是很好?这是...
  • 微信小程序订阅消息

    千次阅读 热门讨论 2020-03-02 15:19:21
    消息能力是小程序能力中的重要组成,以便实现服务的闭环和更优的体验。此前的小程序模板消息接口于2020年1月10日下线,2.10.0 版本开始,开发版和体验版小程序将禁止使用模板消息 fomrId。开发者可使用订阅消息功能...
  • 史上最全的消息队列总结,我确实不信你能看完!!
  • 什么是分布式消息中间件? 消息中间件的作用是什么消息中间件的使用场景是什么消息中间件选型? 初识 Kafka Kafka知识树 1 Why Kafka 活动跟踪:Kafka 可以用来跟踪用户行为,比如我们经常回去淘宝购物,你...
  • Java架构之消息队列 ():消息队列的概述

    万次阅读 多人点赞 2018-10-08 16:09:38
     消息队列的概述 二、消息队列之RabbitMQ的使用 三、消息队列之Kafka的使用 四、消息队列之RabbitMQ的原理详解 五、消息队列之Kafka的原理详解 六、消息队列之面试集锦 1.消息队列的概述 消息队列...
  • 消息队列及消息中间件

    千次阅读 2018-08-03 10:08:35
    它具有 低耦合、可靠投递、广播、流量控制、最终一致性 等系列功能。 当前使用较多的 消息队列 有 RabbitMQ、RocketMQ、ActiveMQ、Kafka、ZeroMQ、MetaMQ 等,而部分 数据库 如 Redis、MySQL 以及 phxsql ...
  • 消息队列:RabbitMQ

    千次阅读 多人点赞 2022-01-23 11:04:54
    总结了消息中间件的特性、应用以及相关问题。详细介绍了如何使用RabbitMQ解决分布式相关问题。
  • 消息推送作为移动 APP 运营中的项关键技术,已经被越来越广泛的运用。本文追溯了推送技术的发展历史,剖析了其核心原理,并对推送服务的关键技术进行深入剖析,围绕消息推送时产生的服务不稳定性,消息丢失、延迟...
  • 大家好,我是 Tom哥~马上要开启国庆小长假了,祝大家节日快乐,吃喝玩乐走起~为了便于大家查找问题,了解全貌,整理个目录,我们可以快速全局了解关于消息队列,面试官一般会问哪些问题。本篇文章的目录:消息队列的...
  • Java面试突击系列():消息队列的面试连环炮

    千次阅读 多人点赞 2020-11-18 10:39:32
    我们有一个订单系统,订单系统会每次下一个新订单的时候,就会发送一条消息到ActiveMQ里面去,后台有一个库存系统,负责获取消息,然后更新库存。 为什么使用消息队列? 你的订单系统不发送消息到MQ,而是直接...
  • 听叔句劝,消息队列的水太深,你把握不住!

    千次阅读 多人点赞 2021-05-19 10:10:21
    很多人在做架构设计时往往会“过度设计”,简单问题复杂化,上来就引堆中间件,我想大概原因主要有下面两点: 为了秀(学)技术而架构 我们常说技术是为业务服务的,不能为了技术而技术,为了秀技术引入堆复杂...
  • 消息队列Kafka

    千次阅读 2021-02-06 16:28:11
    Kafka 简介及使用场景 写在前面 我们提到消息中间件,往往都会聊到,RabbitMQ,RocketMQ,Kafka。 对于刚入门消息中间件,...Kafka 是最初 Linkedin 公司开发,是个分布式、支持分区的(partition)、多副本的(re
  • Android全面解析之浅及深Handler消息机制

    千次阅读 多人点赞 2020-10-08 21:17:45
    关于Handler的博客可谓是俯拾皆是,而这也是个老生常谈的话题,可见的他非常基础,也非常重要。但很多的博客,却很少有从入门开始介绍,这在我开始学习的时候就直接给我讲Looper讲阻塞,非常难以理解。同时,也...
  • 小程序订阅消息功能介绍消息能力是小程序能力中的重要组成,我们为开发者提供了订阅消息能力,以便实现服务的闭环和更优的体验。 订阅消息推送位置:服务通知订阅消息下发条件:用户自主订阅订阅消息卡片跳转能力:...
  • 、RocketMQ 支持 3 种消息发送方式 : 1、同步消息(sync message ) producer向 broker 发送消息,执行 API 时同步等待, 直到broker 服务器返回发送结果 。 2、异步消息(async message) producer向 broker ...
  • RabbitMQ消息队列常见面试题总结

    万次阅读 多人点赞 2021-03-22 02:46:39
    1、什么消息队列?消息队列的优缺点? 2、Kafka、ActiveMQ、RabbitMQ、RocketMQ的区别? 3、如何保证消息不被重复消费? 4、如何保证消息不丢失,进行可靠性传输? 5、如何保证消息的有序性? 6、如何处理消息堆积...
  • Kafka、RabbitMQ、RocketMQ等 消息中间件 介绍和对比

    万次阅读 多人点赞 2019-09-05 17:59:00
    文章目录1、前言2、概念2.1、MQ简介2.2、MQ特点2.2.1、先进先出2.2.2、发布订阅2.2.3、持久化2.2.4、分布式3、消息中间件性能究竟哪家强?3.1、Kafka3.2、RabbitMQ3.3、RocketMQ4、测试4.1、测试目的4.2、测试场景...
  • 消息队列中间件是分布式系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构。目前使用较多的消息队列有ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 241,791
精华内容 96,716
关键字:

一条完整的消息由什么组成