用于客户端通知的AMQP或XMPP - java

我正在设计一个自定义消息传递系统的替代品,该系统目前用于从服务器端(Java)通知JavaScript Web应用程序有关更改的内容。该旧版消息传递系统通过使用基于自定义文本的协议和纯Java套接字,通过Flash XMLSocket进行工作。

替换将不仅由Web应用程序(通过Web套接字而不是Flash)使用,而且还将由用C#编写的其他桌面客户端应用程序使用。

我的要求是:

用户认证
传输加密(SSL / TLS)
双向消息交换
某种(自动)发布/订阅,以便用户仅获得他们被允许接收的消息
基于已建立协议的消息交换(以便我们尽可能使用现有的库)
可集群服务器组件

此时,消息传递系统将仅用于将更新发布到客户端。客户端将对这些消息做出反应,并直接从服务器(而不是通过消息传递系统)获取更多信息。如果成功建立了新的消息传递系统,则将来可以将其用于更高级的用例。一些可能性可能包括用户聊天,文件交换和服务器组件的远程控制。

我对实现这些要求的可行技术进行了一些研究,我认为我的选择归结为使用ejabberd(XMPP)或RabbitMQ(AMQP)。就我的要求而言,这两个系统的主要优缺点是什么?我们已经在系统基础架构的其他部分使用RabbitMQ,所以这是我的自然选择。我只是不确定将客户端应用程序直接连接到如此重要的主要组件是否是一个好主意。尽管可以通过仅将不同的RabbitMQ安装用于客户端通知来缓解这种情况。

参考方案

好吧,您可以使用这两种协议来满足您的需求,xmpp是可扩展的协议,因此毫无疑问,您正在寻找的东西是否已经以plugin的形式存在,或者该协议的正确术语是什么。但是,包括我在内的一些人可能实际上将其视为不利因素,并且给协议增加了额外的复杂性。要记住的另一件事是,xmpp最初被设计为即时消息传递协议。例如,发布/订阅是xmpp的extension,而不是协议本身的一部分。

话虽这么说,xmpp得到了Google等组织的支持,这意味着有一些主要参与者正在使用此协议,所以毫无疑问,某些扩展确实非常好,并且编写/思想都很好。

另一方面,您拥有AMQP,这是一种几乎专门针对您所追求的协议。它得到了JP Morgan,思科,瑞士信贷等组织的支持,因此毫无疑问,AMQP是值得信赖的协议,即使它的早期版本已经critized

在使用RabbitMQ时,memory似乎存在一些问题,但是由于我只收到有关此问题的通知,而从未真正地去解决它,甚至从不了解它,所以我不能多说。但是,似乎有相当多的人在不同版本的RMQ上体验到这一点。

但是对我而言,RabbitMQ从未崩溃过(嘿,如果以一件事而闻名的erlang就是它的稳定性),这是一种设置的乐趣,并且在集群中的设置非常容易,并且您可以在多个实例上轻松地镜像队列RMQ,您可以通过使一个或多个实例将消息写入磁盘来获得额外的安全性。

因此,我想和RabbitMQ和AMQP一起使用,我相信这是一个非常适合您需要的协议,但是说了xmpp也可以很好地完成工作。

我读过this book,这是对AMQP和RabbitMQ的很好的介绍,但是我发现它在技术方面缺乏,基本上是一个很好的教程。

PS:我觉得我应该老实说,我不太确定bidirectional message exchange的含义,但是如果这意味着发送和接收消息,那么AMQP也很明确。 🙂

我希望这有助于阐明选择哪种协议。

编辑

RabbitMQ有一个称为virtual hosts的东西,其行为类似于RabbitMQ的自己的实例,因此您不必从设置集群开始就可以处理单独的职责。根据您如何设置队列和交换方式,我看不到客户端连接到RabbitMQ服务器的问题,但是群集无疑是一个好主意。用HAProxy设置RabbitMQ似乎也很容易,但这又是我所没有的经验。

JAVA:字节码和二进制有什么区别? - java

java字节代码(已编译的语言,也称为目标代码)与机器代码(当前计算机的本机代码)之间有什么区别?我读过一些书,他们将字节码称为二进制指令,但我不知道为什么。 参考方案 字节码是独立于平台的,在Windows中运行的编译器编译的字节码仍将在linux / unix / mac中运行。机器代码是特定于平台的,如果在Windows x86中编译,则它将仅在Win…

java:继承 - java

有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…

Java:BigInteger,如何通过OutputStream编写它 - java

我想将BigInteger写入文件。做这个的最好方式是什么。当然,我想从输入流中读取(使用程序,而不是人工)。我必须使用ObjectOutputStream还是有更好的方法?目的是使用尽可能少的字节。谢谢马丁 参考方案 Java序列化(ObjectOutputStream / ObjectInputStream)是将对象序列化为八位字节序列的一种通用方法。但…

Java-如何将此字符串转换为日期? - java

我从服务器收到此消息,我不明白T和Z的含义,2012-08-24T09:59:59Z将此字符串转换为Date对象的正确SimpleDateFormat模式是什么? java大神给出的解决方案 这是ISO 8601标准。您可以使用SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy-MM…

Java:从类中查找项目名称 - java

仅通过类的实例,如何使用Java反射或类似方法查找项目名称?如果不是,项目名称(我真正想要的是)可以找到程序包名称吗? 参考方案 项目只是IDE使用的简单组织工具,因此项目名称不是类或JVM中包含的信息。要获取软件包,请使用Class#getPackage()。然后,可以调用Package#getName()将包作为您在代码的包声明中看到的String来获取…