扫盲消息队列 | 消息中间件 | Kafka

先吐槽

我真的写技术文章写到怀疑人生,我翻看历史发文记录,只要我一本正经的写的技术文章,都没人看,但是!一发闲扯淡的内容,阅读量肯定是技术文的好几倍(读者爸爸们别这么搞嘛)

这说明啥?说明学习还是太枯燥无趣了,但是你想想,每天就网上看闲扯淡的文章,这咋能进大厂嘛!对吧。

再接受几次这样的打击我都不想写技术文章了。哎!不过我也就嘴上说说,我还是会坚持写下去的。

反正你们有没有认真看我不知道,我写完一遍这个文章,每个知识点细节我都滚瓜乱熟了,因为都是我一个字一个字敲出来的。

开始正文吧!21世纪的流水线工人,消息队列是一定要会的。

我真的不能再贴心了!!!!

背景

image-20200420194331765

分布式微服务系统下,凡是可以“排队”去做的事情,都可以使用消息队列。网上买东西同样也需要“排队付款”,但是有人说,我点确认付款后马上就显示成功了,没感觉到排队呀?其实在后台系统中是排了,只不过排队的时间对于人来说有点短,可能1-2秒就结束了,但是对于计算机来说,这1-2秒的时间很长了。

大型分布式系统建设中,消息队列主要解决应用耦合、异步消息、流量削锋等问题。实现高性能、高可用、可伸缩和最终一致性架构。是大型分布式系统不可缺少的中间件。消息发布者只管把消息发布到 MQ 中而不用管谁来取,消息使用者只管从 MQ 中取消息而不管是谁发布的。这样发布者和使用者都不用知道对方的存在。

Web应用程序毫无疑问有大量的代码执行HTTP请求/响应周期的一部分。这适用于更快的任务耗费数百毫秒内或更少。然而,有些处理,还需要耗时更多甚至最终会是一两秒钟缓慢的同步执行,在如此长时间的调用流转中,肯定有一些调用是可以不同步的,如下单送积分,用户下单是最主要的,送积分的操作可以异步去做,订单支付成功给用户的短信通知,返回支付订单进入下一环节更更好,短信通知可以异步去发送,为了应对诸如此类的异步操作,消息队列这门技术应运而生。

message-queue-example

在计算机科学中,消息队列(Message queue)是一种进程间通信或同一进程的不同线程间的通信方式。实际上,消息队列常常保存在链表结构中。[2]拥有权限的进程可以向消息队列中写入或读取消息。

目前,有很多消息队列有很多开源的实现,包括JBoss Messaging、JORAM、Apache ActiveMQ、Sun Open Message Queue、RabbitMQ[3]、IBM MQ[4]、Apache Qpid[5]、Apache RocketMQ[6]和HTTPSQS。[7]

说了这么多没用的,消息队列到底在企业里怎么用的?

我就直接上两段代码吧

发送一条消息demo

public class MqProducer {private final Logger LOG = LoggerFactory.getLogger(MqProducer.class);@Resourceprivate Producer payProducer;public void sendPayMsg(String msg) {try {LOG.debug("send msg:{}", msg);payProducer.send(msg);//发送出去一条消息。} catch (MQException e) {LOG.error("mq消息异常 message:{}", msg, e);}}
}

接收一个消息demo

public class DemoConsumer {/*** 注意:服务端对单ip创建相同主题相同队列的消费者实例数有限制,超过100个拒绝创建.* */private static IConsumerProcessor consumer;public static void main(String[] args) throws Exception {Properties properties = new Properties();properties.setProperty(ConsumerConstants.SubscribeGroup, "dache.risk.log.queue.v2");// 创建topic对应的consumer对象(注意每次build调用会产生一个新的实例)consumer = KafkaClient.buildConsumerFactory(properties, "topic.xxx.xxx");// 调用recvMessageWithParallel设置listenerconsumer.recvMessageWithParallel(String.class, new IMessageListener() {@Overridepublic ConsumeStatus recvMessage(Message message, MessagetContext context) {//TODO:业务侧的消费逻辑代码try {System.out.println("message=[" + message.getBody() + "]  partition=" + message.getParttion());} catch (Exception e) {e.printStackTrace();}return ConsumeStatus.CONSUME_SUCCESS;}});}
}

消息长什么样子?

{"businessType":1,"cityId":10,"ctime":1567426767077,"dataKey":20190902,"logType":1,"phone":"13212341234","uid":12345678,"userType":1,"uuid":"32EA02C86D78863"}

代码呢,就是普通的java代码,只不过引入了一个kafka的jar,消息就是json串,使用消息队列真的就这么点代码,剩下的内容都是业务代码了。

新手关注消息队列,主要关注两个最重要的概念就行了,一个是生产者,一个是消费者,两者的关系和我们日常发短信一样,短信是通过手机号发送接收,系统间消息是通过topic,可以理解成手机号。

  • Producer消息的生产方,如支付系统确认用户已经支付,支付系统要通知订单系统和物流系统,支付系统就是生产者。

  • Consumer消费的接收方,Producer 的案例中,物流系统就是消费方,前两个都比较简单,我就不多说了。

  • Topic每条发布到MQ集群的消息都有一个类别,这个类别被称为topic,可以理解成一类消息的名字。所有的消息都以topic作为单位进行归类。

日常开发中需要关心哪些指标

1.生产消息数目

每分钟几百几千个都正常水平吧,业务繁忙的每分钟几万几十万也是有的

image-20200420193350371

2.消息延迟情况

延迟越低越好啦,几百毫秒正常水平。

image-20200420193540766

3.消息积压数

这个当然是要0了,如果遇到消费端服务器上线,可能会有段时间积压正常,这个指标,日常应该都是0才对。

image-20200420194052328

为什么使用消息队列

开头不是说了,排队能解决一个问题,就是削峰,意思就是流量洪峰来了,收银员结账速度依旧是一样的,不会被累死,还有两个重要的概念就是解耦异步

使用消息队列有什么缺点呢?

这个新手也一定要知道啦,因为面试官会问。

  1. 消息丢失问题: 任何系统不能保证万无一失,比如 Producer 发出了10000条消息,Consumer 只收到了 9999 个消息,有1个丢了,Consumer 能否接受丢一条?如果是订单成功短信可以接受丢一条,就是有一个顾客没有通知到已经发货,但货还是发出去了,如果是支付系统,用户已经付款却因为消息丢失没有通知到订单或物流系统,那恐怕顾客要找你麻烦了。

  2. 消息重复问题:如 Producer 发出了10000条消息,Consumer 只收到了 10001 条消息,有一条是重复的,业务能否接受一条重复的消息,这个是作为系统设计者要考虑的问题。

  3. 消息的顺序问题:如 Producer 发送顺序是123,Consumer 收到的消息是132,要考虑消费端是否对顺序敏感。

  4. 一致性问题: 如消息丢失问题真的发生且无法找回,会造成两个系统的数据最终不一致,如果消息延迟,会造成短暂不一致。

ActiveMQ vs Kafka vs RabbitMQ

RabbitMQ、Kafka和ActiveMQ都是用于提供异步通信和解耦进程(分离消息的发送方和接收方)的消息传递技术。

它们被称为消息队列、消息代理或消息传递工具。RabbitMQ、Kafka和ActiveMQ都有相同的基本用途,但它们的工作方式不同。Kafka是一个高吞吐量的分布式消息传递系统。

RabbitMQ是一个基于AMQP的可靠消息代理。ActiveMQ和Kafka都是Apache的产品,都是用Java编写的,RabbitMQ是用Erlang编写的。

进BAT你就研究这其中一个就可以了,数量不在多,重点是深度。

ActiveMQ,Kafka和RabbitMQ有哪些替代方案?

这些在国内都不是很常用,新手了解一下就可以了,反正,知识广度&眼界是有了。

  1. Apollo:在现有REST API的基础上构建一个通用的GraphQL API,可以快速发布新的应用程序特性,而无需等待后端更改。

  2. IBM MQ:它是一个消息传递中间件,可以简化和加速跨多个平台的不同应用程序和业务数据的集成。它提供了经过验证的企业级消息传递功能,能够熟练而安全地移动信息。

  3. ZeroMQ:扩展性好,开发比较灵活,采用C语言实现,实际上他只是一个socket库的重新封装,如果我们做为消息队列使用,需要开发大量的代码

  4. Amazon SQS

关于消息队列的常见面试题

  1. 为什么使用消息队列?

  2. 消息队列有什么优点和缺点?

  3. 那为什么Kafka的吞吐量远高于其他同类中间件?

  4. 比较重要的关键字吗?比如ProducerConsumer,Partition,Broker,你都是怎么理解的?

参考资料

  1. Thorough Introduction to Apache Kafka

  2. 推荐一本书《深入理解Kafka:核心设计与实践原理》,微信读书就可以免费阅读。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/310400.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构与索引-- B+树索引

B树索引 上一节中我们讨论的都是B树的数据结构的由来以及他的一些操作,B树索引在本质就是B树在数据库中的一个实现,但是B索引在数据库中有一个特点就是他的高扇出性,因此在数据库中,B树的高度一般是2~3层,也就是对于查…

7种方法帮助企业改进软件维护效率

前言为了更高效地维护软件,同时为新的软件开发创造尽可能多的时间,以下为你介绍一些企业采取的方法和步骤。2019年,Tiedlift,一个开源支持和维护的企业,对软件开发人员进行了一项调查,结果显示,…

数据结构与索引-- mySql索引诡异事件

什么时候使用B树索引 并不是所有查询条件下出现的列都需要添加索引。对于什么时候添加索引,我们通过经验判断,访问表中很少一部分行时候,使用B树索引才有意义。对于性别字段,地区字段,类型字段,他们取值范…

[Java基础]抽象类和接口的区别

抽象类和接口的区别:

async,await执行流看不懂?看完这篇以后再也不会了

昨天有朋友在公众号发消息说看不懂await,async执行流,其实看不懂太正常了,因为你没经过社会的毒打,没吃过牢饭就不知道自由有多重要,没生过病就不知道健康有多重要,没用过ContinueWith就不知道await,async有…

如何分析EFCore引发的内存泄漏

调查实体框架核心中的内存泄漏不要让内存泄漏成为洪水术语“内存泄漏”和“ .NET应用程序”不是经常一起使用。但是,我们最近在一个.NET Core Web应用程序中出现了一系列内存不足异常。事实证明,此问题是由Entity Framework Core中的行为更改引起的&…

数据结构与算法-- 二叉树中和为某一值的路径

二叉树中和为某一值的路径 题目:输入一颗二叉树和一个整数,打印出二叉树中节点值的和为给定值的所有路径。从树的根节点开始往下一只到叶子节点所经过的节点形成一条路径。我们用二叉树节点的定义沿用之前文章中 二叉查找树实现原理定义。如下&#xff…

微服务统计,分析,图表,监控, 分布式追踪一体化的 HttpReports 在 .Net Core 的应用...

前言介绍HttpReports 是针对.Net Core 开发的轻量级APM系统,基于MIT开源协议, 使用HttpReports可以快速搭建.Net Core环境下统计,分析,图表,监控,分布式追踪一体化的站点, 适应.Net Core WebAPI,MVC,Web项目, 通过引用Nuget构建Da…

WPF 创建自定义面板

前面两个章节分别介绍了两个自定义控件:自定义的ColorPicker和FlipPanel控件。接下来介绍派生自定义面板以及构建自定义绘图控件。创建自定义面板是一种特殊但较常见的自定义控件开发子集。前面以及介绍过有关面板方面的知识,了解到面板驻留一个或多个子元素&#x…

vue.js中mock本地json数据

vue.js中mock本地json数据 新版本的vue项目中已经将dev-server.js,dev-client.js两个js文件合并到了webpack.dev.conf.js文件中,以下分别是新旧版本的build目录结构: 新版本: 旧版本: 本次验证mock:运…

互联网40岁失业是一个无法打破的魔咒吗?

最近刚刚过完生日,又大了一岁,距离40岁又进了一步。年纪大了,就要多复盘。最近几天思考的比较多,因为身边失业的朋友开始多了起来。我又有点陷入担忧、焦虑的心态了。好在我一直是个有阿Q精神的中年油腻男,很快安抚好自…

数据结构与算法--复杂链表的复制

复杂链表的复制 题目:实现一个函数complexListNode 复制一个复杂链表。在链表中,每个节点除了有一个next指针指向下一个节点,还有另外一个before节点,before节点指向链表中任意一个节点,或者null节点。链表节点定义使…

如何实时主动监控你的网站接口是否挂掉并及时报警

“ 阅读本文大概需要 10 分钟。 ”最近我在公司负责的业务已经正式投入上线了,既然是线上环境,那么就需要保证其可用性。我负责的业务其中就包括一个 Web Service,我需要保证 Service 的每个接口都是可用的,如果某个时间流量大了或…

数据结构与算法--二叉查找树转顺序排列双向链表

二叉查找树转顺序排列双向链表 题目:输入一颗二叉查找树,将二叉查找树转成一个排序的双向链表,要求不能创建任何新节点,只调整树节点中指针的指向。例如下图所示: 本次二叉查找树节点定义使用之前文章 数据结构与算法…