肯定是ActiveMQ有一些数据库没有的特性吧?
它被用于可靠地在两个分布式进程之间通信。
是的,你可以将消息存储在数据库中以在两个进程之间通信,但是,一旦消息被接收,您需要DELETE
该消息,这意味着对于每条消息都需要进行INSERT
和DELETE
操作。
当您尝试扩展以每秒传输数千条消息时,数据库往往会崩溃。
反之,像ActiveMQ
这样的消息中间件[MOM]则是为处理这些用例而构建的。
它们假设健康系统中的消息将会被非常快速地删除,并且可以进行优化来避免开销。
它还可以将消息推送给消费者,而不是消费者必须执行SQL查询来轮询新消息。
这进一步减少了处理新发送到系统中的消息所涉及的延迟。
ActiveMQ
,或者一般所有面向消息的中间件(MOM)的实现都被设计用于在两个应用程序或一个应用程序内的两个组件之间发送消息。
本质上,MOM和数据库共享一个共同基础,即它们提供事务性和持久性数据存储以供读写。
最大的区别在于使用模式-数据库非常通用且优化用于跨多个表进行复杂搜索,而MOM则针对读取消息进行了优化,以FIFO方式(队列)逐个读取。
JMS
是ActiveMQ实现的API,在Java企业应用程序中是一个重要的基石。这使得消息共享相当普遍的格式和语义,从而使不同应用程序之间的集成更加容易。
当然,还有许多仅在ActiveMQ中具有的更详细的功能,如OpenWire
、STOMP
和MQTT
的线路协议、JMS
、EIP
与Apache Camel、"请求/回复"和"发布/订阅"消息模式、JMS桥接、群集化("经纪人网络")等,这些功能实现了可扩展性和分布式处理,等等。
如果您有兴趣,可以稍微了解一下这些主题,因为它们非常庞大。
ActiveMQ
拥有出色的调度程序支持,这意味着您可以安排发送消息以在特定时间交付。
我们已经在医疗保健场景中使用此功能向上传药品详细信息的患者发送用药提醒。
使用关系型数据库管理系统(RDBMS),在处理一行数据时,您通常会更新一个标志以指示该行已被处理,以便不会重复进行处理。
但是,在消息队列中,您只需要确认一条消息,下一个消费者将处理下一条消息。
区别在于,与 RDBMS 中的 UPDATE
语句相比,activemq 中的 acknowledge
操作非常快速。
来自维基百科
Apache ActiveMQ是一个开源的消息代理,使用Java编写,拥有完整的Java消息服务(JMS)客户端。它提供了“企业级功能”,这意味着可以促进来自多个客户端或服务器的通信。
关于你的问题:
为什么不使用数据库?
应该将数据库用于持久数据而不是临时数据。假设你需要向接收方发送一条消息,当接收方接收到消息后,会执行一个操作(接收、处理和遗忘)。在处理完该消息后,你就不再需要那条消息了。在这种情况下,将消息存储在持久数据库中并不是一个正确的解决方案。
我完全同意@Hiram Chirino的回答,他对于如果使用数据库而不是消息系统进行插入和删除消息的回答也非常认同。
ActiveMQ 有哪些数据库没有的功能?
请查看此演示文稿,了解ActiveMQ的内部情况。
解耦:系统能够在无连接状态下通信。队列位于系统之间,一个系统的故障不会影响其他系统,因为通过队列进行通信。当系统处于开启状态时,它们将继续工作。
恢复支持:队列中的消息本身被保留。如果队列出现故障,可以稍后恢复消息。
可靠的通信:考虑一个处理客户请求的系统。在正常情况下,该系统每分钟接收100个请求。当请求数量超过平均值时,该系统是不可靠的。在这种情况下,队列可以管理请求,并根据系统吞吐量定期推送消息而不会破坏它。
异步:客户端服务器通信是非阻塞的。一旦客户端向服务器发送请求,它可以在等待响应的同时执行其他操作。当收到响应后,客户端可以随时处理。
假设您有一个应用程序,同时在多个位置使用。 此外,假设您的应用程序每分钟必须处理数千个请求或类似操作,因此普通的数据库操作无法处理这样的操作,ActiveMQ作为消息处理,将所有消息进入队列,因此即使其中一个应用程序在某个位置崩溃,其他位置也不会受到影响。
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';