>>与软件开发有关的知识:操作系统,数据库,网络通信等 书籍支持  卫琴直播  品书摘要  在线测试  资源下载  联系我们
发表一个新主题 开启一个新投票 回复文章 您是本文章第 23268 个阅读者 刷新本主题
 * 贴子主题:  消息队列、消息代理和消息中间件的区别和联系 回复文章 点赞(0)  收藏  
作者:fangwei    发表时间:2024-04-21 02:11:11     消息  查看  搜索  好友  邮件  QQ  复制  引用

中间件(Middleware)
首先就要说什么是中间件?我的理解是:
中间件是帮助应用程序与其他应用程序、网络、硬件、操作系统交互或通信的软件。

换句更简洁的话:「将具体业务和底层逻辑解耦的软件」。其实符合中间件的软件范畴非常宽,日常用的

Redis、Nginx、Zookeeper、Memcached等等都是「中间件」。所谓的「中间」是相对于架构体系内的,它不涉

及具体的业务逻辑也不涉及底层的硬件逻辑,用于用户数据交换和管理,能够起到「中介」的作用,这就是中间件。
那么问题来了:为什么需要中间件的帮助(代理),直接去和对应的应用程序、硬件、操作系统等交互/通信不好嘛?
回答问题前,我们要明确一点:

任何中间件必然是为了解决特定领域的某个(些)问题而出现的。

我举2个例子来帮助大家理解。

数据库中间件
当项目很小的时候,直接使用编程语言下的数据库驱动操作数据库就可以了,有些开发会用ORM的方式操作数据库:这是够用的。
但随着业务发展,数据量和读写QPS越来越高,主从模式的MySQL实例压力越来越大,单纯的对服务器硬件升级已经无法满足生产环境的需要。在我司不成文的习惯是单表不要超过5千万条记录,数据库量大的时候就设计分库分表,也就是「分而治之」,把QPS和数据量分片限定在一个范围内。
当然还有很多其他相关的功能,如读写分离、路由策略、统计、管理、鉴权等等。这些是在业务逻辑之上的,不应该在业务代码中把这部分堆进去,应该抽象它们出来作为一个独立的组件,这就是数据库中间件。

现在主流的开源数据库中间件有Mycat、MySQL-proxy、Atlas等等,不过现在都不怎么维护了,另外还有Cetus ,作者是tcpcopy的作者,这个项目还在不断维护,有同学有兴趣的可以试试。当然其实各大公司内部都有自己的数据库中间件产品,更多的贴近公司的业务产品和基础设施。
Web框架中间件
一般Web框架都支持中间件,Web框架中间件的本质是插件系统,是一系列的框架钩子,在收到请求和返回响应这个过程里面去做一些额外的事情。中间件种类很多,举例一些:
1. 响应压缩
2. 记录日志
3. 支持会话Session
4. CSRF保护
5. 验证/身份鉴别
6. 访问控制
7. 资源使用检查(如内存占用)
8. 请求指标
9. 健康检查
10. 静态资源管理 …
这些中间件将业务和非业务代码功能进行解耦:
1. 框架里面可能内置了一些常用的中间件,也可能只是内置中间件支持。你可以配置使用某个(些),也能方便的自定义中间件
2. Web视图中不需要手写中间件逻辑,按约定好的用法框架会在对应的生命周期中按照约定的顺序去执行这些中间件逻辑
PS: Golang语言中最知名的Web框架Gin支持中间件,而且还官网搞了个叫gin-gonic/contrib的项目搜集社区里面的中间件。

消息队列(Message Queue)
消息队列就是Message+Queue。其实消息可以说是一个数据传输单位,它包含了创建时间、通道/主题信息、输入参数等全部数据;队列(Queue)是一种FIFO(先进先出)的数据结构,编程语言一般都内置(内存中的)队列实现,可以作为进程间通讯(IPC)的方法。使用队列最常见的场景就是生产者/消费者模式:生产者生产消息放到队列中,消费者从队列里面获取消息消费。
准确的说,消息队列(以下简称MQ**是一种能实现生产者到消费者单向通信的通信模型,而一般大家说MQ是指实现了这个模型的中间件,比如RabbitMQ、RocketMQ、Kafka等。
设想一个订单场景,当你付款成功之后要做什么:
1. 通知/提醒系统。通知商家有人买了Ta的商品,通知买家你购买成功(相当于确认订单)。通知/提醒的方式很多,如邮件、短信、App内消息等等
2. 会员系统。更新用户的积分、等级等
3. 日志系统。订单这么重要的服务需要有日志可以用于未来回溯问题
4. 推荐系统。更新用户画像,重新给用户推荐他可能感兴趣的商品 ..
这就出现了一些问题:
1. 响应耗时。事实上做的比这要多得多,每一项都需要有开销,增加响应时间。如果这些逻辑是同步执行的,用户要等多久?这种体验是完全不可以接受的!所以呢,需要一种异步消费的机制
2. 过度耦合。本来仅仅是一个订单系统,结果上述的那些东西都要堆进来,这就成了一个巨无霸应用,未来开发、维护都是问题
3. 错误丢失。假如这些后续的行为中某个(些)服务正好出现了故障执行失败或者验证超时,但是付款成功的确认是必须完成的,那么需要有个地方存这些还没有被正确消费的部分
4. 需要组(广)播。就像上面的订单场景,付款成功这个消息被发送给多个子系统,相当于组播。未来如果要新增删减订阅源,怎么便捷的实现呢?
当然还有其他的问题:
1. 秒杀场景下并发可能会很高的,非常有可能出现出现远超现有服务器处理能力的情况,这就容易把系统搞崩了,如果出现这种问题时把未处理的放进消息队列,这就达到了「削峰」和「限流」的作用。
2. 某些场景下需要有消息的优先级 …
而消息中间件就是解决上述问题的,虽然不同的中间件的实现方案不同,但都具备以下特点:
1. 分布式。其实消息中间件解决的就是分布式系统之间消息传递的问题,消费者可以分布在多台服务器上,一方面降低了由于单点故障引起的消息队列阻塞的风险,另外一方面也非常容易横向扩展。
2. 持久可靠。消息队列一般会把接收到的消息存储到本地硬盘上,保证消息不会在未消息前莫名丢失。
3. 高性能和高吞吐量。例如RocketMQ有亿级消息堆积能力,广泛应用在阿里系的各种高并发场景下;而Kafka在实时计算、日志采集等场景下算是业界的标准。
可以说,消息中间件是现在企业架构中不可或缺的组合部分,用了都说好。

消息代理(Message Broker)
消息代理是一种架构模式,用于消息验证、变换、路由。虽然不同的消息中间件架构和实现各不相同,但是大部分都实现了Broker:其实就是消息中间件服务器,它是中间件的核心。
注意:RabbitMQ、Kafka、RocketMQ等都有消息代理,但是注意,不是所有中间件都这么选,例如ZeroMQ,它用了套接字风格的API。




程序猿的技术大观园:www.javathinker.net
  Java面向对象编程-->操作符
  JavaWeb开发-->访问数据库(Ⅱ)
  JSP与Hibernate开发-->数据库事务的概念和声明
  Java网络编程-->创建非阻塞的HTTP服务器
  精通Spring-->Vue组件开发高级技术
  Vue3开发-->CSS过渡和动画
  关于Mongodb的全面总结
  MySQL不推荐使用uuid或者雪花id作为主键
  SQL查询语句练习题
  神奇的 SQL 之 WHERE 条件的提取与应用
  Linux下网络流量实时监控工具大全
  Ubuntu环境下挂载新硬盘
  MySQL的数据类型
  SQL MS Access、MySQL 和 SQL Server 数据类型
  SQL INSERT INTO SELECT 语句
  SQL 通配符
  DTD 验证
  XML的DTD定义
  存储与虚拟主机管理
  连接数据库发现大量的TIME_WAIT解决办法
  一次给朋友转账引发我对分布式事务的思考
  更多...

-----------------------------------------------------------------
踏踏实实做人,勤勤恳恳做技术
 IPIP: 已设置保密
楼主      
1页 0条记录 当前第1
发表一个新主题 开启一个新投票 回复文章


中文版权所有: JavaThinker技术网站 Copyright 2016-2026 沪ICP备16029593号-2
荟萃Java程序员智慧的结晶,分享交流Java前沿技术。  联系我们
如有技术文章涉及侵权,请与本站管理员联系。