我查了一下,它曾经在两个系统之间发送消息。
但为什么?你为什么不直接使用 a Database
?
一定有一些ActiveMQ
没有的功能Databases
?
8 回答
它用于在两个分布式进程之间进行可靠的通信。
是的,您可以将消息存储在数据库中以在两个进程之间进行通信,但是,一旦收到消息,您就必须接收DELETE
消息,这意味着一行INSERT
和DELETE
每条消息。
当您尝试扩大每秒传达数千条消息的规模时,数据库往往会崩溃。
ActiveMQ
另一方面,面向消息的中间件 [MOM] 就是为处理这些用例而构建的。
他们假设健康系统中的消息将很快被删除,并且可以进行优化以避免开销。
它还可以将消息推送给消费者,而不是消费者必须通过执行 SQL 查询来轮询新消息。
这进一步减少了处理发送到系统的新消息所涉及的延迟。
ActiveMQ
,或者一般来说,所有面向消息的中间件 (MOM) 实现都是为了在两个应用程序之间或一个应用程序内的两个组件之间发送消息而设计的。
从本质上讲,MOM 和数据库共享一个共同的基础,因为它们提供可以读取和写入的事务性和持久性数据存储。
最大的区别在于使用模式 - 数据库非常通用并且针对多个表的复杂搜索进行了优化,MOM 针对读取消息进行了优化,一次一个,以类似 FIFO 的方式 [Queue]。
JMS
是 ActiveMQ 实现的 API,是 Java 企业应用程序的重要基石。这使得消息共享一种相当通用的格式和语义,这使得不同应用程序之间的集成更容易。
当然,还有很多只有 ActiveMQ 才有的更详细的特性,像OpenWire
,STOMP
和MQTT
,这样的有线协议JMS
,以及EIP
Apache Camel,像“请求/回复”和“发布/订阅”这样的消息模式,JMS 桥接,集群(“经纪人网络”),它允许扩展和分发等。
如果您有兴趣,您应该阅读这些主题,因为它们相当大。
ActiveMQ
具有出色的调度程序支持,这意味着您可以安排在特定时间发送您的消息。
我们已使用此功能向在医疗保健场景中上传药物详细信息的患者发送药物提醒。
使用 RDBMS,当您处理一行数据时,您通常会更新一个指示该行已被处理的标志,以便不再重复处理。
但是,使用消息队列,您只需确认一条消息,下一个消费者将处理下一个消息。
不同之处在于,与 activmeqUPDATE
中的相比,RDBMS 中的语句是一个非常慢的操作acknowledge
。
来自维基百科
Apache ActiveMQ 是一个用 Java 编写的开源消息代理以及完整的 Java 消息服务 (JMS) 客户端。它提供“企业功能”,在这种情况下,这意味着促进来自多个客户端或服务器的通信
关于您的查询:
为什么不使用数据库?
您应该将数据库用于持久数据,而不是用于临时数据。假设您必须从 Sender 向 Receiver 发送消息。接收消息时,接收者执行一项操作(接收、处理和忘记)。处理完该消息后,您根本不需要该消息。在这种情况下,将消息存储在持久数据库中并不是一个正确的解决方案。
如果您使用数据库而不是消息传递系统,我完全同意@Hiram Chirino关于在数据库中插入和删除消息的回答。
- 企业集成:允许使用不同语言和不同操作系统构建的应用程序相互集成
- 位置透明性:客户端应用程序不需要知道服务应用程序的位置
- 可靠的通信——消息的生产者/消费者不必同时可用
- 扩展——可以通过添加更多服务来水平扩展
- 异步通信——客户端可以触发消息并继续其他处理,而不是阻塞,直到服务发送响应;
- 减少耦合——由于前面的 5 个好处,客户和服务所做的假设大大减少。服务可以更改有关其自身的详细信息,包括其位置、协议和可用性,而不会影响或中断客户端。
ActiveMQ 一定有数据库没有的功能吗?
查看此演示文稿以了解 ActiveMQ 的内部结构。
我想强调以下几点:
解耦:系统能够在不连接的情况下进行通信。队列位于系统之间,一个系统故障永远不会影响另一个系统,因为通信是通过队列完成的。系统在启动时继续工作。
恢复支持:队列本身中的消息保持不变。如果队列失败,消息可以稍后恢复。
可靠通信:考虑一个处理客户请求的系统。在正常情况下,系统每分钟接收 100 个请求。当请求数量超过平均水平时,该系统是不可靠的。在这种情况下,Queue 可以管理请求,并且可以根据系统吞吐量定期推送消息而不会破坏它。
异步:客户端服务器通信是非阻塞的。一旦客户端向服务器发送请求,它就可以在不等待响应的情况下执行其他操作。当收到响应时,客户端可以随时处理。
假设您有一个同时在多个位置使用的应用程序。还假设您的应用程序必须每分钟处理 1000 次请求或类似的操作,因此正常的数据库操作无法处理此类操作,Activemq 充当消息处理,它将所有消息放入队列中,因此即使您的应用程序之一在一个位置崩溃其他位置不会受到影响。
考虑以下通用用户场景
用户场景
- 客户上传文本文档
- 您的应用程序将文本文档转换为 PDF
- 您的应用程序通过电子邮件将 PDF 发送回客户
基于队列的系统的数据库 在这种情况下,您可能会考虑为您的 PDF 作业线使用数据库。通常,您会创建一个数据库表,其中包含一行与 PDF 需求相关的记录。那时你会在表中打个招呼,说明任务处于哪个状态以及任务是否完成。
INSERT INTO pdf_job_queue (name, status, email) VALUES ("White paper", "NEW", "myemail@example.com");
SELECT * FROM pdf_job_queue WHERE queue = 'resize_queue' AND handled = false ORDER BY date_recived limit 1;
您需要编写代码将新请求插入数据库。从数据库获取输入的代码,可能会更改状态列,例如“ NEW
”和“ PROCESSING
”值,处理请求的代码,再次将数据库状态字段更新为“ FINISHED
”的代码,以及删除来自队列的请求。
update pdf_job_queue set Status="FINISHED" where Id = 'SomeId';
为了有效地操作,您可能需要快速且频繁地轮询数据库。当然,这会给数据库和您的应用程序增加很大的负载。
消息队列 当您尝试通过使用消息队列来实现相同目的时。
实时 推送来自消息行的消息是实时推送的,而不是偶尔从数据库中调查。可以熟练地使用消息行来支持更大数量的并发消息。消息行中的消息在被获取后自然会被清理。
ACKNOWLEDGMENT 一个确认从worker发回,告诉消息队列一个特定的消息已经被接收和处理并且消息队列可以自由地删除它。如果工作人员在没有发送确认的情况下死亡,消息队列将了解消息未完全处理并将其重新传递到队列和另一个工作人员。这样您就可以确保不会丢失任何消息。
对于消息队列系统,我总是推荐ActiveMQ,因为它易于安装、配置并且非常易于扩展。